using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using BLL.Interfaces;
using MDL.Models;

namespace BLL.Services
{
    /// <summary>
    /// FTP上传服务
    /// </summary>
    public class FtpUploadService : IFtpUploadService
    {
        private readonly ILogger<FtpUploadService> _logger;
        
        // FTP服务器配置
        private const string FtpHost = "172.232.21.79";
        private const int FtpPort = 2121;
        private const string FtpUsername = "TE-WIN-TEST\\jennison";
        private const string FtpPassword = "xuancheng-2025";
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志记录器</param>
        public FtpUploadService(ILogger<FtpUploadService> logger)
        {
            _logger = logger;
        }
        
        /// <summary>
        /// 上传文件到FTP服务器
        /// </summary>
        /// <param name="fileStream">文件流</param>
        /// <param name="fileName">文件名</param>
        /// <param name="directory">上传目录</param>
        /// <returns>上传结果</returns>
        public async Task<FtpUploadResult> UploadFileAsync(Stream fileStream, string fileName, string directory)
        {
            var result = new FtpUploadResult
            {
                Filename = fileName,
                Status = "ok",
                Message = "Upload successful"
            };
            
            try
            {
                // 构建FTP路径
                string ftpPath = $"ftp://{FtpHost}:{FtpPort}/{directory}/{fileName}";
                
                _logger.LogInformation("Uploading file to FTP: {ftpPath}", ftpPath);
                
                // 创建FTP请求
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath);
                request.Method = WebRequestMethods.Ftp.UploadFile;
                request.Credentials = new NetworkCredential(FtpUsername, FtpPassword);
                request.UseBinary = true;
                request.UsePassive = true;
                request.KeepAlive = false;
                // 确保覆盖同名文件
                request.EnableSsl = false;
                
                // 确保目录存在
                await EnsureDirectoryExistsAsync(directory);
                
                // 上传文件
                using (Stream requestStream = await request.GetRequestStreamAsync())
                {
                    await fileStream.CopyToAsync(requestStream);
                }
                
                // 获取响应
                using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
                {
                    _logger.LogInformation("FTP upload response: {status}", response.StatusDescription);
                }
                
                result.FilePath = $"/api-lable/pdf/{directory}/{fileName}";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error uploading file to FTP: {fileName}", fileName);
                result.Status = "error";
                result.Message = ex.Message;
            }
            
            return result;
        }
        
        /// <summary>
        /// 确保FTP目录存在
        /// </summary>
        /// <param name="directory">目录路径</param>
        /// <returns></returns>
        private async Task EnsureDirectoryExistsAsync(string directory)
        {
            try
            {
                // 构建基础路径
                string basePath = $"ftp://{FtpHost}:{FtpPort}/api-lable/pdf";
                string fullPath = $"{basePath}/{directory}";
                
                // 检查基础目录是否存在
                await CreateDirectoryIfNotExistsAsync(basePath);
                
                // 检查目标目录是否存在
                await CreateDirectoryIfNotExistsAsync(fullPath);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error ensuring directory exists: {directory}", directory);
                throw;
            }
        }
        
        /// <summary>
        /// 如果目录不存在则创建
        /// </summary>
        /// <param name="directoryPath">目录路径</param>
        /// <returns></returns>
        private async Task CreateDirectoryIfNotExistsAsync(string directoryPath)
        {
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(directoryPath);
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.Credentials = new NetworkCredential(FtpUsername, FtpPassword);
                
                using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
                {
                    // 目录存在
                    _logger.LogInformation("Directory exists: {directoryPath}", directoryPath);
                }
            }
            catch (WebException ex)
            {
                if (ex.Response is FtpWebResponse response && response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                    // 目录不存在，创建目录
                    _logger.LogInformation("Creating directory: {directoryPath}", directoryPath);
                    
                    FtpWebRequest createRequest = (FtpWebRequest)WebRequest.Create(directoryPath);
                    createRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
                    createRequest.Credentials = new NetworkCredential(FtpUsername, FtpPassword);
                    
                    using (FtpWebResponse createResponse = (FtpWebResponse)await createRequest.GetResponseAsync())
                    {
                        _logger.LogInformation("Directory created: {directoryPath}", directoryPath);
                    }
                }
                else
                {
                    throw;
                }
            }
        }
        
        /// <summary>
        /// 批量上传文件
        /// </summary>
        /// <param name="fileStreams">文件流列表</param>
        /// <param name="fileNames">文件名列表</param>
        /// <param name="directory">上传目录</param>
        /// <returns>上传结果列表</returns>
        public async Task<List<FtpUploadResult>> UploadFilesAsync(List<Stream> fileStreams, List<string> fileNames, string directory)
        {
            var results = new List<FtpUploadResult>();
            
            for (int i = 0; i < fileStreams.Count; i++)
            {
                var result = await UploadFileAsync(fileStreams[i], fileNames[i], directory);
                results.Add(result);
            }
            
            return results;
        }
        
        /// <summary>
        /// 检查文件是否存在于FTP服务器
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="directory">目录</param>
        /// <returns>检查结果</returns>
        public async Task<bool> CheckFileExistsAsync(string fileName, string directory)
        {
            try
            {
                // 构建FTP路径
                string ftpPath = $"ftp://{FtpHost}:{FtpPort}/api-lable/pdf/{directory}/{fileName}";
                
                _logger.LogInformation("Checking if file exists on FTP: {ftpPath}", ftpPath);
                
                // 创建FTP请求
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath);
                request.Method = WebRequestMethods.Ftp.GetFileSize;
                request.Credentials = new NetworkCredential(FtpUsername, FtpPassword);
                request.UseBinary = true;
                request.UsePassive = true;
                
                using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
                {
                    // 文件存在
                    _logger.LogInformation("File exists on FTP: {ftpPath}", ftpPath);
                    return true;
                }
            }
            catch (WebException ex)
            {
                if (ex.Response is FtpWebResponse response && response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                    // 文件不存在
                    _logger.LogInformation("File does not exist on FTP: {fileName}", fileName);
                    return false;
                }
                else
                {
                    // 其他错误
                    _logger.LogError(ex, "Error checking file existence: {fileName}", fileName);
                    throw;
                }
            }
        }
        
        /// <summary>
        /// 批量检查文件是否存在于FTP服务器
        /// </summary>
        /// <param name="fileNames">文件名列表</param>
        /// <param name="directory">目录</param>
        /// <returns>检查结果列表</returns>
        public async Task<List<FtpCheckResult>> CheckFilesExistsAsync(List<string> fileNames, string directory)
        {
            var results = new List<FtpCheckResult>();
            
            foreach (var fileName in fileNames)
            {
                var result = new FtpCheckResult
                {
                    Filename = fileName,
                    FilePath = $"/api-lable/pdf/{directory}/{fileName}"
                };
                
                try
                {
                    result.Exists = await CheckFileExistsAsync(fileName, directory);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error checking file existence: {fileName}", fileName);
                    result.Exists = false;
                }
                
                results.Add(result);
            }
            
            return results;
        }
    }
}
