#include <fancontroller.h>
#include <filesystem>
#include <qdebug.h>
#include <qglobal.h>
#include <string>
#include <fstream>
#include <QDebug>
#include <QTimer>
#include <QObject>


void FanController::setFanSpeed(PwmFan &fan, int speed)
{
    speed = std::clamp(speed, 0, 255);

    std::ofstream pwmFile(fan.pwmPath);
    if (pwmFile.is_open())
    {
        pwmFile << speed;
        pwmFile.close();
    }
    else
    {
        qDebug() << "Failed to open pwm file:" << fan.pwmPath.c_str();
    }
}

FanController::FanController()
{
    // 初始化温度控制器
    thermalController = new ThermalController();
    thermalController->findThermalPath();
    
    // 每一秒更新一次风扇转速
    QTimer *timer = new QTimer();
    connect(timer, &QTimer::timeout, [&]()
            {
                if (targetFanCurves.empty())
                {
                    return;
                }
                for (auto &target : targetFanCurves)
                {
                    const std::string &targetFanName = target.first;

                    for (auto &fan : fans)
                    {
                        if (fan.fanName == targetFanName)
                        {
                            PwmFan &targetFan = fan;
                            QVector<CurvePoint> &targetCurve = target.second;

                            for (auto &point : targetCurve)
                            {
                                
                                // TODO：添加温度判断
                                
                                float inputTemperature = thermalController->getCpuTemp();

                                // 错误温度值处理
                                if (inputTemperature < 0)
                                {
                                    continue;
                                }

                                // 判断是否在曲线范围内
                                if (inputTemperature >= point.x)
                                {
                                    int targetSpeed = static_cast<int>((point.y / 100) * 255);
                                    setFanSpeed(targetFan, targetSpeed);
                                }
                            }
                        }
                    }

                }
            });

    timer->start(1000);
}

void FanController::findFanPaths()
{
    const std::string hwmonPath = "/sys/class/hwmon/";

    for (const auto &entry : std::filesystem::directory_iterator(hwmonPath))
    {
        if (entry.is_directory())
        {
            for (const auto &subEntry : std::filesystem::directory_iterator(entry.path()))
            {
                const std::string curFileName = subEntry.path().filename().string();

                auto checkIsNum = [](std::string str)
                {
                    for (int i = 0; i < str.size(); i++)
                    {
                        int tmp = (int)str[i];
                        if (tmp >= 48 && tmp <= 57)
                        {
                            continue;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    return true;
                };


                if (curFileName.find("pwm") != std::string::npos &&
                        checkIsNum(curFileName.substr(3, curFileName.size() - 1)))
                {

                    // 目前来看，pwmX ， fanX_label， fanX_input 是成对出现的，先这样处理，卡Bug再处理
                    std::string fanName;
                    std::string pwmPath;
                    std::string fanSpeedPath;

                    // pwm
                    pwmPath = subEntry.path().string();

                    // 获取 pwm 后面的数字id
                    std::string pwmId = subEntry.path().filename().string().substr(3);

                    try
                    {
                        std::string fanLabelPath = entry.path().string() + "/fan" + pwmId + "_label";
                        std::ifstream fanLabelFile(fanLabelPath);
                        if (fanLabelFile.is_open())
                        {
                            std::string fanLabel;
                            fanLabelFile >> fanLabel;

                            qDebug() << fanLabel.c_str();
                            // fanX_label
                            fanName = fanLabel;
                        }
                    }
                    catch (const std::exception &e)
                    {
                        qDebug() << "Error reading fan label:" << e.what();
                    }

                    try
                    {
                        // 台式机主板pwm风扇启用定义
                        // 0：风扇关闭
                        // 1：手动
                        // 2：CPU温度
                        // 3：风扇调速器  ？？？
                        // 4：风扇调速器温度调节模式  ？？？
                        // 5：BIOS控制

                        std::string fanEnablePath = entry.path().string() + "/pwm" + pwmId + "_enable";
                        std::ofstream fanEnable(fanEnablePath);
                        if (fanEnable.is_open())
                        {
                            fanEnable << 1;
                        }
                        else
                        {
                            qDebug() << "无法修改为手动模式，请检查权限";
                        }

                    }
                    catch (const std::exception &e)
                    {

                    }

                    try
                    {
                        std::string fanInputPath = entry.path().string() + "/fan" + pwmId + "_input";
                        if (std::filesystem::exists(fanInputPath))
                        {
                            // fanX_input
                            fanSpeedPath = fanInputPath;
                        }
                    }
                    catch (const std::exception &e)
                    {
                        qDebug() << "Error reading fan speed:" << e.what();
                    }

                    PwmFan fan(fanName, pwmPath, fanSpeedPath);
                    fans.push_back(fan);
                }
            }
        }
    }
}

std::vector<PwmFan> FanController::getFans()
{
    return fans;
}

void FanController::setFanCurve(PwmFan &fan, QVector<CurvePoint> curvePoints)
{
    targetFanCurves[fan.fanName] = curvePoints;
}
