using MinicsConsole.Helper.RawDataFilter;

namespace MinicsConsole.Business;

public class HardwareOperator(
    Hardwares hardwares,
    HardWareMonitor hardWareMonitor,
    //HardwareFileLoader hardwareFileLoader, 
    HardwareDBLoader hardwareDBLoader,
    UISender uIConnector,ILog log)
{
    public Task QueryHardwares()
    {
        uIConnector.UpdateMini8All();
        uIConnector.UpdateChannelAll();
        uIConnector.UpdateAddressAll();

        foreach (KeyValuePair<byte, Mini8Provider> providers in hardWareMonitor.Mini8Providers)
            uIConnector.Mini8ConnectNotify(providers.Key, providers.Value.IsConnect);

        return Task.CompletedTask;
    }

    public void FullyReset()
    {
        hardWareMonitor.FullyReset();
    }

    public bool SendSetValue(ChannelData channelData)
    {
        if (!hardWareMonitor.Mini8Communicators.TryGetValue(channelData.Mini8Index, out IMini8Communicator? mini8Sender) || mini8Sender is null)
        {
            log.Error($"Hardware - SendSetValue Failed {channelData.Mini8Index} Not Exist in Mini8 Communicator");
            return false;
        }

        if (!hardwares.Mini8Channels.TryGetValue(channelData.Mini8Index, out ConcurrentDictionary<byte, ChannelData>? channleDataValues) || channelData is null)
        {
            log.Error($"Hardware - SendSetValue Failed {channelData!.Mini8Index} Not Exist in Mini8 Channels");
            return false;
        }

        if (!channleDataValues.TryGetValue(channelData.ChannelIndex, out ChannelData? channel) || channel is null)
        {
            log.Error($"Hardware - SendSetValue Failed {channelData!.Mini8Index} Not Exist in Mini8 Channel Data SetValues");
            return false;
        }



        Mini8Input input = new();
        channelData.Adapt(input);
        bool success = true;
        if (!mini8Sender.SendMini8Data(channelData.ChannelIndex, input))
        {
            log.Error($"Hardware - SendSetValue Failed {channelData!.Mini8Index} Send to Mini8 Failed ");
            success = false;
        }



        channelData.Adapt(channel);
        uIConnector.UpdateSingleChannel(channelData.Mini8Index, channelData.ChannelIndex, channel);

        log.Info($"HardwareHub - SendSetValue {channelData.Mini8Index} {channelData.Name}");
        log.Info($"{JsonSerializer.Serialize(channelData).Trim('{').Trim('}').Replace("\"", string.Empty).Replace(",", Environment.NewLine)}");

        return success;
    }

    public bool ReconnectMini8(byte mini8Index)
    {
        return hardWareMonitor.CreateConnection(mini8Index, true);
    }

    public bool EnableChannel(byte mini8Index, byte channelIndex, Inhibit inhibit)
    {
        if (!hardWareMonitor.Mini8Communicators.TryGetValue(mini8Index, out IMini8Communicator? mini8Sender) || mini8Sender is null)
        {
            log.Error($"Hardware - EnableChannel Failed {mini8Index} Not Exist in Mini8 Communicator");
            return false;
        }

        if (!hardwares.Mini8Channels.TryGetValue(mini8Index, out var channels) || channels is null)
            return false;

        if (!channels.TryGetValue(channelIndex, out ChannelData? channel) || channel is null)
            return false;

        if (!mini8Sender.EnableChannel(channelIndex, inhibit))
            return false;
        log.Info($"HardwareHub - EnableChannel  Mini8-{mini8Index} Channel-{channelIndex} Inhibit-{inhibit}");

        return true;
    }

    public bool SwitchChannelMode(byte mini8Index, byte channelIndex, ChannelMode channelMode)
    {
        if (!hardWareMonitor.Mini8Communicators.TryGetValue(mini8Index, out IMini8Communicator? mini8Sender) || mini8Sender is null)
        {
            log.Error($"Hardware - SwitchChannelMode Failed {mini8Index} Not Exist in Mini8 Communicator");
            return false;
        }

        if (!hardwares.Mini8Channels.TryGetValue(mini8Index, out var channels) || channels is null)
            return false;

        if (!channels.TryGetValue(channelIndex, out ChannelData? channel) || channel is null)
            return false;

        channel.ChannelMode = channelMode;

        if (channelMode == ChannelMode.UnUsed)
            EnableChannel(mini8Index, channelIndex, Inhibit.Disable);

        uIConnector.UpdateSingleChannel(mini8Index, channelIndex, channel);
        hardwareDBLoader.SaveSingleMini8(mini8Index);

        log.Info($"HardwareHub - SwitchChannelMode  Mini8-{mini8Index} Channel-{channelIndex} ChannelMode-{channelMode}");

        return true;
    }


    public bool SelectPID(byte mini8Index, byte channelIndex, ActiveTuneSet activeTuneSet)
    {
        if (!hardWareMonitor.Mini8Communicators.TryGetValue(mini8Index, out IMini8Communicator? mini8Sender) || mini8Sender is null)
        {
            log.Error($"Hardware - SelectPID Failed {mini8Index} Not Exist in Mini8 Communicator");
            return false;
        }

        log.Info($"HardwareHub - SelectPID  Mini8-{mini8Index} Channel-{channelIndex} ActiveTuneSet-{activeTuneSet}");

        return mini8Sender.SelectPID(channelIndex, activeTuneSet);
    }

    public bool EnableAT(byte mini8Index, byte channelIndex, bool isEnable)
    {
        if (!hardWareMonitor.Mini8Communicators.TryGetValue(mini8Index, out IMini8Communicator? mini8Sender) || mini8Sender is null)
        {
            log.Error($"Hardware - EnableAT Failed {mini8Index} Not Exist in Mini8 Communicator");
            return false;
        }

        log.Info($"HardwareHub - EnableAT  Mini8-{mini8Index} Channel-{channelIndex} Enable-{isEnable}");
        return mini8Sender.EnableChannelAutoTune(channelIndex, isEnable);
    }


    public Task EnableDisableDevice(byte mini8Index, bool isEnable)
    {
        if (hardWareMonitor.Mini8Communicators.TryGetValue(mini8Index, out IMini8Communicator? communicator) && communicator is not null)
        {
            _ = isEnable switch
            {
                true => ReconnectMini8(mini8Index),
                false => communicator.Close(),
            };
        }

        if (hardwares.Mini8s.TryGetValue(mini8Index, out Mini8Data? mini8) && mini8 is not null)
        {
            mini8.Enable = isEnable;
            uIConnector.UpdateMini8(mini8Index, mini8);
        }

        hardwareDBLoader.SaveSingleMini8(mini8Index);
        log.Info($"HardwareHub - EnableDisableDevice  Mini8-{mini8Index}  isEnable-{isEnable}");

        return Task.CompletedTask;
    }
}
