using Microsoft.EntityFrameworkCore;
using FutureMailAPI.Data;
using FutureMailAPI.Models;
using FutureMailAPI.DTOs;

namespace FutureMailAPI.Services
{
    public class MailService : IMailService
    {
        private readonly FutureMailDbContext _context;
        
        public MailService(FutureMailDbContext context)
        {
            _context = context;
        }
        
        public async Task<ApiResponse<SentMailResponseDto>> CreateMailAsync(int userId, SentMailCreateDto createDto)
        {
            // 检查投递时间是否在未来
            if (createDto.DeliveryTime <= DateTime.UtcNow)
            {
                return ApiResponse<SentMailResponseDto>.ErrorResult("投递时间必须是未来时间");
            }
            
            // 如果是指定用户，检查用户是否存在
            int? recipientId = null;
            if (createDto.RecipientType == 1 && !string.IsNullOrEmpty(createDto.RecipientEmail))
            {
                var recipient = await _context.Users
                    .FirstOrDefaultAsync(u => u.Email == createDto.RecipientEmail);
                    
                if (recipient == null)
                {
                    return ApiResponse<SentMailResponseDto>.ErrorResult("收件人不存在");
                }
                
                recipientId = recipient.Id;
            }
            
            // 创建邮件
            var mail = new SentMail
            {
                Title = createDto.Title,
                Content = createDto.Content,
                SenderId = userId,
                RecipientType = createDto.RecipientType,
                RecipientId = recipientId,
                DeliveryTime = createDto.DeliveryTime,
                SentAt = DateTime.UtcNow, // 显式设置发送时间
                Status = createDto.DeliveryTime > DateTime.UtcNow ? 1 : 0, // 根据投递时间直接设置状态
                TriggerType = createDto.TriggerType,
                TriggerDetails = createDto.TriggerDetails,
                Attachments = createDto.Attachments,
                IsEncrypted = createDto.IsEncrypted,
                EncryptionKey = createDto.EncryptionKey,
                Theme = createDto.Theme
            };
            
            _context.SentMails.Add(mail);
            await _context.SaveChangesAsync();
            
            // 如果是发送状态（不是草稿），创建时间胶囊
            if (mail.Status == 1) // 已发送(待投递)
            {
                // 创建时间胶囊
                var timeCapsule = new TimeCapsule
                {
                    UserId = userId,
                    SentMailId = mail.Id,
                    PositionX = 0,
                    PositionY = 0,
                    PositionZ = 0,
                    Status = 1, // 漂浮中
                    Type = 0 // 普通
                };
                
                _context.TimeCapsules.Add(timeCapsule);
                await _context.SaveChangesAsync();
            }
            
            var mailResponse = await GetSentMailWithDetailsAsync(mail.Id);
            
            return ApiResponse<SentMailResponseDto>.SuccessResult(mailResponse, "邮件创建成功");
        }
        
        public async Task<ApiResponse<PagedResponse<SentMailResponseDto>>> GetSentMailsAsync(int userId, MailListQueryDto queryDto)
        {
            var query = _context.SentMails
                .Where(m => m.SenderId == userId)
                .Include(m => m.Sender)
                .Include(m => m.Recipient)
                .AsQueryable();
            
            // 应用筛选条件
            if (queryDto.Status.HasValue)
            {
                query = query.Where(m => m.Status == queryDto.Status.Value);
            }
            
            if (queryDto.RecipientType.HasValue)
            {
                query = query.Where(m => m.RecipientType == queryDto.RecipientType.Value);
            }
            
            if (!string.IsNullOrEmpty(queryDto.Keyword))
            {
                query = query.Where(m => m.Title.Contains(queryDto.Keyword) || m.Content.Contains(queryDto.Keyword));
            }
            
            if (queryDto.StartDate.HasValue)
            {
                query = query.Where(m => m.SentAt >= queryDto.StartDate.Value);
            }
            
            if (queryDto.EndDate.HasValue)
            {
                query = query.Where(m => m.SentAt <= queryDto.EndDate.Value);
            }
            
            // 排序
            query = query.OrderByDescending(m => m.SentAt);
            
            // 分页
            var totalCount = await query.CountAsync();
            var mails = await query
                .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                .Take(queryDto.PageSize)
                .ToListAsync();
            
            var mailDtos = mails.Select(MapToSentMailResponseDto).ToList();
            
            var pagedResponse = new PagedResponse<SentMailResponseDto>(
                mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
            
            return ApiResponse<PagedResponse<SentMailResponseDto>>.SuccessResult(pagedResponse);
        }
        
        public async Task<ApiResponse<SentMailResponseDto>> GetSentMailByIdAsync(int userId, int mailId)
        {
            var mail = await _context.SentMails
                .Include(m => m.Sender)
                .Include(m => m.Recipient)
                .FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
                
            if (mail == null)
            {
                return ApiResponse<SentMailResponseDto>.ErrorResult("邮件不存在");
            }
            
            var mailDto = MapToSentMailResponseDto(mail);
            
            return ApiResponse<SentMailResponseDto>.SuccessResult(mailDto);
        }
        
        public async Task<ApiResponse<SentMailResponseDto>> UpdateMailAsync(int userId, int mailId, SentMailUpdateDto updateDto)
        {
            var mail = await _context.SentMails
                .FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
                
            if (mail == null)
            {
                return ApiResponse<SentMailResponseDto>.ErrorResult("邮件不存在");
            }
            
            // 检查邮件是否已投递，已投递的邮件不能修改
            if (mail.Status >= 2)
            {
                return ApiResponse<SentMailResponseDto>.ErrorResult("已投递的邮件不能修改");
            }
            
            // 更新邮件信息
            if (updateDto.Title != null)
            {
                mail.Title = updateDto.Title;
            }
            
            if (updateDto.Content != null)
            {
                mail.Content = updateDto.Content;
            }
            
            if (updateDto.DeliveryTime.HasValue)
            {
                if (updateDto.DeliveryTime.Value <= DateTime.UtcNow)
                {
                    return ApiResponse<SentMailResponseDto>.ErrorResult("投递时间必须是未来时间");
                }
                
                mail.DeliveryTime = updateDto.DeliveryTime.Value;
            }
            
            if (updateDto.TriggerDetails != null)
            {
                mail.TriggerDetails = updateDto.TriggerDetails;
            }
            
            if (updateDto.Attachments != null)
            {
                mail.Attachments = updateDto.Attachments;
            }
            
            if (updateDto.Theme != null)
            {
                mail.Theme = updateDto.Theme;
            }
            
            await _context.SaveChangesAsync();
            
            var mailResponse = await GetSentMailWithDetailsAsync(mail.Id);
            
            return ApiResponse<SentMailResponseDto>.SuccessResult(mailResponse, "邮件更新成功");
        }
        
        public async Task<ApiResponse<bool>> DeleteMailAsync(int userId, int mailId)
        {
            var mail = await _context.SentMails
                .FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
                
            if (mail == null)
            {
                return ApiResponse<bool>.ErrorResult("邮件不存在");
            }
            
            // 检查邮件是否已投递，已投递的邮件不能删除
            if (mail.Status >= 2)
            {
                return ApiResponse<bool>.ErrorResult("已投递的邮件不能删除");
            }
            
            // 删除相关的时间胶囊
            var timeCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.SentMailId == mailId);
                
            if (timeCapsule != null)
            {
                _context.TimeCapsules.Remove(timeCapsule);
            }
            
            // 删除邮件
            _context.SentMails.Remove(mail);
            await _context.SaveChangesAsync();
            
            return ApiResponse<bool>.SuccessResult(true, "邮件删除成功");
        }
        
        public async Task<ApiResponse<PagedResponse<ReceivedMailResponseDto>>> GetReceivedMailsAsync(int userId, MailListQueryDto queryDto)
        {
            var query = _context.ReceivedMails
                .Where(r => r.RecipientId == userId)
                .Include(r => r.SentMail)
                .ThenInclude(m => m.Sender)
                .AsQueryable();
            
            // 应用筛选条件
            if (queryDto.Status.HasValue)
            {
                if (queryDto.Status.Value == 0) // 未读
                {
                    query = query.Where(r => !r.IsRead);
                }
                else if (queryDto.Status.Value == 1) // 已读
                {
                    query = query.Where(r => r.IsRead);
                }
            }
            
            if (!string.IsNullOrEmpty(queryDto.Keyword))
            {
                query = query.Where(r => r.SentMail.Title.Contains(queryDto.Keyword) || r.SentMail.Content.Contains(queryDto.Keyword));
            }
            
            if (queryDto.StartDate.HasValue)
            {
                query = query.Where(r => r.ReceivedAt >= queryDto.StartDate.Value);
            }
            
            if (queryDto.EndDate.HasValue)
            {
                query = query.Where(r => r.ReceivedAt <= queryDto.EndDate.Value);
            }
            
            // 排序
            query = query.OrderByDescending(r => r.ReceivedAt);
            
            // 分页
            var totalCount = await query.CountAsync();
            var receivedMails = await query
                .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                .Take(queryDto.PageSize)
                .ToListAsync();
            
            var mailDtos = receivedMails.Select(MapToReceivedMailResponseDto).ToList();
            
            var pagedResponse = new PagedResponse<ReceivedMailResponseDto>(
                mailDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
            
            return ApiResponse<PagedResponse<ReceivedMailResponseDto>>.SuccessResult(pagedResponse);
        }
        
        public async Task<ApiResponse<ReceivedMailResponseDto>> GetReceivedMailByIdAsync(int userId, int mailId)
        {
            var receivedMail = await _context.ReceivedMails
                .Include(r => r.SentMail)
                .ThenInclude(m => m.Sender)
                .FirstOrDefaultAsync(r => r.Id == mailId && r.RecipientId == userId);
                
            if (receivedMail == null)
            {
                return ApiResponse<ReceivedMailResponseDto>.ErrorResult("邮件不存在");
            }
            
            var mailDto = MapToReceivedMailResponseDto(receivedMail);
            
            return ApiResponse<ReceivedMailResponseDto>.SuccessResult(mailDto);
        }
        
        public async Task<ApiResponse<bool>> MarkReceivedMailAsReadAsync(int userId, int mailId)
        {
            var receivedMail = await _context.ReceivedMails
                .FirstOrDefaultAsync(r => r.Id == mailId && r.RecipientId == userId);
                
            if (receivedMail == null)
            {
                return ApiResponse<bool>.ErrorResult("邮件不存在");
            }
            
            if (!receivedMail.IsRead)
            {
                receivedMail.IsRead = true;
                receivedMail.ReadAt = DateTime.UtcNow;
                await _context.SaveChangesAsync();
            }
            
            return ApiResponse<bool>.SuccessResult(true, "邮件已标记为已读");
        }
        
        public Task<ApiResponse<SentMailResponseDto>> GetMailByIdAsync(int userId, int mailId)
        {
            return GetSentMailByIdAsync(userId, mailId);
        }
        
        public Task<ApiResponse<PagedResponse<SentMailResponseDto>>> GetMailsAsync(int userId, MailListQueryDto queryDto)
        {
            return GetSentMailsAsync(userId, queryDto);
        }
        
        public Task<ApiResponse<bool>> MarkAsReadAsync(int userId, int mailId)
        {
            return MarkReceivedMailAsReadAsync(userId, mailId);
        }
        
        public async Task<ApiResponse<bool>> RevokeMailAsync(int userId, int mailId)
        {
            var mail = await _context.SentMails
                .FirstOrDefaultAsync(m => m.Id == mailId && m.SenderId == userId);
                
            if (mail == null)
            {
                return ApiResponse<bool>.ErrorResult("邮件不存在");
            }
            
            // 检查邮件是否已投递，已投递的邮件不能撤销
            if (mail.Status >= 2)
            {
                return ApiResponse<bool>.ErrorResult("已投递的邮件不能撤销");
            }
            
            // 更新邮件状态为已撤销
            mail.Status = 4; // 4-已撤销
            await _context.SaveChangesAsync();
            
            // 更新相关的时间胶囊状态
            var timeCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.SentMailId == mailId);
                
            if (timeCapsule != null)
            {
                timeCapsule.Status = 3; // 3-已撤销
                await _context.SaveChangesAsync();
            }
            
            return ApiResponse<bool>.SuccessResult(true, "邮件已撤销");
        }
        
        private async Task<SentMailResponseDto> GetSentMailWithDetailsAsync(int mailId)
        {
            var mail = await _context.SentMails
                .Include(m => m.Sender)
                .Include(m => m.Recipient)
                .FirstOrDefaultAsync(m => m.Id == mailId);
                
            return MapToSentMailResponseDto(mail!);
        }
        
        private static SentMailResponseDto MapToSentMailResponseDto(SentMail mail)
        {
            return new SentMailResponseDto
            {
                Id = mail.Id,
                Title = mail.Title,
                Content = mail.Content,
                SenderId = mail.SenderId,
                SenderUsername = mail.Sender?.Username ?? "",
                RecipientType = mail.RecipientType,
                RecipientId = mail.RecipientId,
                RecipientUsername = mail.Recipient?.Username ?? "",
                SentAt = mail.SentAt,
                DeliveryTime = mail.DeliveryTime,
                Status = mail.Status,
                StatusText = GetStatusText(mail.Status),
                TriggerType = mail.TriggerType,
                TriggerTypeText = GetTriggerTypeText(mail.TriggerType),
                TriggerDetails = mail.TriggerDetails,
                Attachments = mail.Attachments,
                IsEncrypted = mail.IsEncrypted,
                Theme = mail.Theme,
                RecipientTypeText = GetRecipientTypeText(mail.RecipientType),
                DaysUntilDelivery = (int)(mail.DeliveryTime - DateTime.UtcNow).TotalDays
            };
        }
        
        private static ReceivedMailResponseDto MapToReceivedMailResponseDto(ReceivedMail receivedMail)
        {
            return new ReceivedMailResponseDto
            {
                Id = receivedMail.Id,
                SentMailId = receivedMail.SentMailId,
                Title = receivedMail.SentMail.Title,
                Content = receivedMail.SentMail.Content,
                SenderUsername = receivedMail.SentMail.Sender?.Username ?? "",
                SentAt = receivedMail.SentMail.SentAt,
                ReceivedAt = receivedMail.ReceivedAt,
                IsRead = receivedMail.IsRead,
                ReadAt = receivedMail.ReadAt,
                IsReplied = receivedMail.IsReplied,
                ReplyMailId = receivedMail.ReplyMailId,
                Theme = receivedMail.SentMail.Theme
            };
        }
        
        private static string GetStatusText(int status)
        {
            return status switch
            {
                0 => "草稿",
                1 => "已发送(待投递)",
                2 => "投递中",
                3 => "已送达",
                _ => "未知"
            };
        }
        
        private static string GetRecipientTypeText(int recipientType)
        {
            return recipientType switch
            {
                0 => "自己",
                1 => "指定用户",
                2 => "公开时间胶囊",
                _ => "未知"
            };
        }
        
        private static string GetTriggerTypeText(int triggerType)
        {
            return triggerType switch
            {
                0 => "时间",
                1 => "地点",
                2 => "事件",
                _ => "未知"
            };
        }
    }
}