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

namespace FutureMailAPI.Services
{
    public class TimeCapsuleService : ITimeCapsuleService
    {
        private readonly FutureMailDbContext _context;
        
        public TimeCapsuleService(FutureMailDbContext context)
        {
            _context = context;
        }
        
        public async Task<ApiResponse<TimeCapsuleResponseDto>> CreateTimeCapsuleAsync(int userId, TimeCapsuleCreateDto createDto)
        {
            // 检查邮件是否存在且属于当前用户
            var mail = await _context.SentMails
                .FirstOrDefaultAsync(m => m.Id == createDto.SentMailId && m.SenderId == userId);
                
            if (mail == null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("邮件不存在或无权限");
            }
            
            // 检查是否已存在时间胶囊
            var existingCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.SentMailId == createDto.SentMailId);
                
            if (existingCapsule != null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("该邮件已创建时间胶囊");
            }
            
            // 创建时间胶囊
            var timeCapsule = new TimeCapsule
            {
                UserId = userId,
                SentMailId = createDto.SentMailId,
                PositionX = createDto.PositionX,
                PositionY = createDto.PositionY,
                PositionZ = createDto.PositionZ,
                Size = createDto.Size,
                Color = createDto.Color,
                Opacity = createDto.Opacity,
                Rotation = createDto.Rotation,
                Status = 1, // 漂浮中
                Type = createDto.Type
            };
            
            _context.TimeCapsules.Add(timeCapsule);
            await _context.SaveChangesAsync();
            
            var capsuleResponse = await GetTimeCapsuleWithDetailsAsync(timeCapsule.Id);
            
            return ApiResponse<TimeCapsuleResponseDto>.SuccessResult(capsuleResponse, "时间胶囊创建成功");
        }
        
        public async Task<ApiResponse<PagedResponse<TimeCapsuleResponseDto>>> GetTimeCapsulesAsync(int userId, TimeCapsuleListQueryDto queryDto)
        {
            var query = _context.TimeCapsules
                .Where(tc => tc.UserId == userId)
                .Include(tc => tc.User)
                .Include(tc => tc.SentMail)
                .AsQueryable();
            
            // 应用筛选条件
            if (queryDto.Status.HasValue)
            {
                query = query.Where(tc => tc.Status == queryDto.Status.Value);
            }
            
            if (queryDto.Type.HasValue)
            {
                query = query.Where(tc => tc.Type == queryDto.Type.Value);
            }
            
            if (queryDto.IncludeExpired.HasValue && !queryDto.IncludeExpired.Value)
            {
                query = query.Where(tc => tc.SentMail.DeliveryTime > DateTime.UtcNow);
            }
            
            // 排序
            query = query.OrderByDescending(tc => tc.CreatedAt);
            
            // 分页
            var totalCount = await query.CountAsync();
            var capsules = await query
                .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                .Take(queryDto.PageSize)
                .ToListAsync();
            
            var capsuleDtos = capsules.Select(MapToTimeCapsuleResponseDto).ToList();
            
            var pagedResponse = new PagedResponse<TimeCapsuleResponseDto>(
                capsuleDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
            
            return ApiResponse<PagedResponse<TimeCapsuleResponseDto>>.SuccessResult(pagedResponse);
        }
        
        public async Task<ApiResponse<TimeCapsuleResponseDto>> GetTimeCapsuleByIdAsync(int userId, int capsuleId)
        {
            var timeCapsule = await _context.TimeCapsules
                .Include(tc => tc.User)
                .Include(tc => tc.SentMail)
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId && tc.UserId == userId);
                
            if (timeCapsule == null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("时间胶囊不存在");
            }
            
            var capsuleDto = MapToTimeCapsuleResponseDto(timeCapsule);
            
            return ApiResponse<TimeCapsuleResponseDto>.SuccessResult(capsuleDto);
        }
        
        public async Task<ApiResponse<TimeCapsuleResponseDto>> UpdateTimeCapsuleAsync(int userId, int capsuleId, TimeCapsuleUpdateDto updateDto)
        {
            var timeCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId && tc.UserId == userId);
                
            if (timeCapsule == null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("时间胶囊不存在");
            }
            
            // 检查胶囊是否已开启，已开启的胶囊不能修改
            if (timeCapsule.Status >= 3)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("已开启的时间胶囊不能修改");
            }
            
            // 更新胶囊信息
            if (updateDto.PositionX.HasValue)
            {
                timeCapsule.PositionX = updateDto.PositionX.Value;
            }
            
            if (updateDto.PositionY.HasValue)
            {
                timeCapsule.PositionY = updateDto.PositionY.Value;
            }
            
            if (updateDto.PositionZ.HasValue)
            {
                timeCapsule.PositionZ = updateDto.PositionZ.Value;
            }
            
            if (updateDto.Size.HasValue)
            {
                timeCapsule.Size = updateDto.Size.Value;
            }
            
            if (updateDto.Color != null)
            {
                timeCapsule.Color = updateDto.Color;
            }
            
            if (updateDto.Opacity.HasValue)
            {
                timeCapsule.Opacity = updateDto.Opacity.Value;
            }
            
            if (updateDto.Rotation.HasValue)
            {
                timeCapsule.Rotation = updateDto.Rotation.Value;
            }
            
            await _context.SaveChangesAsync();
            
            var capsuleResponse = await GetTimeCapsuleWithDetailsAsync(timeCapsule.Id);
            
            return ApiResponse<TimeCapsuleResponseDto>.SuccessResult(capsuleResponse, "时间胶囊更新成功");
        }
        
        public async Task<ApiResponse<bool>> DeleteTimeCapsuleAsync(int userId, int capsuleId)
        {
            var timeCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId && tc.UserId == userId);
                
            if (timeCapsule == null)
            {
                return ApiResponse<bool>.ErrorResult("时间胶囊不存在");
            }
            
            // 检查胶囊是否已开启，已开启的胶囊不能删除
            if (timeCapsule.Status >= 3)
            {
                return ApiResponse<bool>.ErrorResult("已开启的时间胶囊不能删除");
            }
            
            // 删除时间胶囊
            _context.TimeCapsules.Remove(timeCapsule);
            await _context.SaveChangesAsync();
            
            return ApiResponse<bool>.SuccessResult(true, "时间胶囊删除成功");
        }
        
        public async Task<ApiResponse<PagedResponse<TimeCapsuleResponseDto>>> GetPublicTimeCapsulesAsync(TimeCapsuleListQueryDto queryDto)
        {
            var query = _context.TimeCapsules
                .Where(tc => tc.SentMail.RecipientType == 2) // 公开时间胶囊
                .Include(tc => tc.User)
                .Include(tc => tc.SentMail)
                .AsQueryable();
            
            // 应用筛选条件
            if (queryDto.Status.HasValue)
            {
                query = query.Where(tc => tc.Status == queryDto.Status.Value);
            }
            
            if (queryDto.Type.HasValue)
            {
                query = query.Where(tc => tc.Type == queryDto.Type.Value);
            }
            
            if (queryDto.IncludeExpired.HasValue && !queryDto.IncludeExpired.Value)
            {
                query = query.Where(tc => tc.SentMail.DeliveryTime > DateTime.UtcNow);
            }
            
            // 排序
            query = query.OrderByDescending(tc => tc.CreatedAt);
            
            // 分页
            var totalCount = await query.CountAsync();
            var capsules = await query
                .Skip((queryDto.PageIndex - 1) * queryDto.PageSize)
                .Take(queryDto.PageSize)
                .ToListAsync();
            
            var capsuleDtos = capsules.Select(MapToTimeCapsuleResponseDto).ToList();
            
            var pagedResponse = new PagedResponse<TimeCapsuleResponseDto>(
                capsuleDtos, queryDto.PageIndex, queryDto.PageSize, totalCount);
            
            return ApiResponse<PagedResponse<TimeCapsuleResponseDto>>.SuccessResult(pagedResponse);
        }
        
        public async Task<ApiResponse<TimeCapsuleResponseDto>> ClaimPublicCapsuleAsync(int userId, int capsuleId)
        {
            var timeCapsule = await _context.TimeCapsules
                .Include(tc => tc.SentMail)
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId && tc.SentMail.RecipientType == 2);
                
            if (timeCapsule == null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("时间胶囊不存在或不是公开胶囊");
            }
            
            // 检查胶囊是否已开启
            if (timeCapsule.Status >= 3)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("时间胶囊已开启");
            }
            
            // 检查是否已认领
            var existingReceivedMail = await _context.ReceivedMails
                .FirstOrDefaultAsync(rm => rm.SentMailId == timeCapsule.SentMailId && rm.RecipientId == userId);
                
            if (existingReceivedMail != null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("您已认领此时间胶囊");
            }
            
            // 创建接收邮件记录
            var receivedMail = new ReceivedMail
            {
                SentMailId = timeCapsule.SentMailId,
                RecipientId = userId,
                ReceivedAt = DateTime.UtcNow
            };
            
            _context.ReceivedMails.Add(receivedMail);
            await _context.SaveChangesAsync();
            
            var capsuleResponse = await GetTimeCapsuleWithDetailsAsync(timeCapsule.Id);
            
            return ApiResponse<TimeCapsuleResponseDto>.SuccessResult(capsuleResponse, "时间胶囊认领成功");
        }
        
        public async Task<ApiResponse<TimeCapsuleViewResponseDto>> GetTimeCapsuleViewAsync(int userId)
        {
            // 获取用户的所有时间胶囊
            var capsules = await _context.TimeCapsules
                .Where(tc => tc.UserId == userId)
                .Include(tc => tc.SentMail)
                .ToListAsync();
            
            // 转换为视图DTO
            var capsuleViews = capsules.Select(capsule => 
            {
                var totalDays = (capsule.SentMail.DeliveryTime - capsule.SentMail.SentAt).TotalDays;
                var elapsedDays = (DateTime.UtcNow - capsule.SentMail.SentAt).TotalDays;
                var progress = totalDays > 0 ? Math.Min(1, elapsedDays / totalDays) : 0;
                
                return new TimeCapsuleViewDto
                {
                    CapsuleId = capsule.Id,
                    MailId = capsule.SentMailId,
                    Title = capsule.SentMail.Title,
                    SendTime = capsule.SentMail.SentAt,
                    DeliveryTime = capsule.SentMail.DeliveryTime,
                    Progress = progress,
                    Position = new TimeCapsulePosition
                    {
                        X = capsule.PositionX,
                        Y = capsule.PositionY,
                        Z = capsule.PositionZ
                    },
                    Style = capsule.Color ?? "#FFFFFF",
                    GlowIntensity = capsule.Status == 1 ? 0.8 : 0.3 // 漂浮中的胶囊发光更亮
                };
            }).ToList();
            
            // 获取用户偏好设置（如果有）
            var user = await _context.Users.FindAsync(userId);
            var scene = user?.PreferredScene ?? "SPACE";
            var background = user?.PreferredBackground ?? "default";
            
            var viewResponse = new TimeCapsuleViewResponseDto
            {
                Capsules = capsuleViews,
                Scene = scene,
                Background = background
            };
            
            return ApiResponse<TimeCapsuleViewResponseDto>.SuccessResult(viewResponse);
        }
        
        public async Task<ApiResponse<TimeCapsuleResponseDto>> UpdateTimeCapsuleStyleAsync(int userId, int capsuleId, TimeCapsuleStyleUpdateDto updateDto)
        {
            var timeCapsule = await _context.TimeCapsules
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId && tc.UserId == userId);
                
            if (timeCapsule == null)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("时间胶囊不存在");
            }
            
            // 检查胶囊是否已开启，已开启的胶囊不能修改
            if (timeCapsule.Status >= 3)
            {
                return ApiResponse<TimeCapsuleResponseDto>.ErrorResult("已开启的时间胶囊不能修改");
            }
            
            // 更新胶囊样式
            timeCapsule.Color = updateDto.Style;
            
            if (updateDto.GlowIntensity.HasValue)
            {
                // 将发光强度转换为透明度（反向关系）
                timeCapsule.Opacity = 1.0 - (updateDto.GlowIntensity.Value * 0.5);
            }
            
            await _context.SaveChangesAsync();
            
            var capsuleResponse = await GetTimeCapsuleWithDetailsAsync(timeCapsule.Id);
            
            return ApiResponse<TimeCapsuleResponseDto>.SuccessResult(capsuleResponse, "时间胶囊样式更新成功");
        }
        
        private async Task<TimeCapsuleResponseDto> GetTimeCapsuleWithDetailsAsync(int capsuleId)
        {
            var timeCapsule = await _context.TimeCapsules
                .Include(tc => tc.User)
                .Include(tc => tc.SentMail)
                .FirstOrDefaultAsync(tc => tc.Id == capsuleId);
                
            return MapToTimeCapsuleResponseDto(timeCapsule!);
        }
        
        private static TimeCapsuleResponseDto MapToTimeCapsuleResponseDto(TimeCapsule timeCapsule)
        {
            var daysUntilDelivery = (int)(timeCapsule.SentMail.DeliveryTime - DateTime.UtcNow).TotalDays;
            var distanceFromNow = CalculateDistanceFromNow(daysUntilDelivery);
            
            return new TimeCapsuleResponseDto
            {
                Id = timeCapsule.Id,
                UserId = timeCapsule.UserId,
                SentMailId = timeCapsule.SentMailId,
                MailTitle = timeCapsule.SentMail.Title,
                PositionX = timeCapsule.PositionX,
                PositionY = timeCapsule.PositionY,
                PositionZ = timeCapsule.PositionZ,
                Size = timeCapsule.Size,
                Color = timeCapsule.Color,
                Opacity = timeCapsule.Opacity,
                Rotation = timeCapsule.Rotation,
                Status = timeCapsule.Status,
                StatusText = GetStatusText(timeCapsule.Status),
                Type = timeCapsule.Type,
                TypeText = GetTypeText(timeCapsule.Type),
                CreatedAt = timeCapsule.CreatedAt,
                DeliveryTime = timeCapsule.SentMail.DeliveryTime,
                DaysUntilDelivery = daysUntilDelivery,
                DistanceFromNow = distanceFromNow
            };
        }
        
        private static string GetStatusText(int status)
        {
            return status switch
            {
                0 => "未激活",
                1 => "漂浮中",
                2 => "即将到达",
                3 => "已开启",
                _ => "未知"
            };
        }
        
        private static string GetTypeText(int type)
        {
            return type switch
            {
                0 => "普通",
                1 => "特殊",
                2 => "限时",
                _ => "未知"
            };
        }
        
        private static double CalculateDistanceFromNow(int daysUntilDelivery)
        {
            // 简单的距离计算，可以根据需要调整
            // 距离"现在"越远，距离值越大
            return Math.Max(1, daysUntilDelivery / 30.0); // 以月为单位
        }
    }
}