using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Data;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using HandyControl.Tools.Extension;
using log4net;
using SparkClient.Model.Common;
using SparkClient.Model.Entity.ApiEntity;
using SparkClient.Model.Helper;

namespace SparkClient.Model.Services
{
    /// <summary>
    /// SOC 客户端服务类,用于与远程服务器进行交互,包括启动图片收集任务、获取图片、获取采集状态等操作。
    /// </summary>
    public class SOCClientService
    {
        // Log地址
        private const string LogFilePath = @"..\..\..\Resource\Document\log.txt";
        
        private static readonly ILog Logger = LogManager.GetLogger(typeof(SOCClientService));
        
        /// <summary>
        /// 基础URL,用于构建完整的API请求地址。
        /// </summary>
        private readonly string? _baseUrl;

        /// <summary>
        /// 认证令牌,用于HTTP请求的认证。
        /// </summary>
        private readonly string _authToken;

        /// <summary>
        /// 构造函数,初始化基础URL和认证令牌。
        /// </summary>
        public SOCClientService()
        {
            //_baseUrl = "http://192.168.3.100:8080";
            _baseUrl = ConfigurationManager.AppSettings["BaseUrl"];
            _authToken = "your_basic_auth_token";
        }

        /// <summary>
        /// 发送GET请求的通用方法。
        /// </summary>
        /// <param name="url">请求的完整URL</param>
        /// <returns>HTTP响应</returns>
        private async Task<HttpResponseMessage> SendGetRequestAsync(string url)
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Basic " + _authToken);
                return await client.GetAsync(url);
            }
        }

        /// <summary>
        /// 启动图片收集任务。
        /// </summary>
        /// <returns>任务状态</returns>
        public async Task<SocResultEntity> CollectImagesAsync()
        {
            try
            {
                // 光照度和半圆
                int lightLevel = 0;
                string halfCircle = string.Empty;
                // 查询光照度和半圆配置
                string sql = $"SELECT KEY, VALUE FROM CUTTER_CONFIG WHERE KEY IN ('light_level', 'half_circle')";
                DataTable table = DataBaseHelper.ExecuteQuery(sql);

                if (table == null || table.Rows.Count == 0)
                {
                    throw new Exception("No data found for the specified keys.");
                }
                foreach (DataRow row in table.Rows)
                {
                    string key = row["Key"].ToString() ?? string.Empty;
                    string value = row["Value"].ToString() ?? string.Empty;

                    if (key == "light_level" && int.TryParse(value, out int parsedLightLevel))
                    {
                        lightLevel = parsedLightLevel; // 光照度
                    }
                    else if (key == "half_circle")
                    {
                        halfCircle = value; // 半圆
                    }
                }
                
                string url = $"{_baseUrl}/collect_images?light_level={lightLevel}&half_circle={halfCircle}";
           
                var response = await SendGetRequestAsync(url);

                if (!response.IsSuccessStatusCode)
                {
                    return  new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List<string>()};   
                }

                var jsonResponse = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject<ResponseStatus>(jsonResponse);

                if (result == null)
                {
                    return  new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List<string>()};   
                }
                return new SocResultEntity { Status = result.Status, Images = new List<string>() , DeviceId = result.device_id};
               
            }
            catch (Exception ex)
            {
                // 记录日志或进行其他处理
                Console.WriteLine($"Error in DoSoc: {ex.Message}");
                Logger.Warn($"Error in DoSoc: {ex.Message}");
                // 或者使用日志框架记录日志
                // logger.LogError(ex, "Error in DoSoc method.");
                return  new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List<string>() , DeviceId = ""};   
            }
        }

        /// <summary>
        /// 获取指定索引的图片。
        /// </summary>
        /// <param name="savePath">保存图片路径</param>
        /// <returns>图片的字节数组</returns>
        public async Task<List<string>> RetrieveImageAsync(string? savePath)
        {
            List<string> imageNames = new List<string>();
            // 读取图片接口
            int imageIndex = 0;
            while (true)
            {
                string url = $"{_baseUrl}/retrieve_image/{imageIndex}";
                try
                {
                    var response = await SendGetRequestAsync(url);
                    int status = (int)response.StatusCode;

                    switch (status)
                    {
                        case 200:
                            byte[] imageBytes = await response.Content.ReadAsByteArrayAsync();

                            // 获取 Content-Type 头以确定图片格式
                            string contentType = response.Content.Headers.ContentType.MediaType;
                            string fileExtension = GetFileExtension(contentType);

                            string fileName = Path.Combine(savePath, $"image_{imageIndex}{fileExtension}");
                            // 图片名称List
                            imageNames.Add(Path.GetFileName(fileName));
                            // 保存图片
                            await File.WriteAllBytesAsync(fileName, imageBytes);
                            imageIndex++;
                            break;
                        case 425:
                            // 请求被锁定,等待一段时间后重试
                            await Task.Delay(1000);
                            break;
                        case 410:
                            // 资源已被永久删除,跳过当前索引
                            imageIndex++;
                            break;

                        case 404:
                            // 资源未找到,结束循环
                            return imageNames;
                        default:
                            // 其他状态码,记录警告并继续
                            Logger.Warn($"Unexpected status code: {status} for URL: {url}");
                            imageIndex++;
                            break;
                    }
                }
                catch (HttpRequestException ex)
                {
                    // 捕获HTTP请求异常并记录错误信息
                    Logger.Error($"HTTP request failed for URL: {url}, Exception: {ex.Message}");
                    imageNames.Clear();
                    return imageNames;
                }
                catch (Exception ex)
                {
                    // 捕获其他异常并记录错误信息,结束循环
                    Logger.Error($"An unexpected error occurred for URL: {url}, Exception: {ex.Message}");
                    imageNames.Clear();
                    return imageNames;
                }
            }
        }

        /// <summary>
        /// 获取图片采集状态。
        /// </summary>
        /// <returns>采集状态</returns>
        public async Task<string> CollectStatusAsync()
        {
            string url = $"{_baseUrl}/collect_status";

            try
            {
                var response = await SendGetRequestAsync(url);

                if (response.IsSuccessStatusCode)
                {
                    var jsonResponse = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<ResponseStatus>(jsonResponse);
                    return result.Status;
                }

                return StatusCodes.DeviceNotFound;
            }
            catch (HttpRequestException ex)
            {
                return StatusCodes.DeviceNotFound;
            }
            catch (JsonException ex)
            {
                return StatusCodes.DeviceNotFound;
            }
            catch (Exception ex)
            {
                return StatusCodes.DeviceNotFound;
            }
        }

        /// <summary>
        /// 处理图片收集、保存和状态检查。
        /// </summary>
        /// <returns>操作结果</returns>
        public async Task<SocResultEntity> ProcessImageCollectionAsync()
        {
            try
            {
                // SOC接口
                string? savePath = ConfigurationManager.AppSettings["ImageFileBasePath"];
                // 清理 savePath 文件夹
                if (Directory.Exists(savePath))
                {
                    Directory.Delete(savePath, true);
                }
                Directory.CreateDirectory(savePath);
                // 启动任务接口
                SocResultEntity entity = await CollectImagesAsync();
                // 成功
                if (entity.Status != StatusCodes.Success)
                {
                    // 启动任务失败
                    return new SocResultEntity { Status = entity.Status, Images = new List<string>() };
                }

                // 读取图片接口
                List<string> imageNames = await RetrieveImageAsync(savePath);
                if (imageNames.Count != 0)
                {
                    // 采集状态接口
                    string acquisitionStatus = await CollectStatusAsync();
                    // 成功
                    if (acquisitionStatus != StatusCodes.Success)
                    {
                        // 采集状态失败
                        return new SocResultEntity { Status = acquisitionStatus, Images = new List<string>() };                        
                    }
                }
                return new SocResultEntity { Status = StatusCodes.Success, Images = imageNames, DeviceId = entity.DeviceId};                
            }
            catch (Exception e)
            {
                // 日志记录
                // logger.Error(e, "发生异常");
                string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] 发生异常: {e.Message}{Environment.NewLine}";
                Logger.Error(logMessage);
                return new SocResultEntity { Status = StatusCodes.DeviceNotFound, Images = new List<string>() };                
            }
        }
        
        /// <summary>
        /// 根据给定的 MIME 类型获取对应的文件扩展名。
        /// </summary>
        /// <param name="contentType">HTTP 响应中的 Content-Type 头字段,表示内容的 MIME 类型。</param>
        /// <returns>与 MIME 类型对应的文件扩展名。</returns>
        /// <exception cref="InvalidOperationException">当传入的 MIME 类型不受支持时抛出此异常。</exception>
        private string GetFileExtension(string contentType)
        {
            switch (contentType.ToLower())
            {
                case "image/bmp":
                    return ".bmp";
                case "image/jpg":
                    return ".jpg";
                case "image/png":
                    return ".png";
                default:
                    throw new InvalidOperationException($"Unsupported content type: {contentType}");
            }
        }

    }
    

    /// <summary>
    /// 响应状态类,用于解析服务器返回的状态信息。
    /// </summary>
    public class ResponseStatus
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public string Status { get; set; }

        /// <summary>
        /// 状态消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 机器号
        /// </summary>
        public string device_id { get; set; }
    }
}