using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using ZhonTai.Admin.Services;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
using NPP.SmartSchedue.Api.Contracts.Services.Notification;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Notification.Output;

namespace NPP.SmartSchedue.Api.Services.Notification;

/// <summary>
/// 通知服务 模板
/// </summary>
[DynamicApi(Area = "app")]
public class NotificationTemplateService : BaseService, INotificationTemplateService, IDynamicApi
{
    // 变量匹配正则表达式：匹配 {变量名} 格式
    private static readonly Regex VariableRegex = new Regex(@"\{([a-zA-Z_][a-zA-Z0-9_]*)\}", RegexOptions.Compiled);

    #region 模板渲染

    /// <summary>
    /// 渲染通知模板
    /// 支持变量替换，如：{变量名}
    /// </summary>
    /// <param name="input">渲染模板输入参数</param>
    /// <returns>渲染结果</returns>
    [HttpPost]
    public async Task<RenderTemplateOutput> RenderTemplateAsync(RenderTemplateInput input)
    {
        try
        {
            var renderedContent = RenderTemplateCore(input.Template, input.Variables);
            
            return await Task.FromResult(new RenderTemplateOutput
            {
                RenderedContent = renderedContent,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new RenderTemplateOutput
            {
                Success = false,
                ErrorMessage = $"渲染模板时发生错误：{ex.Message}"
            };
        }
    }

    #endregion

    #region 模板验证

    /// <summary>
    /// 验证模板语法是否正确
    /// </summary>
    /// <param name="input">验证模板输入参数</param>
    /// <returns>验证结果</returns>
    [HttpPost]
    public async Task<ValidateTemplateOutput> ValidateTemplateAsync(ValidateTemplateInput input)
    {
        try
        {
            var validationResult = ValidateTemplateCore(input.Template);
            
            return await Task.FromResult(new ValidateTemplateOutput
            {
                ValidationResult = validationResult,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new ValidateTemplateOutput
            {
                Success = false,
                ErrorMessage = $"验证模板时发生错误：{ex.Message}",
                ValidationResult = new TemplateValidationResult()
            };
        }
    }

    #endregion

    #region 变量解析

    /// <summary>
    /// 提取模板中的变量列表
    /// </summary>
    /// <param name="input">提取变量输入参数</param>
    /// <returns>变量列表</returns>
    [HttpPost]
    public async Task<ExtractVariablesOutput> ExtractVariablesAsync(ExtractVariablesInput input)
    {
        try
        {
            var variables = ExtractVariablesCore(input.Template);
            
            return await Task.FromResult(new ExtractVariablesOutput
            {
                Variables = variables,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new ExtractVariablesOutput
            {
                Success = false,
                ErrorMessage = $"提取变量时发生错误：{ex.Message}"
            };
        }
    }

    #endregion

    #region 内置变量

    /// <summary>
    /// 获取系统内置变量
    /// </summary>
    /// <returns>系统变量字典</returns>
    [HttpPost]
    public async Task<GetSystemVariablesOutput> GetSystemVariablesAsync()
    {
        try
        {
            var systemVariables = GetSystemVariablesCore();
            
            return await Task.FromResult(new GetSystemVariablesOutput
            {
                Variables = systemVariables,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new GetSystemVariablesOutput
            {
                Success = false,
                ErrorMessage = $"获取系统变量时发生错误：{ex.Message}"
            };
        }
    }

    /// <summary>
    /// 获取业务相关变量
    /// </summary>
    /// <param name="input">获取业务变量输入参数</param>
    /// <returns>业务变量字典</returns>
    [HttpPost]
    public async Task<GetBusinessVariablesOutput> GetBusinessVariablesAsync(GetBusinessVariablesInput input)
    {
        try
        {
            var businessVariables = await GetBusinessVariablesCore(input.BusinessType, input.BusinessId, input.BusinessData);
            
            return new GetBusinessVariablesOutput
            {
                Variables = businessVariables,
                Success = true
            };
        }
        catch (Exception ex)
        {
            return new GetBusinessVariablesOutput
            {
                Success = false,
                ErrorMessage = $"获取业务变量时发生错误：{ex.Message}"
            };
        }
    }

    #endregion

    #region 模板预定义

    /// <summary>
    /// 获取预定义模板列表
    /// </summary>
    /// <param name="input">获取模板列表输入参数</param>
    /// <returns>预定义模板列表</returns>
    [HttpPost]
    public async Task<GetPredefinedTemplatesOutput> GetPredefinedTemplatesAsync(GetPredefinedTemplatesInput input)
    {
        try
        {
            var templates = GetDefaultPredefinedTemplates();
            
            if (!string.IsNullOrWhiteSpace(input.Category))
            {
                templates = templates.Where(t => 
                    string.Equals(t.Category, input.Category, StringComparison.OrdinalIgnoreCase)).ToList();
            }

            return await Task.FromResult(new GetPredefinedTemplatesOutput
            {
                Templates = templates,
                TotalCount = templates.Count,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new GetPredefinedTemplatesOutput
            {
                Success = false,
                ErrorMessage = $"获取预定义模板列表时发生错误：{ex.Message}"
            };
        }
    }

    /// <summary>
    /// 获取指定预定义模板
    /// </summary>
    /// <param name="input">获取指定模板输入参数</param>
    /// <returns>预定义模板</returns>
    [HttpPost]
    public async Task<GetPredefinedTemplateOutput> GetPredefinedTemplateAsync(GetPredefinedTemplateInput input)
    {
        try
        {
            var templates = GetDefaultPredefinedTemplates();
            var template = templates.FirstOrDefault(t => 
                string.Equals(t.TemplateId, input.TemplateId, StringComparison.OrdinalIgnoreCase));

            return await Task.FromResult(new GetPredefinedTemplateOutput
            {
                Template = template,
                Success = true
            });
        }
        catch (Exception ex)
        {
            return new GetPredefinedTemplateOutput
            {
                Success = false,
                ErrorMessage = $"获取指定预定义模板时发生错误：{ex.Message}"
            };
        }
    }

    #endregion

    #region 核心业务逻辑方法

    /// <summary>
    /// 核心模板渲染逻辑
    /// </summary>
    /// <param name="template">模板内容</param>
    /// <param name="variables">变量字典</param>
    /// <returns>渲染后的内容</returns>
    private string RenderTemplateCore(string template, Dictionary<string, string> variables)
    {
        if (string.IsNullOrWhiteSpace(template))
            return string.Empty;

        if (variables == null || !variables.Any())
            return template;

        var result = template;

        // 替换所有匹配的变量
        result = VariableRegex.Replace(result, match =>
        {
            var variableName = match.Groups[1].Value;
            
            // 如果变量存在于字典中，则替换
            if (variables.TryGetValue(variableName, out var variableValue))
            {
                return variableValue ?? string.Empty;
            }

            // 如果变量不存在，保留原始占位符
            return match.Value;
        });

        return result;
    }

    /// <summary>
    /// 核心模板验证逻辑
    /// </summary>
    /// <param name="template">模板内容</param>
    /// <returns>验证结果</returns>
    private TemplateValidationResult ValidateTemplateCore(string template)
    {
        var result = new TemplateValidationResult();

        if (string.IsNullOrWhiteSpace(template))
        {
            result.AddError("模板内容不能为空");
            return result;
        }

        try
        {
            // 提取所有变量
            var variables = ExtractVariablesCore(template);
            result.Variables = variables;

            // 检查变量命名规范
            foreach (var variable in variables)
            {
                if (!IsValidVariableName(variable))
                {
                    result.AddError($"变量名 '{variable}' 不符合命名规范，变量名只能包含字母、数字和下划线，且不能以数字开头");
                }
            }

            // 检查是否有未闭合的大括号
            var openBraceCount = template.Count(c => c == '{');
            var closeBraceCount = template.Count(c => c == '}');
            if (openBraceCount != closeBraceCount)
            {
                result.AddError($"大括号不匹配：找到 {openBraceCount} 个左大括号和 {closeBraceCount} 个右大括号");
            }

            // 检查嵌套大括号
            if (template.Contains("{{") || template.Contains("}}"))
            {
                result.AddWarning("发现嵌套大括号，这可能导致变量替换异常");
            }

            // 检查空的变量占位符
            if (template.Contains("{}"))
            {
                result.AddError("发现空的变量占位符 {}，请指定变量名");
            }
        }
        catch (Exception ex)
        {
            result.AddError($"模板验证时发生异常：{ex.Message}");
        }

        return result;
    }

    /// <summary>
    /// 核心变量提取逻辑
    /// </summary>
    /// <param name="template">模板内容</param>
    /// <returns>变量名列表</returns>
    private List<string> ExtractVariablesCore(string template)
    {
        if (string.IsNullOrWhiteSpace(template))
            return new List<string>();

        var variables = new HashSet<string>();
        var matches = VariableRegex.Matches(template);

        foreach (Match match in matches)
        {
            var variableName = match.Groups[1].Value;
            variables.Add(variableName);
        }

        return variables.OrderBy(v => v).ToList();
    }

    /// <summary>
    /// 获取系统内置变量核心逻辑
    /// </summary>
    /// <returns>系统变量字典</returns>
    private Dictionary<string, string> GetSystemVariablesCore()
    {
        var now = DateTime.Now;
        
        return new Dictionary<string, string>
        {
            ["CurrentDateTime"] = now.ToString("yyyy-MM-dd HH:mm:ss"),
            ["CurrentDate"] = now.ToString("yyyy-MM-dd"),
            ["CurrentTime"] = now.ToString("HH:mm:ss"),
            ["CurrentYear"] = now.Year.ToString(),
            ["CurrentMonth"] = now.Month.ToString(),
            ["CurrentDay"] = now.Day.ToString(),
            ["CurrentWeekday"] = GetWeekdayName(now.DayOfWeek),
            ["SystemName"] = "NPP智能生产调度系统",
            ["CompanyName"] = "核电站"
        };
    }

    /// <summary>
    /// 获取业务相关变量核心逻辑
    /// </summary>
    /// <param name="businessType">业务类型</param>
    /// <param name="businessId">业务ID</param>
    /// <param name="businessData">业务数据</param>
    /// <returns>业务变量字典</returns>
    private async Task<Dictionary<string, string>> GetBusinessVariablesCore(
        string businessType, 
        long? businessId, 
        string businessData)
    {
        var businessVariables = new Dictionary<string, string>
        {
            ["BusinessType"] = businessType ?? "",
            ["BusinessId"] = businessId?.ToString() ?? ""
        };

        // 根据业务类型添加特定变量
        switch (businessType?.ToLower())
        {
            case "workorder":
            case "工作任务":
                await AddWorkOrderVariablesAsync(businessVariables, businessId, businessData);
                break;
            case "equipment":
            case "设备":
                await AddEquipmentVariablesAsync(businessVariables, businessId, businessData);
                break;
            case "personnel":
            case "人员":
                await AddPersonnelVariablesAsync(businessVariables, businessId, businessData);
                break;
            case "maintenance":
            case "维护":
                await AddMaintenanceVariablesAsync(businessVariables, businessId, businessData);
                break;
        }

        return businessVariables;
    }

    #endregion

    #region 私有辅助方法

    /// <summary>
    /// 验证变量名是否符合规范
    /// </summary>
    /// <param name="variableName">变量名</param>
    /// <returns>是否符合规范</returns>
    private static bool IsValidVariableName(string variableName)
    {
        if (string.IsNullOrWhiteSpace(variableName))
            return false;

        // 变量名只能包含字母、数字和下划线，且不能以数字开头
        return Regex.IsMatch(variableName, @"^[a-zA-Z_][a-zA-Z0-9_]*$");
    }

    /// <summary>
    /// 获取星期几的中文名称
    /// </summary>
    /// <param name="dayOfWeek">星期枚举</param>
    /// <returns>中文名称</returns>
    private static string GetWeekdayName(DayOfWeek dayOfWeek)
    {
        return dayOfWeek switch
        {
            DayOfWeek.Monday => "星期一",
            DayOfWeek.Tuesday => "星期二",
            DayOfWeek.Wednesday => "星期三",
            DayOfWeek.Thursday => "星期四",
            DayOfWeek.Friday => "星期五",
            DayOfWeek.Saturday => "星期六",
            DayOfWeek.Sunday => "星期日",
            _ => ""
        };
    }

    /// <summary>
    /// 添加工作任务相关变量
    /// </summary>
    /// <param name="variables">变量字典</param>
    /// <param name="businessId">业务ID</param>
    /// <param name="businessData">业务数据</param>
    /// <returns>异步任务</returns>
    private async Task AddWorkOrderVariablesAsync(Dictionary<string, string> variables, long? businessId, string businessData)
    {
        // 这里可以根据businessId查询工作任务详情，然后添加相关变量
        // 为了简化示例，先添加一些基础变量
        variables["WorkOrderId"] = businessId?.ToString() ?? "";
        
        if (!string.IsNullOrWhiteSpace(businessData))
        {
            try
            {
                var data = JsonConvert.DeserializeObject<Dictionary<string, object>>(businessData);
                if (data != null)
                {
                    foreach (var item in data)
                    {
                        variables[$"WorkOrder_{item.Key}"] = item.Value?.ToString() ?? "";
                    }
                }
            }
            catch (JsonException)
            {
                // 忽略JSON解析错误
            }
        }

        await Task.CompletedTask;
    }

    /// <summary>
    /// 添加设备相关变量
    /// </summary>
    /// <param name="variables">变量字典</param>
    /// <param name="businessId">业务ID</param>
    /// <param name="businessData">业务数据</param>
    /// <returns>异步任务</returns>
    private async Task AddEquipmentVariablesAsync(Dictionary<string, string> variables, long? businessId, string businessData)
    {
        variables["EquipmentId"] = businessId?.ToString() ?? "";
        // 可以添加更多设备相关变量
        await Task.CompletedTask;
    }

    /// <summary>
    /// 添加人员相关变量
    /// </summary>
    /// <param name="variables">变量字典</param>
    /// <param name="businessId">业务ID</param>
    /// <param name="businessData">业务数据</param>
    /// <returns>异步任务</returns>
    private async Task AddPersonnelVariablesAsync(Dictionary<string, string> variables, long? businessId, string businessData)
    {
        variables["PersonnelId"] = businessId?.ToString() ?? "";
        // 可以添加更多人员相关变量
        await Task.CompletedTask;
    }

    /// <summary>
    /// 添加维护相关变量
    /// </summary>
    /// <param name="variables">变量字典</param>
    /// <param name="businessId">业务ID</param>
    /// <param name="businessData">业务数据</param>
    /// <returns>异步任务</returns>
    private async Task AddMaintenanceVariablesAsync(Dictionary<string, string> variables, long? businessId, string businessData)
    {
        variables["MaintenanceId"] = businessId?.ToString() ?? "";
        // 可以添加更多维护相关变量
        await Task.CompletedTask;
    }

    /// <summary>
    /// 获取默认预定义模板
    /// </summary>
    /// <returns>预定义模板列表</returns>
    private static List<PredefinedTemplate> GetDefaultPredefinedTemplates()
    {
        return new List<PredefinedTemplate>
        {
            new PredefinedTemplate
            {
                TemplateId = "work_order_assignment",
                TemplateName = "工作任务分配通知",
                Category = "工作任务",
                Description = "当工作任务被分配给人员时发送的通知",
                EmailSubjectTemplate = "工作任务分配通知 - {WorkOrderCode}",
                EmailContentTemplate = @"
                    <div>
                        <h3>工作任务分配通知</h3>
                        <p>您好，{PersonnelName}！</p>
                        <p>有新的工作任务分配给您：</p>
                        <ul>
                            <li>任务代码：{WorkOrderCode}</li>
                            <li>项目号：{ProjectNumber}</li>
                            <li>工序名称：{ProcessName}</li>
                            <li>计划开始时间：{PlannedStartTime}</li>
                            <li>计划结束时间：{PlannedEndTime}</li>
                        </ul>
                        <p>请及时查看并开始执行任务。</p>
                        <p>系统时间：{CurrentDateTime}</p>
                    </div>
                ",
                SystemMessageTitleTemplate = "新任务分配 - {WorkOrderCode}",
                SystemMessageContentTemplate = "您有新的工作任务：{WorkOrderCode}，请及时处理。",
                SupportedVariables = new List<TemplateVariable>
                {
                    new TemplateVariable { Name = "PersonnelName", Description = "人员姓名", IsRequired = true },
                    new TemplateVariable { Name = "WorkOrderCode", Description = "任务代码", IsRequired = true },
                    new TemplateVariable { Name = "ProjectNumber", Description = "项目号", IsRequired = true },
                    new TemplateVariable { Name = "ProcessName", Description = "工序名称", IsRequired = true },
                    new TemplateVariable { Name = "PlannedStartTime", Description = "计划开始时间", IsRequired = true },
                    new TemplateVariable { Name = "PlannedEndTime", Description = "计划结束时间", IsRequired = true }
                }
            },
            new PredefinedTemplate
            {
                TemplateId = "equipment_maintenance_reminder",
                TemplateName = "设备维护提醒",
                Category = "设备维护",
                Description = "设备维护到期提醒通知",
                EmailSubjectTemplate = "设备维护提醒 - {EquipmentName}",
                EmailContentTemplate = @"
                    <div>
                        <h3>设备维护提醒</h3>
                        <p>您好，{PersonnelName}！</p>
                        <p>以下设备需要进行维护：</p>
                        <ul>
                            <li>设备名称：{EquipmentName}</li>
                            <li>设备编号：{EquipmentCode}</li>
                            <li>计划维护时间：{PlannedMaintenanceTime}</li>
                            <li>维护类型：{MaintenanceType}</li>
                        </ul>
                        <p>请及时安排维护工作。</p>
                        <p>系统时间：{CurrentDateTime}</p>
                    </div>
                ",
                SystemMessageTitleTemplate = "设备维护提醒 - {EquipmentName}",
                SystemMessageContentTemplate = "设备 {EquipmentName} 需要维护，计划时间：{PlannedMaintenanceTime}",
                SupportedVariables = new List<TemplateVariable>
                {
                    new TemplateVariable { Name = "PersonnelName", Description = "人员姓名", IsRequired = true },
                    new TemplateVariable { Name = "EquipmentName", Description = "设备名称", IsRequired = true },
                    new TemplateVariable { Name = "EquipmentCode", Description = "设备编号", IsRequired = true },
                    new TemplateVariable { Name = "PlannedMaintenanceTime", Description = "计划维护时间", IsRequired = true },
                    new TemplateVariable { Name = "MaintenanceType", Description = "维护类型", IsRequired = false }
                }
            }
        };
    }

    #endregion
}