using Universal;

namespace ProximaAnalizer.Helpers;

public class DBProcessData<T_Hierarchy>(char spilter, int skip)
    where T_Hierarchy : IDictionary<string, object>, new()
{
    public bool ToDictionary(IDictionary<string, object> input, out T_Hierarchy? output)
    {
        output = default;

        if (input is null)
            return false;

        T_Hierarchy cache = [];
        foreach (KeyValuePair<string, object> rawData in input)
        {
            Span<string> source = rawData.Key.Split(spilter).AsSpan()[skip..];
            ColumAnalizer(cache, source, rawData.Key);
        }

        output = cache;
        return true;
    }

    private static void ColumAnalizer(/*ref*/ T_Hierarchy cache, Span<string> seprated, object value)
    {
        if (seprated.Length <= 1)
        {
            cache[seprated[0]] = value;
            return;
        }

        if (!cache.TryGetValue(seprated[0], out object? output) || output is not T_Hierarchy hierarchy)
        {
            hierarchy = [];
            cache[seprated[0]] = hierarchy;
        }

        cache = hierarchy;
        ColumAnalizer(cache, seprated[1..], value);
    }
}

public class GeneralProcessData(int skip = 0) : DBProcessData<Dictionary<string, object>>('.', skip)
{
    public static bool CreateTablePM(IDictionary<string, object> data, IDictionary<string, object> cache)
    {
        Dictionary<string, object> ValueSensor = [];
        Dictionary<string, object> StatusSensor = [];
        Dictionary<string, object> leakCheck = [];
        Dictionary<string, object> recipe = [];
        Dictionary<string, object> aoValue = [];

        Dictionary<string, object> ffu = [];
        Dictionary<string, object> mfc = [];
        Dictionary<string, object> gaslineHeater = [];
        Dictionary<string, object> bufferFoup = [];
        Dictionary<string, object> avValue = [];

        foreach (var item in data)
        {
            if (item.Value is not IDictionary<string, object> values)
            {
                switch (item.Key)
                {
                    case string s when s.EndsWith("Enable"):
                        continue;
                    case string s when s.StartsWith("LeakCheck"):
                        leakCheck.Add(item.Key, item.Value);
                        continue;
                    default:
                        recipe.Add(item.Key, item.Value);
                        continue;
                }
            }

            switch (item.Key)
            {
                case "APC":
                case "APCVATGV":
                case "BoatElevatorServo":
                case "BoatRotationServo":
                case "BufferServo":
                case "Shutter":
                    CreateTable(cache, item.Key, values);
                    continue;

                case string s when s.StartsWith("Trig"):
                    if (item.Value is IDictionary<string, object> value)
                        aoValue.Add(item.Key, value["AOValue"]);
                    continue;

                case string s when s.StartsWith("FS"):
                case string s1 when s1.StartsWith("PG"):
                case string s2 when s2.StartsWith("PS"):
                case string s3 when s3.StartsWith("VG"):
                    if (item.Value is IDictionary<string, object> vss)
                        ValueSensor.Add(item.Key, vss["Value"]);
                    continue;

                case string s when s.StartsWith("Sensor"):
                    if (item.Value is IDictionary<string, object> status)
                        StatusSensor.Add(item.Key, status["Value"]);
                    continue;
                case string s when s.StartsWith("MFC"):
                    if (item.Value is IDictionary<string, object> mfcs)
                        mfcs.Foreach(t => mfc.Add($"{item.Key}_{t.Key}", t.Value));
                    continue;
                case string s when s.StartsWith("FFU"):
                    if (item.Value is IDictionary<string, object> ffus)
                        ffus.Foreach(t => ffu.Add($"{item.Key}_{t.Key}", t.Value));
                    continue;
                case string s when s.StartsWith("GaslineHeater"):
                    if (item.Value is IDictionary<string, object> gaslines)
                        gaslines.Foreach(t => gaslineHeater.Add($"{item.Key}_{t.Key}", t.Value));
                    continue;
                case string s when s.StartsWith("Valve"):
                    if (item.Value is IDictionary<string, object> valves)
                        valves.Foreach(t => avValue.Add($"{item.Key}_{t.Key}", t.Value));
                    continue;
                default:
                    continue;
            }
        }
        CreateTable(cache, "MFC", mfc);
        CreateTable(cache, "FFU", ffu);
        CreateTable(cache, "Valve", avValue);
        CreateTable(cache, "GaslineHeater", gaslineHeater);
        CreateTable(cache, "ValueSensor", ValueSensor);
        CreateTable(cache, "StatusSensor", StatusSensor);
        CreateTable(cache, "LeakCheck", leakCheck);
        CreateTable(cache, "AoValue", aoValue);
        CreateTable(cache, "Recipe", recipe);

        return true;
    }

    public static void CreateTableSystem(IDictionary<string, object> data, IDictionary<string, object> cache)
    {
        Dictionary<string, object> systemCollection = [];
        Dictionary<string, object> alarmCollection = [];

        Dictionary<string, object> Heater = [];
        Dictionary<string, object> Stocker = [];
        Dictionary<string, object> LoadPort = [];
        //Dictionary<string, object> FIMS = [];

        foreach (var item in data)
        {
            if (item.Value is not IDictionary<string, object> values)
                continue;

            switch (item.Key)
            {
                case "Boat":
                case "CarrierRobot":
                case "Scheduler":
                case "WaferRobot":
                    CreateTable(cache, item.Key, values);
                    continue;
                case string s when s.StartsWith("Stocker"):
                    Stocker.Add(item.Key, values);
                    continue;
                case string s when s.StartsWith("LP"):
                    LoadPort.Add(item.Key, values);
                    continue;
                //case string s when s.StartsWith("FIMS"):
                //    FIMS.Add(item.Key, values);
                //    continue;

                case "System":
                    if (values is not IDictionary<string, object> systems)
                        continue;
                    foreach (var system in systems)
                    {
                        switch (system.Key)
                        {
                            case string s when s.StartsWith("Heater"):
                                Heater.Add(system.Key, system.Value);
                                continue;
                            case string s when s.StartsWith("AlarmSignalHeater"):
                                alarmCollection.Add(system.Key, ((IDictionary<string, object>)system.Value)["Value"] ??= false);
                                continue;
                            default:
                                systemCollection.Add(system.Key, system.Value);
                                break;
                        }
                    }
                    continue;
                default:
                    break;
            }

            //CreateTable(cache, "FIMS", FIMS);
            CreateTable(cache, "Heater", Heater);
            CreateTable(cache, "LoadPort", LoadPort);
            CreateTable(cache, "Stocker", Stocker);
            CreateTable(cache, "System", systemCollection);
            CreateTable(cache, "AlarmSignalHeater", alarmCollection);
        }
    }

    private static bool CreateTable(IDictionary<string, object> cache, string key, object value)
    {
        return cache.TryAdd(key, value);
    }
}