
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PTMedicalInsurance.Business;
using PTMedicalInsurance.Variables;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PTMedicalInsurance.Helper
{
     class DictionaryHelper
    {
        private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictCache
        = new ConcurrentDictionary<string, Dictionary<string, string>>();

        public int SaveDicToJson(string dicType, out string error)
        {
            InsuServices iris = new InsuServices();
            JObject joRtn = iris.getSpecDictionary(Global.inf.interfaceDr.ToString(), dicType,false);
            DictionaryHelper dicHelper = new DictionaryHelper();
            return dicHelper.SaveDictionaryToFile(joRtn.ToString(), dicType,out error);
        }

        private int SaveDictionaryToFile(string jsonResponse, string dicType,out string error)
        {
            error = "";
            try
            {
                // 解析原始响应（只取 data 部分）
                var response = JsonConvert.DeserializeObject<DictResponse>(jsonResponse);
                var dictData = response?.Result?.Data;

                if (dictData == null || dictData.Count <= 1)
                {
                    error = "无效的字典数据";
                    return -1;
                }


                // 构建文件路径
                string directoryPath = Path.Combine(Global.curEvt.path, "Dictionary");
                string filePath = Path.Combine(directoryPath, $"{dicType}.json");

                // ✅ 关键：确保目录存在（不存在则创建）
                Directory.CreateDirectory(directoryPath);

                // 写入文件（只保存 code -> name 映射，更轻量）
                var simpleDict = dictData.ToDictionary(
                    item => item.Code,
                    item => item.Name,
                    StringComparer.OrdinalIgnoreCase
                );

                string jsonContent = JsonConvert.SerializeObject(simpleDict, Formatting.Indented);
                File.WriteAllText(filePath, jsonContent, Encoding.UTF8);

                error = $"字典已保存至: {filePath}";
                return 0;
            }
            catch (Exception ex)
            {
                error = $"保存字典失败: {ex.Message}";
                return -1;
            }
        }


        /// <summary>
        /// 获取指定字典中代码对应的中文名称
        /// </summary>
        /// <param name="dicType">字典类型，如 "clr_type", "insu_type"</param>
        /// <param name="code">代码值，如 "11"</param>
        /// <param name="returnOriginalIfNotFound">未找到时是否返回原 code</param>
        /// <returns>中文名称或原值/空</returns>
        public string GetChineseName(string dicType, string code, bool returnOriginalIfNotFound = true)
        {
            if (string.IsNullOrEmpty(dicType) || string.IsNullOrEmpty(code))
                return returnOriginalIfNotFound ? code ?? "" : "";

            // 自动构建字典文件路径
            string dictFilePath = GetDictFilePath(dicType);

            var dict = _dictCache.GetOrAdd(dicType, key =>
            {
                //if (!File.Exists(dictFilePath))
                //    throw new FileNotFoundException($"字典文件未找到: {dictFilePath}");

                if (!File.Exists(dictFilePath))
                {
                    //此次报警只会一次，因为GetOrAdd方法只有当key不存在时才会执行，返回一个空数据集后，key已存在，lambda内不再执行
                    MessageBox.Show($"字典文件未找到: {dictFilePath}");
                    return new Dictionary<string, string>(); // 返回空字典，避免后续异常
                }

                var json = File.ReadAllText(dictFilePath, Encoding.UTF8);
                var parsed = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
                return parsed ?? new Dictionary<string, string>();
            });

            return dict.TryGetValue(code, out var name) && !string.IsNullOrEmpty(name)
                ? name
                : returnOriginalIfNotFound ? code : "";
        }

        /// <summary>
        /// 根据字典名称生成完整文件路径
        /// </summary>
        public  string GetDictFilePath(string dictName)
        {
            // 假设所有字典都存放在 Global.curEvt.path/Dictionary/ 下
            string baseDir = Global.curEvt.path;
            string dictDir = Path.Combine(baseDir, "Dictionary");
            return Path.Combine(dictDir, $"{dictName}.json");
        }

        /// <summary>
        /// 读取JSON文件并转换为DataTable
        /// </summary>
        /// <param name="filePath">JSON文件路径</param>
        /// <returns>DataTable</returns>
        public  DataTable JsonFileToDataTable(string dictName)
        {
            string filePath = GetDictFilePath(dictName);
            if (!File.Exists(filePath))
                throw new FileNotFoundException($"文件未找到: {filePath}");

            string json = File.ReadAllText(filePath, Encoding.Default);
            return JsonToDataTable(json);
        }

        /// <summary>
        /// 将JSON字符串转换为DataTable
        /// </summary>
        /// <param name="json">JSON字符串（键值对格式，如 {"01": "挂号", "02": "住院"}）</param>
        /// <returns>DataTable，包含 code 和 name 两列</returns>
        public static DataTable JsonToDataTable(string json, string arrayPath = null)
        {
            json = json.Trim();
            DataTable dt = new DataTable();
            dt.Columns.Add("code", typeof(string));
            dt.Columns.Add("name", typeof(string));

            if (!json.StartsWith("{"))
                throw new InvalidOperationException("JSON格式不正确，需要键值对格式");

            JObject jo = JObject.Parse(json);
            foreach (var prop in jo.Properties())
            {
                DataRow dr = dt.NewRow();
                dr["code"] = prop.Name;
                dr["name"] = prop.Value?.ToString() ?? "";
                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>
        /// 批量转换整个 DataTable
        /// </summary>
        public void TranslateDataTable(DataTable table, List<ColumnDictMapping> mappings)
        {
            if (table == null || mappings == null || !mappings.Any())
                return;

            // 验证列是否存在
            foreach (var mapping in mappings)
            {
                if (!table.Columns.Contains(mapping.ColumnName))
                    throw new ArgumentException($"DataTable 中不存在列: {mapping.ColumnName}");
            }

            // 遍历每一行
            foreach (DataRow row in table.Rows)
            {
                foreach (var mapping in mappings)
                {
                    var currentValue = row[mapping.ColumnName]?.ToString();
                    if (string.IsNullOrEmpty(currentValue)) continue;

                    var chinese = GetChineseName(mapping.DicType, currentValue);
                    row[mapping.ColumnName] = chinese;
                }
            }
        }

        /// <summary>
        /// 设置ComboBox的数据源为指定字典的DataTable
        /// </summary>
        /// <param name="comboBox">ComboBox控件（支持System.Windows.Forms.ComboBox和Sunny.UI.UIComboBox）</param>
        /// <param name="dicName">字典名称（不含.json后缀）</param>
        /// <param name="insertEmptyOption">是否插入空选项</param>
        public void SetComboxDatasource(object comboBox, string dicName, bool insertEmptyOption = false)
        {
            if (comboBox == null)
                throw new ArgumentNullException(nameof(comboBox));
            if (string.IsNullOrEmpty(dicName))
                throw new ArgumentNullException(nameof(dicName));

            DataTable dt = JsonFileToDataTable(dicName);

            if (insertEmptyOption)
            {
                DataRow dr = dt.NewRow();
                dr["code"] = "";
                dr["name"] = "请选择";
                dt.Rows.InsertAt(dr, 0);
            }

            // 使用dynamic避免类型转换问题
            dynamic cb = comboBox;
            cb.DataSource = dt;
            cb.DisplayMember = "name";
            cb.ValueMember = "code";
        }
    }

    public class ColumnDictMapping
    {
        /// <summary>
        /// DataTable 中的列名
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 对应的字典类型
        /// </summary>
        public string DicType { get; set; }
    }

    public class DictItem
    {
        [JsonProperty("code")]
        public string Code { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("searchcode")]
        public string SearchCode { get; set; }
    }

    public class DictResponse
    {
        [JsonProperty("result")]
        public Result Result { get; set; }
    }

    public class Result
    {
        [JsonProperty("data")]
        public List<DictItem> Data { get; set; }
    }
}
