using SqlSugar;

namespace ProximaAnalizer.Helpers;

internal class DBDataHelper(SqlSugarCustom sqlSugarCustom)
{
    public bool GetRecipeSteps(string? guid, out string reason, out List<RecipeStepData>? recipeSteps)
    {
        recipeSteps = default;
        reason = string.Empty;
        if (string.IsNullOrEmpty(guid))
            return false;

        if (sqlSugarCustom.Client is null)
            return false;

        try
        {
            recipeSteps = sqlSugarCustom.Client.Queryable<RecipeStepData>().AS("recipe_step_data")
                .Where(t => t.Process_Data_Guid == guid)
                .OrderBy(t => t.Step_Begin_Time).ToList();
        }
        catch
        {
            reason = "recipe_step_data 记录不存在";
            return false;
        }

        if (recipeSteps.Count == 0)
        {
            reason = "recipe_step 步骤数量为0";
            return false;
        }

        return true;
    }

    public bool GetFirstData(DateTime beginTime, out string reason, out Dictionary<string, object>? temp)
    {
        temp = default;
        reason = string.Empty;
        if (sqlSugarCustom.Client is null)
            return false;

        dynamic pm;
        dynamic system;
        try
        {
            pm = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.PM1\"").First();
            system = sqlSugarCustom.Client.Queryable<dynamic>().AS($"\"{beginTime:yyyyMMdd}.System\"").First();
        }
        catch
        {
            reason = $"{beginTime:yyyyMMdd} 记录不存在";
            return false;
        }

        if (pm is not IDictionary<string, object> input)
            return false;

        GeneralProcessData processData = new();

        if (!processData.ToDictionary(input, out Dictionary<string, object>? output) || output is null)
            return false;

        if (output["PM1"] is not IDictionary<string, object> pmData)
            return false;

        if (!processData.ToDictionary(system, out Dictionary<string, object>? systemDic) || systemDic is null)
            return false;

        temp = [];
        Dictionary<string, object> PM1 = [];
        Dictionary<string, object> System = [];
        temp.Add("PM1", PM1);
        temp.Add("System", System);

        GeneralProcessData.CreateTablePM(pmData, PM1);
        GeneralProcessData.CreateTableSystem(systemDic!, System);
        return true;
    }


    public DateTime? StartTime { get; internal set; }
    public DateTime? EndTime { get; internal set; }

    private ObjectFuncModel? _whereFunc;

    public void SetTimeRange(DateTime startTime, DateTime endTime)
    {
        this.StartTime = startTime;
        this.EndTime = endTime;
        _whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");
    }

    public bool GetPMData(DateTime startTime, DateTime endTime, out List<dynamic>? pm1)
    {
        pm1 = null;

        if (sqlSugarCustom.Client is null)
            return false;
        try
        {
            ObjectFuncModel whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");

            pm1 = sqlSugarCustom.Client
                .Queryable<dynamic>()
                .AS($"\"{startTime:yyyyMMdd}.PM1\"")
                .Where(whereFunc).ToList();
        }
        catch
        {
            return false;
        }

        return true;
    }
    public bool GetSystemData(DateTime startTime, DateTime endTime, out List<dynamic>? systemData)
    {
        systemData = default;

        if (sqlSugarCustom.Client is null)
            return false;
        try
        {
            ObjectFuncModel whereFunc = ObjectFuncModel.Create("Format", "time", ">", "{long}:" + $"{startTime.Ticks}", "&&", "time", "<", "{long}:" + $"{endTime.Ticks}");

            systemData = sqlSugarCustom.Client
                .Queryable<dynamic>()
                .AS($"\"{startTime:yyyyMMdd}.System\"")
                .Where(whereFunc).ToList();
        }
        catch
        {
            return false;
        }

        return true;
    }

    public bool GetPMData(IEnumerable<string> fields, out List<dynamic>? pm1)
    {
        pm1 = null;
        if (this._whereFunc is null)
            return false;
        if (sqlSugarCustom.Client is null)
            return false;

        List<SelectModel> selectModels = [];

        foreach (var field in fields)
            selectModels.Add(new() { FieldName = $"\"{field}\"" });

        try
        {
            pm1 = sqlSugarCustom.Client
                .Queryable<dynamic>()
                .AS($"\"{StartTime:yyyyMMdd}.PM1\"")
                .Select(selectModels)
                .Where(_whereFunc).ToList();
        }
        catch
        {
            return false;
        }

        return true;
    }


    public bool GetSystemData(IEnumerable<string> fields, out List<dynamic>? systemData)
    {
        systemData = default;
        if (this._whereFunc is null)
            return false;
        if (sqlSugarCustom.Client is null)
            return false;

        List<SelectModel> selectModels = [];

        foreach (var field in fields)
            selectModels.Add(new() { FieldName = $"\"{field}\"" });
        try
        {
            systemData = sqlSugarCustom.Client
                .Queryable<dynamic>()
                .AS($"\"{StartTime:yyyyMMdd}.System\"")
                .Select(selectModels)
                .Where(_whereFunc).ToList();
        }
        catch
        {
            return false;
        }

        return true;
    }

    public bool GetAlarmData(out List<EventData>? alarm)
    {
        alarm = default;
        if (this._whereFunc is null)
            return false;
        if (sqlSugarCustom.Client is null)
            return false;
        try
        {
            alarm = sqlSugarCustom.Client
                .Queryable<EventData>()
                .AS($"event_data")
                .Where(t => t.Occur_Time >= this.StartTime && t.Occur_Time <= this.EndTime && (t.Level == "Alarm" || t.Level == "Warning")).ToList();
        }
        catch
        {

        }

        return alarm is not null;
    }
}
