using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using FutureMailAPI.DTOs;
using System.Security.Cryptography;
using System.Text;

namespace FutureMailAPI.Services
{
    public class FileUploadService : IFileUploadService
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<FileUploadService> _logger;
        private readonly string _uploadPath;
        private readonly string _baseUrl;
        private readonly long _maxFileSize;
        private readonly List<string> _allowedImageTypes;
        private readonly List<string> _allowedVideoTypes;
        private readonly List<string> _allowedDocumentTypes;
        private readonly List<string> _allowedAudioTypes;
        
        public FileUploadService(IConfiguration configuration, ILogger<FileUploadService> logger)
        {
            _configuration = configuration;
            _logger = logger;
            
            // 从配置中获取上传路径和基础URL
            _uploadPath = configuration["FileUpload:UploadPath"] ?? "uploads";
            _baseUrl = configuration["FileUpload:BaseUrl"] ?? "http://localhost:5054/uploads";
            _maxFileSize = long.Parse(configuration["FileUpload:MaxFileSize"] ?? "104857600"); // 默认100MB
            
            // 允许的文件类型
            _allowedImageTypes = new List<string> { "image/jpeg", "image/png", "image/gif", "image/webp" };
            _allowedVideoTypes = new List<string> { "video/mp4", "video/avi", "video/mov", "video/wmv" };
            _allowedDocumentTypes = new List<string> { "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" };
            _allowedAudioTypes = new List<string> { "audio/mpeg", "audio/wav", "audio/ogg" };
            
            // 确保上传目录存在
            EnsureUploadDirectoryExists();
        }
        
        public async Task<ApiResponse<FileUploadResponseDto>> UploadFileAsync(IFormFile file, int userId, FileUploadRequestDto request)
        {
            try
            {
                if (file == null || file.Length == 0)
                {
                    return ApiResponse<FileUploadResponseDto>.ErrorResult("请选择要上传的文件");
                }
                
                // 检查文件大小
                if (file.Length > _maxFileSize)
                {
                    return ApiResponse<FileUploadResponseDto>.ErrorResult($"文件大小不能超过 {_maxFileSize / (1024 * 1024)}MB");
                }
                
                // 检查文件类型
                var contentType = file.ContentType.ToLower();
                if (!IsAllowedFileType(contentType, request.Type))
                {
                    return ApiResponse<FileUploadResponseDto>.ErrorResult("不支持的文件类型");
                }
                
                // 生成唯一文件名
                var fileId = GenerateFileId();
                var fileExtension = Path.GetExtension(file.FileName);
                var fileName = $"{fileId}{fileExtension}";
                
                // 创建用户目录
                var userDirectory = Path.Combine(_uploadPath, userId.ToString());
                var categoryDirectory = string.IsNullOrEmpty(request.Category) 
                    ? userDirectory 
                    : Path.Combine(userDirectory, request.Category);
                
                Directory.CreateDirectory(categoryDirectory);
                
                // 保存文件
                var filePath = Path.Combine(categoryDirectory, fileName);
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }
                
                // 生成缩略图（如果是图片）
                string thumbnailUrl = string.Empty;
                if (request.Type == AttachmentType.IMAGE)
                {
                    thumbnailUrl = await GenerateThumbnailAsync(filePath, fileName, categoryDirectory);
                }
                
                // 构建文件URL
                var relativePath = Path.GetRelativePath(_uploadPath, filePath).Replace("\\", "/");
                var fileUrl = $"{_baseUrl}/{relativePath}";
                
                // 构建缩略图URL
                if (!string.IsNullOrEmpty(thumbnailUrl))
                {
                    var relativeThumbnailPath = Path.GetRelativePath(_uploadPath, thumbnailUrl).Replace("\\", "/");
                    thumbnailUrl = $"{_baseUrl}/{relativeThumbnailPath}";
                }
                
                var response = new FileUploadResponseDto
                {
                    FileId = fileId,
                    FileName = file.FileName,
                    FileUrl = fileUrl,
                    ThumbnailUrl = thumbnailUrl,
                    FileSize = file.Length,
                    ContentType = file.ContentType,
                    Type = request.Type,
                    UploadedAt = DateTime.UtcNow
                };
                
                return ApiResponse<FileUploadResponseDto>.SuccessResult(response);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "上传文件时发生错误");
                return ApiResponse<FileUploadResponseDto>.ErrorResult("上传文件失败");
            }
        }
        
        public async Task<ApiResponse<bool>> DeleteFileAsync(string fileId, int userId)
        {
            try
            {
                // 在实际应用中，这里应该从数据库中查找文件信息
                // 目前我们只是简单地根据文件ID删除文件
                
                // 查找用户目录下的所有文件
                var userDirectory = Path.Combine(_uploadPath, userId.ToString());
                if (!Directory.Exists(userDirectory))
                {
                    return ApiResponse<bool>.ErrorResult("文件不存在");
                }
                
                // 查找匹配的文件
                var files = Directory.GetFiles(userDirectory, $"{fileId}*", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    return ApiResponse<bool>.ErrorResult("文件不存在");
                }
                
                // 删除所有相关文件（包括缩略图）
                foreach (var file in files)
                {
                    try
                    {
                        System.IO.File.Delete(file);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning(ex, $"删除文件 {file} 失败");
                    }
                }
                
                return ApiResponse<bool>.SuccessResult(true);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除文件时发生错误");
                return ApiResponse<bool>.ErrorResult("删除文件失败");
            }
        }
        
        public async Task<ApiResponse<FileUploadResponseDto>> GetFileAsync(string fileId, int userId)
        {
            try
            {
                // 在实际应用中，这里应该从数据库中查找文件信息
                // 目前我们只是简单地根据文件ID返回文件信息
                
                // 查找用户目录下的所有文件
                var userDirectory = Path.Combine(_uploadPath, userId.ToString());
                if (!Directory.Exists(userDirectory))
                {
                    return ApiResponse<FileUploadResponseDto>.ErrorResult("文件不存在");
                }
                
                // 查找匹配的文件
                var files = Directory.GetFiles(userDirectory, $"{fileId}*", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    return ApiResponse<FileUploadResponseDto>.ErrorResult("文件不存在");
                }
                
                // 获取主文件（排除缩略图）
                var mainFile = files.FirstOrDefault(f => !f.Contains("_thumb."));
                if (mainFile == null)
                {
                    mainFile = files[0]; // 如果没有找到主文件，使用第一个文件
                }
                
                var fileInfo = new FileInfo(mainFile);
                var relativePath = Path.GetRelativePath(_uploadPath, mainFile).Replace("\\", "/");
                var fileUrl = $"{_baseUrl}/{relativePath}";
                
                // 查找缩略图
                var thumbnailFile = files.FirstOrDefault(f => f.Contains("_thumb."));
                string thumbnailUrl = string.Empty;
                if (thumbnailFile != null)
                {
                    var relativeThumbnailPath = Path.GetRelativePath(_uploadPath, thumbnailFile).Replace("\\", "/");
                    thumbnailUrl = $"{_baseUrl}/{relativeThumbnailPath}";
                }
                
                // 确定文件类型
                var contentType = GetContentType(fileInfo.Extension);
                var attachmentType = GetAttachmentType(contentType);
                
                var response = new FileUploadResponseDto
                {
                    FileId = fileId,
                    FileName = fileInfo.Name,
                    FileUrl = fileUrl,
                    ThumbnailUrl = thumbnailUrl,
                    FileSize = fileInfo.Length,
                    ContentType = contentType,
                    Type = attachmentType,
                    UploadedAt = fileInfo.CreationTimeUtc
                };
                
                return ApiResponse<FileUploadResponseDto>.SuccessResult(response);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取文件信息时发生错误");
                return ApiResponse<FileUploadResponseDto>.ErrorResult("获取文件信息失败");
            }
        }
        
        private void EnsureUploadDirectoryExists()
        {
            if (!Directory.Exists(_uploadPath))
            {
                Directory.CreateDirectory(_uploadPath);
            }
        }
        
        private bool IsAllowedFileType(string contentType, AttachmentType type)
        {
            return type switch
            {
                AttachmentType.IMAGE => _allowedImageTypes.Contains(contentType),
                AttachmentType.VIDEO => _allowedVideoTypes.Contains(contentType),
                AttachmentType.DOCUMENT => _allowedDocumentTypes.Contains(contentType),
                AttachmentType.VOICE => _allowedAudioTypes.Contains(contentType),
                _ => true // 其他类型暂时允许
            };
        }
        
        private string GenerateFileId()
        {
            return Guid.NewGuid().ToString("N");
        }
        
        private async Task<string> GenerateThumbnailAsync(string filePath, string fileName, string directory)
        {
            try
            {
                // 在实际应用中，这里应该使用图像处理库（如ImageSharp）生成缩略图
                // 目前我们只是创建一个简单的缩略图文件名
                
                var fileExtension = Path.GetExtension(fileName);
                var thumbnailFileName = $"{Path.GetFileNameWithoutExtension(fileName)}_thumb{fileExtension}";
                var thumbnailPath = Path.Combine(directory, thumbnailFileName);
                
                // 这里应该添加实际的缩略图生成代码
                // 暂时只是复制原文件作为缩略图
                System.IO.File.Copy(filePath, thumbnailPath);
                
                return thumbnailPath;
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "生成缩略图失败");
                return string.Empty;
            }
        }
        
        private string GetContentType(string extension)
        {
            return extension.ToLower() switch
            {
                ".jpg" or ".jpeg" => "image/jpeg",
                ".png" => "image/png",
                ".gif" => "image/gif",
                ".webp" => "image/webp",
                ".mp4" => "video/mp4",
                ".avi" => "video/avi",
                ".mov" => "video/mov",
                ".wmv" => "video/wmv",
                ".mp3" => "audio/mpeg",
                ".wav" => "audio/wav",
                ".ogg" => "audio/ogg",
                ".pdf" => "application/pdf",
                ".doc" => "application/msword",
                ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                _ => "application/octet-stream"
            };
        }
        
        private AttachmentType GetAttachmentType(string contentType)
        {
            if (_allowedImageTypes.Contains(contentType))
                return AttachmentType.IMAGE;
            
            if (_allowedVideoTypes.Contains(contentType))
                return AttachmentType.VIDEO;
            
            if (_allowedAudioTypes.Contains(contentType))
                return AttachmentType.VOICE;
            
            if (_allowedDocumentTypes.Contains(contentType))
                return AttachmentType.DOCUMENT;
            
            return AttachmentType.OTHER;
        }
    }
}