namespace MinicsConsole.Helper;

public class HardwareDBLoader(OrmCollections ormCollections, Hardwares hardwares)
{
    public bool Load()
    {
        if (ormCollections == null || ormCollections.MainORM is null)
            return false;

        IORM orm = ormCollections.MainORM;

        var result = orm.Query<Mini8Data>("Mini8Config", (mini8s) =>
        {
            foreach (Mini8Data mini8 in mini8s)
                hardwares.Mini8s[mini8.Index] = mini8;

        }).Result;

        result &= orm.Query<ChannelData>("ChannelConfigConfig", (channelDatas) =>
        {
            foreach (ChannelData channelData in channelDatas)
            {
                if (!hardwares.Mini8Channels.TryGetValue(channelData.Mini8Index, out ConcurrentDictionary<byte, ChannelData>? channels) || channels is null)
                {
                    channels = [];
                    hardwares.Mini8Channels[channelData.Mini8Index] = channels;
                }
                channels[channelData.ChannelIndex] = channelData;
            }
        }).Result;

        if (hardwares.Mini8s is null || hardwares.Mini8s.IsEmpty)
            return false;

        if (hardwares.Mini8Channels is null || hardwares.Mini8Channels.IsEmpty)
            return false;

        return result;
    }

    public bool Save()
    {
        if (ormCollections == null || ormCollections.MainORM is null)
            return false;

        IORM orm = ormCollections.MainORM;
        orm.CreateTable<Mini8Data>("Mini8Config");
        orm.CreateTable<ChannelData>("ChannelConfigConfig");

        foreach (var mini8 in hardwares.Mini8s.Values)
        {
            if (!orm.AddOrUpdate("Mini8Config", mini8, t => t.Index == mini8.Index))
                return false;
        }

        foreach (var channels in hardwares.Mini8Channels.Values)
        {
            foreach (var channel in channels)
            {
                ChannelData channelData = channel.Value;

                if (!orm.AddOrUpdate("ChannelConfigConfig", channelData, t => t.Mini8Index == channelData.Mini8Index && t.ChannelIndex == channelData.ChannelIndex))
                    return false;
            }
        }

        return true;
    }

    public bool SaveSingleMini8(byte mini8Index)
    {
        if (ormCollections == null || ormCollections.MainORM is null)
            return false;

        IORM orm = ormCollections.MainORM;
        orm.CreateTable<Mini8Data>("Mini8Config");
        orm.CreateTable<ChannelData>("ChannelConfigConfig");

        if (!hardwares.Mini8s.TryGetValue(mini8Index, out Mini8Data? mini8) || mini8 is null)
            return false;

        if (!hardwares.Mini8Channels.TryGetValue(mini8Index, out ConcurrentDictionary<byte, ChannelData>? channels) || channels is null)
            return false;

        if (!orm.AddOrUpdate("Mini8Config", mini8, t => t.Index == mini8.Index))
            return false;

        foreach (var channel in channels)
        {
            ChannelData channelData = channel.Value;

            if (!orm.AddOrUpdate("ChannelConfigConfig", channelData, t => t.Mini8Index == channelData.Mini8Index && t.ChannelIndex == channelData.ChannelIndex))
                return false;
        }

        return true;
    }

}
