using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Net;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
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;
using NPP.SmartSchedue.Api.Contracts.Core.Configuration;

namespace NPP.SmartSchedue.Api.Services.Notification;

/// <summary>
/// 通知服务 邮件
/// </summary>
[DynamicApi(Area = "app")]
public class EmailNotificationService : BaseService, IEmailNotificationService, IDynamicApi
{
    private readonly ILogger<EmailNotificationService> _logger;
    private readonly EmailConfiguration _emailConfig;
    private readonly INotificationTemplateService _templateService;

    public EmailNotificationService(
        ILogger<EmailNotificationService> logger,
        IOptions<EmailConfiguration> emailConfig,
        INotificationTemplateService templateService)
    {
        _logger = logger;
        _emailConfig = emailConfig.Value;
        _templateService = templateService;
    }

    /// <summary>
    /// 发送单个邮件
    /// </summary>
    [HttpPost]
    public async Task<SendEmailOutput> SendEmailAsync(SendEmailInput input)
    {
        var output = new SendEmailOutput
        {
            RecipientEmail = input.RecipientEmail,
            Subject = input.Subject
        };

        try
        {
            if (!_emailConfig.Enabled)
            {
                output.ErrorMessage = "邮件服务已禁用";
                return output;
            }

            if (!_emailConfig.IsValid())
            {
                output.ErrorMessage = "邮件配置无效";
                return output;
            }

            using var smtpClient = CreateSmtpClient();
            using var mailMessage = CreateMailMessage(input.RecipientEmail, input.Subject, input.Content, input.IsHtml);

            // 添加附件
            if (input.Attachments?.Any() == true)
            {
                AddAttachments(mailMessage, input.Attachments);
            }

            await smtpClient.SendMailAsync(mailMessage);

            output.IsSuccess = true;
            _logger.LogInformation("邮件发送成功：{Email} - {Subject}", input.RecipientEmail, input.Subject);
        }
        catch (Exception ex)
        {
            output.ErrorMessage = ex.Message;
            _logger.LogError(ex, "发送邮件失败：{Email} - {Subject}", input.RecipientEmail, input.Subject);
        }

        return output;
    }

    /// <summary>
    /// 批量发送邮件
    /// </summary>
    [HttpPost]
    public async Task<BatchSendEmailOutput> BatchSendEmailAsync(BatchSendEmailInput input)
    {
        var output = new BatchSendEmailOutput
        {
            TotalCount = input.Recipients.Count
        };

        if (!_emailConfig.Enabled)
        {
            return CreateFailedBatchOutput(input.Recipients, "邮件服务已禁用");
        }

        if (!_emailConfig.IsValid())
        {
            return CreateFailedBatchOutput(input.Recipients, "邮件配置无效");
        }

        // 并行发送邮件
        var tasks = input.Recipients.Select(async recipient =>
        {
            var emailInput = new SendEmailInput
            {
                RecipientEmail = recipient,
                Subject = input.Subject,
                Content = input.Content,
                IsHtml = input.IsHtml
            };

            return await SendEmailAsync(emailInput);
        });

        var results = await Task.WhenAll(tasks);

        output.Results.AddRange(results);
        output.SuccessCount = results.Count(r => r.IsSuccess);
        output.FailedCount = results.Count(r => !r.IsSuccess);

        _logger.LogInformation("批量发送邮件完成：总数 {Total}，成功 {Success}，失败 {Failed}", 
            output.TotalCount, output.SuccessCount, output.FailedCount);

        return output;
    }

    /// <summary>
    /// 个性化批量发送邮件
    /// </summary>
    [HttpPost]
    public async Task<BatchSendEmailOutput> BatchSendPersonalizedEmailAsync(BatchSendPersonalizedEmailInput input)
    {
        var output = new BatchSendEmailOutput
        {
            TotalCount = input.EmailItems.Count
        };

        if (!_emailConfig.Enabled)
        {
            return CreateFailedBatchOutput(input.EmailItems.Select(e => e.RecipientEmail), "邮件服务已禁用");
        }

        if (!_emailConfig.IsValid())
        {
            return CreateFailedBatchOutput(input.EmailItems.Select(e => e.RecipientEmail), "邮件配置无效");
        }

        // 并行发送邮件
        var tasks = input.EmailItems.Select(async item =>
        {
            var emailInput = new SendEmailInput
            {
                RecipientEmail = item.RecipientEmail,
                Subject = item.Subject,
                Content = item.Content,
                IsHtml = item.IsHtml,
                Attachments = item.Attachments
            };

            return await SendEmailAsync(emailInput);
        });

        var results = await Task.WhenAll(tasks);

        output.Results.AddRange(results);
        output.SuccessCount = results.Count(r => r.IsSuccess);
        output.FailedCount = results.Count(r => !r.IsSuccess);

        _logger.LogInformation("个性化批量发送邮件完成：总数 {Total}，成功 {Success}，失败 {Failed}", 
            output.TotalCount, output.SuccessCount, output.FailedCount);

        return output;
    }

    /// <summary>
    /// 使用模板发送邮件
    /// </summary>
    [HttpPost]
    public async Task<SendEmailOutput> SendEmailByTemplateAsync(SendEmailByTemplateInput input)
    {
        var output = new SendEmailOutput
        {
            RecipientEmail = input.RecipientEmail
        };

        try
        {
            // 渲染模板
            var subjectInput = new RenderTemplateInput
            {
                Template = input.SubjectTemplate,
                Variables = input.Variables ?? new Dictionary<string, string>()
            };
            var subjectResult = await _templateService.RenderTemplateAsync(subjectInput);
            
            var contentInput = new RenderTemplateInput
            {
                Template = input.ContentTemplate,
                Variables = input.Variables ?? new Dictionary<string, string>()
            };
            var contentResult = await _templateService.RenderTemplateAsync(contentInput);

            // 检查渲染是否成功
            if (!subjectResult.Success)
            {
                output.ErrorMessage = "主题模板渲染失败: " + subjectResult.ErrorMessage;
                return output;
            }
            
            if (!contentResult.Success)
            {
                output.ErrorMessage = "内容模板渲染失败: " + contentResult.ErrorMessage;
                return output;
            }

            // 创建邮件发送请求
            var emailInput = new SendEmailInput
            {
                RecipientEmail = input.RecipientEmail,
                Subject = subjectResult.RenderedContent,
                Content = contentResult.RenderedContent,
                IsHtml = input.IsHtml
            };

            return await SendEmailAsync(emailInput);
        }
        catch (Exception ex)
        {
            output.ErrorMessage = ex.Message;
            _logger.LogError(ex, "使用模板发送邮件失败：{Email}", input.RecipientEmail);
            return output;
        }
    }

    /// <summary>
    /// 验证邮箱地址格式
    /// </summary>
    public async Task<bool> IsValidEmailAsync(string email)
    {
        return await Task.FromResult(IsValidEmail(email));
    }

    /// <summary>
    /// 检查邮件服务器连接状态
    /// </summary>
    public async Task<EmailServerStatusOutput> CheckEmailServerStatusAsync()
    {
        var output = new EmailServerStatusOutput
        {
            SmtpServer = _emailConfig.SmtpServer,
            SmtpPort = _emailConfig.SmtpPort
        };

        var startTime = DateTime.Now;

        try
        {
            if (!_emailConfig.IsValid())
            {
                output.ErrorMessage = "邮件配置无效";
                return output;
            }

            using var smtpClient = CreateSmtpClient();
            
            // 创建一个测试邮件来验证连接
            var testMail = new MailMessage
            {
                From = new MailAddress(_emailConfig.SenderEmail, _emailConfig.SenderName),
                Subject = "连接测试",
                Body = "这是一个连接测试邮件，可以忽略。",
                IsBodyHtml = false
            };
            testMail.To.Add(_emailConfig.SenderEmail); // 发送给自己进行测试
            
            await smtpClient.SendMailAsync(testMail);

            output.IsAvailable = true;
            output.ResponseTimeMs = (int)(DateTime.Now - startTime).TotalMilliseconds;

            _logger.LogInformation("邮件服务器连接测试成功：{Server}:{Port}, 响应时间：{ResponseTime}ms", 
                _emailConfig.SmtpServer, _emailConfig.SmtpPort, output.ResponseTimeMs);
        }
        catch (Exception ex)
        {
            output.ErrorMessage = ex.Message;
            output.ResponseTimeMs = (int)(DateTime.Now - startTime).TotalMilliseconds;
            _logger.LogError(ex, "邮件服务器连接测试失败");
        }

        return output;
    }

    #region 私有辅助方法

    /// <summary>
    /// 验证邮箱地址格式
    /// </summary>
    private bool IsValidEmail(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
            return false;

        try
        {
            var emailRegex = new Regex(
                @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
                RegexOptions.IgnoreCase | RegexOptions.Compiled);

            return emailRegex.IsMatch(email);
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 创建SMTP客户端
    /// </summary>
    private SmtpClient CreateSmtpClient()
    {
        return new SmtpClient(_emailConfig.SmtpServer, _emailConfig.SmtpPort)
        {
            Credentials = new NetworkCredential(_emailConfig.SenderEmail, _emailConfig.SenderPassword),
            EnableSsl = _emailConfig.EnableSsl,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            Timeout = _emailConfig.TimeoutSeconds * 1000
        };
    }

    /// <summary>
    /// 创建邮件消息
    /// </summary>
    private MailMessage CreateMailMessage(string recipientEmail, string subject, string content, bool isHtml)
    {
        var mailMessage = new MailMessage
        {
            From = new MailAddress(_emailConfig.SenderEmail, _emailConfig.SenderName),
            Subject = subject,
            Body = content,
            IsBodyHtml = isHtml
        };

        mailMessage.To.Add(recipientEmail);
        return mailMessage;
    }

    /// <summary>
    /// 添加附件
    /// </summary>
    private void AddAttachments(MailMessage mailMessage, List<string> attachments)
    {
        foreach (var attachmentPath in attachments)
        {
            if (File.Exists(attachmentPath))
            {
                var attachment = new Attachment(attachmentPath);
                mailMessage.Attachments.Add(attachment);
            }
            else
            {
                _logger.LogWarning("附件文件不存在：{Path}", attachmentPath);
            }
        }
    }

    /// <summary>
    /// 创建失败的批量发送输出
    /// </summary>
    private BatchSendEmailOutput CreateFailedBatchOutput(IEnumerable<string> recipients, string errorMessage)
    {
        var output = new BatchSendEmailOutput
        {
            TotalCount = recipients.Count(),
            FailedCount = recipients.Count()
        };

        foreach (var recipient in recipients)
        {
            output.Results.Add(new SendEmailOutput
            {
                RecipientEmail = recipient,
                IsSuccess = false,
                ErrorMessage = errorMessage
            });
        }

        return output;
    }

    #endregion
}