//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://thingsgateway.cn/
//  QQ群：605534569
//------------------------------------------------------------------------------

using System.Text;
using System.Text.RegularExpressions;

using ThingsGateway.NewLife.Json.Extension;

using TouchSocket.Core;

namespace ThingsGateway.Gateway.Application;

/// <summary>
/// 业务插件，额外实现脚本切换实体
/// </summary>
public abstract partial class BusinessBaseWithCacheIntervalScript : BusinessBaseWithCacheInterval
{
    protected sealed override BusinessPropertyWithCacheInterval _businessPropertyWithCacheInterval => _businessPropertyWithCacheIntervalScript;

    protected abstract BusinessPropertyWithCacheIntervalScript _businessPropertyWithCacheIntervalScript { get; }

    public virtual List<string> Match(string input)
    {
        // 生成缓存键，以确保缓存的唯一性
        var cacheKey = $"{nameof(BusinessBaseWithCacheIntervalScript)}-{CultureInfo.CurrentUICulture.Name}-Match-{input}";

        // 尝试从缓存中获取匹配结果，如果缓存中不存在则创建新的匹配结果
        var strings = App.CacheService.GetOrAdd(cacheKey, entry =>
        {
            List<string> strings = new List<string>();

            // 使用正则表达式查找输入字符串中的所有匹配项
            Regex regex = TopicRegex();
            MatchCollection matches = regex.Matches(input);

            // 遍历匹配结果，将匹配到的字符串添加到列表中
            foreach (Match match in matches)
            {
                if (match.Success)
                {
                    string productKey = match.Groups[1].Value;
                    strings.Add(productKey);
                }
            }

            // 返回匹配结果列表
            return strings;
        });

        // 返回匹配结果列表
        return strings;
    }

    #region 封装方法

    protected IEnumerable<TopicJson> GetAlarms(IEnumerable<AlarmVariable> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<AlarmVariable>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptAlarmModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.AlarmTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics);

                foreach (var group in groups)
                {
                    // 上传主题
                    // 获取预定义的报警主题
                    string topic = _businessPropertyWithCacheIntervalScript.AlarmTopic;

                    // 将主题中的占位符替换为分组键对应的值
                    for (int i = 0; i < topics.Count; i++)
                    {
                        topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                    }

                    // 上传内容
                    if (_businessPropertyWithCacheIntervalScript.IsAlarmList)
                    {

                        // 如果是报警列表，则将整个分组转换为 JSON 字符串
                        var gList = group.Select(a => a).ToList();
                        string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                        // 将主题和 JSON 内容添加到列表中
                        yield return new(topic, json, gList.Count);
                    }
                    else
                    {
                        // 如果不是报警列表，则将每个分组元素分别转换为 JSON 字符串
                        foreach (var gro in group)
                        {
                            string json = SystemTextJsonExtension.ToSystemTextJsonString(gro, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, 1);
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsAlarmList)
            {
                var gList = data.Select(a => a).ToList();
                string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.AlarmTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    string json = SystemTextJsonExtension.ToSystemTextJsonString(group, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.AlarmTopic, json, 1);
                }
            }
        }

    }


    protected IEnumerable<TopicJson> GetDeviceData(IEnumerable<DeviceBasicData> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<DeviceBasicData>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptDeviceModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.DeviceTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的设备主题
                        string topic = _businessPropertyWithCacheIntervalScript.DeviceTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsDeviceList)
                        {
                            // 如果是设备列表，则将整个分组转换为 JSON 字符串
                            var gList = group.Select(a => a).ToList();
                            string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, gList.Count);
                        }
                        else
                        {
                            // 如果不是设备列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                string json = SystemTextJsonExtension.ToSystemTextJsonString(gro, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsDeviceList)
            {
                var gList = data.Select(a => a).ToList();
                string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.DeviceTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    string json = SystemTextJsonExtension.ToSystemTextJsonString(group, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.DeviceTopic, json, 1);
                }
            }
        }
    }

    protected IEnumerable<TopicJson> GetVariableScript(IEnumerable<VariableBasicData> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<VariableBasicData>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptVariableModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.VariableTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的变量主题
                        string topic = _businessPropertyWithCacheIntervalScript.VariableTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsVariableList)
                        {
                            // 如果是变量列表，则将整个分组转换为 JSON 字符串
                            var gList = group.Select(a => a).ToList();
                            string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, gList.Count);
                        }
                        else
                        {
                            // 如果不是变量列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                string json = SystemTextJsonExtension.ToSystemTextJsonString(gro, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsVariableList)
            {
                var gList = data.Select(a => a).ToList();
                string json = gList.ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    string json = SystemTextJsonExtension.ToSystemTextJsonString(group, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, 1);
                }
            }
        }
    }

    protected IEnumerable<TopicJson> GetVariableBasicData(IEnumerable<VariableBasicData> item)
    {
        IEnumerable<VariableBasicData>? data = null;
        if (!_businessPropertyWithCacheIntervalScript.BigTextScriptVariableModel.IsNullOrWhiteSpace())
        {
            foreach (var v in GetVariableScript(item))
                yield return v;

            yield break;  // 提前结束
        }
        else
        {
            data = item;
        }
        var topics = Match(_businessPropertyWithCacheIntervalScript.VariableTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的变量主题
                        string topic = _businessPropertyWithCacheIntervalScript.VariableTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsVariableList)
                        {

                            // 如果是变量列表，则将整个分组转换为 JSON 字符串
                            string json = group.Select(a => a).GroupBy(a => a.DeviceName, b => b).ToDictionary(a => a.Key, b => b.ToList()).ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, group.Count());
                        }
                        else
                        {
                            // 如果不是变量列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                string json = SystemTextJsonExtension.ToSystemTextJsonString(gro, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsVariableList)
            {
                string json = data.Select(a => a).GroupBy(a => a.DeviceName, b => b).ToDictionary(a => a.Key, b => b.ToList()).ToSystemTextJsonString(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, data.Count());
            }
            else
            {
                foreach (var group in data)
                {
                    string json = SystemTextJsonExtension.ToSystemTextJsonString(group, _businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, 1);
                }
            }
        }
    }

    protected IEnumerable<TopicArray> GetAlarmTopicArrays(IEnumerable<AlarmVariable> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<AlarmVariable>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptAlarmModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.AlarmTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics);

                foreach (var group in groups)
                {
                    // 上传主题
                    // 获取预定义的报警主题
                    string topic = _businessPropertyWithCacheIntervalScript.AlarmTopic;

                    // 将主题中的占位符替换为分组键对应的值
                    for (int i = 0; i < topics.Count; i++)
                    {
                        topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                    }

                    // 上传内容
                    if (_businessPropertyWithCacheIntervalScript.IsAlarmList)
                    {
                        var gList = group.Select(a => a).ToList();
                        var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                        // 将主题和 JSON 内容添加到列表中
                        yield return new(topic, json, gList.Count);
                    }
                    else
                    {
                        // 如果不是报警列表，则将每个分组元素分别转换为 JSON 字符串
                        foreach (var gro in group)
                        {
                            var json = gro.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, 1);
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsAlarmList)
            {
                var gList = data.Select(a => a).ToList();
                var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.AlarmTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    var json = group.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.AlarmTopic, json, 1);
                }
            }
        }

    }

    protected IEnumerable<TopicArray> GetDeviceTopicArray(IEnumerable<DeviceBasicData> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<DeviceBasicData>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptDeviceModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.DeviceTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的设备主题
                        string topic = _businessPropertyWithCacheIntervalScript.DeviceTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsDeviceList)
                        {
                            // 如果是设备列表，则将整个分组转换为 JSON 字符串
                            var gList = group.Select(a => a).ToList();
                            var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, gList.Count);
                        }
                        else
                        {
                            // 如果不是设备列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                var json = gro.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsDeviceList)
            {
                var gList = data.Select(a => a).ToList();
                var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.DeviceTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    var json = group.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.DeviceTopic, json, 1);
                }
            }
        }
    }

    protected IEnumerable<TopicArray> GetVariableScriptTopicArray(IEnumerable<VariableBasicData> item)
    {
        var data = Application.DynamicModelExtension.GetDynamicModel<VariableBasicData>(item, _businessPropertyWithCacheIntervalScript.BigTextScriptVariableModel);
        var topics = Match(_businessPropertyWithCacheIntervalScript.VariableTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的变量主题
                        string topic = _businessPropertyWithCacheIntervalScript.VariableTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsVariableList)
                        {
                            // 如果是变量列表，则将整个分组转换为 JSON 字符串
                            var gList = group.Select(a => a).ToList();
                            var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, gList.Count);
                        }
                        else
                        {
                            // 如果不是变量列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                var json = gro.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsVariableList)
            {
                var gList = data.Select(a => a).ToList();
                var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    var json = group.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, 1);
                }
            }
        }
    }

    protected IEnumerable<TopicArray> GetVariableBasicDataTopicArray(IEnumerable<VariableBasicData> item)
    {
        IEnumerable<VariableBasicData>? data = null;
        if (!_businessPropertyWithCacheIntervalScript.BigTextScriptVariableModel.IsNullOrWhiteSpace())
        {
            foreach (var v in GetVariableScriptTopicArray(item))
                yield return v;

            yield break;  // 提前结束
        }
        else
        {
            data = item;
        }

        var topics = Match(_businessPropertyWithCacheIntervalScript.VariableTopic);
        if (topics.Count > 0)
        {
            {
                //获取分组最终结果
                var groups = data.GroupByKeys(topics).ToList();
                if (groups.Count > 0)
                {
                    foreach (var group in groups)
                    {
                        // 上传主题
                        // 获取预定义的变量主题
                        string topic = _businessPropertyWithCacheIntervalScript.VariableTopic;

                        // 将主题中的占位符替换为分组键对应的值
                        for (int i = 0; i < topics.Count; i++)
                        {
                            topic = topic.Replace(@"${" + topics[i] + @"}", group.Key[i]?.ToString());
                        }

                        // 上传内容
                        if (_businessPropertyWithCacheIntervalScript.IsVariableList)
                        {
                            // 如果是变量列表，则将整个分组转换为 JSON 字符串
                            var gList = group.Select(a => a).ToList();
                            var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                            // 将主题和 JSON 内容添加到列表中
                            yield return new(topic, json, gList.Count);
                        }
                        else
                        {
                            // 如果不是变量列表，则将每个分组元素分别转换为 JSON 字符串
                            foreach (var gro in group)
                            {
                                var json = gro.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                                // 将主题和 JSON 内容添加到列表中
                                yield return new(topic, json, 1);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if (_businessPropertyWithCacheIntervalScript.IsVariableList)
            {
                var gList = data.Select(a => a).ToList();
                var json = gList.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, gList.Count);
            }
            else
            {
                foreach (var group in data)
                {
                    var json = group.ToSystemTextJsonUtf8Bytes(_businessPropertyWithCacheIntervalScript.JsonFormattingIndented);
                    yield return new(_businessPropertyWithCacheIntervalScript.VariableTopic, json, 1);
                }
            }
        }
    }


    protected string GetDetailLogString(TopicArray topicArray, int queueCount)
    {
        if (queueCount > 0)
            return $"Up Topic：{topicArray.Topic}{Environment.NewLine}PayLoad：{Encoding.UTF8.GetString(topicArray.Payload)} {Environment.NewLine} VarModelQueue:{queueCount}";
        else
            return $"Up Topic：{topicArray.Topic}{Environment.NewLine}PayLoad：{Encoding.UTF8.GetString(topicArray.Payload)}";
    }

    protected string GetCountLogString(TopicArray topicArray, int queueCount)
    {
        if (queueCount > 0)
            return $"Up Topic：{topicArray.Topic}{Environment.NewLine}Count：{topicArray.Count} {Environment.NewLine} VarModelQueue:{queueCount}";
        else
            return $"Up Topic：{topicArray.Topic}{Environment.NewLine}Count：{topicArray.Count}";

    }
    [GeneratedRegex(@"\$\{(.+?)\}")]
    private static partial Regex TopicRegex();
    #endregion 封装方法
}
