namespace MinicsConsole.Business;

public class ConfigFileOperator(
    BasicInfo basicInfo,
    ConfigFiles configFiles,
    ConfigUpdater configUpdater,
    ConfigFileLoader configFileLoader,
    UISender uIConnector, ILog log)
{
    public Task QueryConfigFiles()
    {
        uIConnector.UpdateAllFiles();
        uIConnector.UpdateCurrentFile();
        uIConnector.UpdateDataBaseInfo(basicInfo.DBKeepRange, basicInfo.DBClearTime);
        return Task.CompletedTask;
    }

    public bool SetConfigFile(string fileName)
    {
        if (!configFiles.Files.TryGetValue(fileName, out TemperatureConfig? file) || file is null || file.Mini8sConfig is null)
        {
            log.Error($"ConfigHub - SetConfigFile {fileName} Not Exist");
            return false;
        }

        if (!configUpdater.SetConfigFile(file, true, out Dictionary<byte, Dictionary<byte, bool>> sendResult))
        {
            log.Error($"ConfigHub - SetConfigFile {fileName} Send to Mini8 Failed");
            return false;
        }

        if (sendResult is null)
        {
            log.Error($"ConfigHub - SetConfigFile {fileName} Send to Mini8 Failed");
            return false;
        }

        foreach (var mini8Unit in sendResult)
        {
            foreach (var channelUnit in mini8Unit.Value)
            {
                _ = channelUnit.Value switch
                {
                    true => log.Info($"ConfigHub - SetConfigFile {fileName} Send to Mini8 {mini8Unit.Key} Channel {channelUnit.Key}"),
                    false => log.Error($"ConfigHub - SetConfigFile {fileName} Send to Mini8 {mini8Unit.Key} Channel {channelUnit.Key}"),
                };
            }
        }

        Task.Factory.StartNew(() =>
        {
            uIConnector.UpdateCurrentFile();
            uIConnector.UpdateChannelAll();
        });

        log.Info($"ConfigHub - SetConfigFile {fileName} Success");

        return true;
    }

    public bool RemoveFile(string fileName)
    {
        if (!fileName.EndsWith(".mc"))
            fileName += ".mc";
        string filePath = Path.Combine(Paths.ConfigFileFolder, fileName);

        if (!File.Exists(filePath))
            return false;

        try
        {
            FileInfo fileInfo = new(filePath);
            string bin = Path.Combine(Paths.ConfigFileFolder, "RecycleBin");
            if (!Directory.Exists(bin))
                Directory.CreateDirectory(bin);

            string destination = Path.Combine(bin, fileInfo.Name);


            int copy = 1;
            while (File.Exists(destination))
            {
                destination = Path.Combine(bin, $"({copy}){fileInfo.Name}");
                copy++;
            }

            File.Copy(filePath, destination);
            File.Delete(filePath);
        }
        catch
        {
            return false;
        }

        configFileLoader.Load();
        Task.Factory.StartNew(uIConnector.UpdateAllFiles);
        return true;
    }

    public bool LoadNewFile(string filePath)
    {
        if (!File.Exists(filePath))
            return false;

        FileInfo fileInfo = new(filePath);
        string destination = Path.Combine(Paths.ConfigFileFolder, fileInfo.Name);

        while (File.Exists(destination))
        {
            destination = Path.Combine(Paths.ConfigFileFolder, $"Copy of {fileInfo.Name}");
        }

        if (!string.Equals(fileInfo.Extension, ".mc"))
            return false;
        if (File.Exists(destination))
            return false;

        try
        {
            File.Copy(filePath, destination);
        }
        catch
        {
            return false;
        }

        configFileLoader.Load();
        Task.Factory.StartNew(uIConnector.UpdateAllFiles);

        return true;
    }

    public bool SaveConfig(string fileName, TemperatureConfig temperatureConfig, bool saveAsNew)
    {
        for (int i = 1; saveAsNew & configFiles.Files.ContainsKey(fileName); i++)
            fileName = fileName.Contains(')') switch
            {
                false => $"({i}){fileName}",
                _ => $"({i}){fileName[(fileName.IndexOf(')') + 1)..]}"
            };


        temperatureConfig.ConfigName = fileName;
        configFiles.Files[fileName] = temperatureConfig;

        configFileLoader.Save();
        configFileLoader.Load();
        Task.Factory.StartNew(uIConnector.UpdateAllFiles);

        return true;
    }

    public TemperatureConfig? QueryMini8Data()
    {
        if (!configUpdater.ReadConfigFromMini8(out TemperatureConfig? config))
            return null;

        if (config is not null && config.Mini8sConfig is not null)
            config.Mini8sConfig = config.Mini8sConfig.OrderBy(t => t.Key).ToDictionary();

        return config;
    }
}
