using Hotline.Caching.Interfaces;
using Hotline.Configurations;
using Hotline.Settings;
using Hotline.Share.Tools;
using Hotline.ThirdAccountDomainServices.Interfaces;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using System.Reflection.Metadata.Ecma335;
using Hotline.Snapshot;
using XF.Domain.Cache;
using XF.Domain.Dependency;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Caching.Services
{
    public class SystemSettingCacheManager : ISystemSettingCacheManager, IScopeDependency
    {

        private readonly ILogger<SystemSettingCacheManager> _logger;
        private readonly ITypedCache<SystemSetting> _cacheSystemSetting;
        private readonly IRepository<SystemSetting> _systemSettingRepository;
        private readonly IOptionsSnapshot<SenparcWeixinSetting> _senparcWeixin;

        public SystemSettingCacheManager(ITypedCache<SystemSetting> cacheSystemSetting, IRepository<SystemSetting> systemSettingRepository, ILogger<SystemSettingCacheManager> logger, IOptionsSnapshot<SenparcWeixinSetting> senparcWeixin)
        {
            _cacheSystemSetting = cacheSystemSetting;
            _systemSettingRepository = systemSettingRepository;
            _logger = logger;
            _senparcWeixin = senparcWeixin;
        }

        public SystemSetting? GetSetting(string code)
        {
            var setting = _cacheSystemSetting.GetOrSet(code, x =>
            {
                var dbsetting = _systemSettingRepository.GetAsync(d => d.Code == code).GetAwaiter().GetResult();
                if (dbsetting == null)
                    throw new UserFriendlyException($"{code} 无效系统设置");
                return dbsetting;
            });
            return setting;
        }

        public void DelSystemSetting(string code)
        {
            _cacheSystemSetting.Remove(code);
        }

        public T GetOrDefault<T>(string? id, string code, string name, T defaultValue, string remark)
        {
            var value = defaultValue.ToString();
            try
            {
                try
                {
                    value = GetSetting(code)?.SettingValue[0];
                    if (value == null) return defaultValue;
                }
                catch (UserFriendlyException e)
                {
                    if (e.Message.Contains("无效系统设置"))
                    {
                        var entity = new SystemSetting
                        {
                            Code = code,
                            SettingName = name,
                            SettingValue = [defaultValue.ToString()],
                            Remark = remark,
                            CreatorName = "自动创建",
                        };
                        if (id.NotNullOrEmpty())
                            entity.Id = id;
                        _systemSettingRepository.AddAsync(entity).GetAwaiter().GetResult();
                    }
                }

                try
                {
                    var targetType = typeof(T);
                    if (targetType.IsEnum)
                    {
                        if (value is string strValue)
                            return (T)Enum.Parse(targetType, strValue, ignoreCase: true);
                        else
                            return (T)Enum.ToObject(targetType, value);
                    }
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                catch (InvalidCastException e)
                {
                    _logger.LogError($"无法将 '{value}' 转换为类型 {typeof(T).Name}！已返回默认值 {defaultValue}. {e.Message}");
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message + e.StackTrace);
            }
            return defaultValue;
        }

        public int EffectiveTimes
            => int.Parse(GetSetting(SettingConstants.EffectiveTimes)?.SettingValue[0]);

        public int ConnectByeTimes
            => int.Parse(GetSetting(SettingConstants.ConnectByeTimes)?.SettingValue[0]);

        public int NoConnectByeTimes => int.Parse(GetSetting(SettingConstants.NoConnectByeTimes)?.SettingValue[0]);

        public int CallInOverConnRingTime => int.Parse(GetSetting(SettingConstants.CallInOverConnRingTime)?.SettingValue[0]);

        public int SeatChaoTime => int.Parse(GetSetting(SettingConstants.SeatChaoTime)?.SettingValue[0]);

        public int RingTimes => int.Parse(GetSetting(SettingConstants.RingTimes)?.SettingValue[0]);

        public string RecordPrefix => GetSetting(SettingConstants.RecordPrefix)?.SettingValue[0].Trim().ToString();

        public string DefaultVisitEmployeeId => GetSetting(SettingConstants.DefaultVisitEmployeeId)?.SettingValue[0].Trim().ToString();

        public int FixedQueryCount => int.Parse(GetSetting(SettingConstants.FixedQueryCount)?.SettingValue[0]);

        /// <summary>
        /// 保存回访详情时发送延迟消息同步通话记录
        /// 如果回访通话记录有多条, 需要关联通话时长最长的那条
        /// </summary>
        public int VisitCallDelaySecond =>
            GetOrDefault(null, SettingConstants.VisitCallDelaySecond, "回访通话记录同步延时时间(秒)", 60, "保存回访详情时发送延迟消息同步通话记录,如果回访通话记录有多条, 需要关联通话时长最长的那条");

        public bool AutomaticPublishOrder =>
            GetOrDefault(null, SettingConstants.AutomaticPublishOrder, "自动发布中心直办归档工单", false, "用于中心直办件归档后默认自动发布, 开启就自动发布.true 或者 false");

        /// <summary>
        /// 取消发布功能总开关
        /// </summary>
        public bool CancelPublishOrderEnabled =>
            GetOrDefault(null, SettingConstants.CancelPublishOrderEnabled, "取消发布功能开关", false, "取消发布功能总开关, 关闭后取消发布功能的所有代码都不会执行.true 或者 false");

        /// <summary>
        /// 发送回访短信后等候市民回复短信的时间(秒)
        /// 如果超过这个时间就更新回访为默认满意
        /// </summary>
        public int DefaultVisitSmsDelaySecond =>
            GetOrDefault<int>("08dc0681-a6d2-4ce7-877d-db65f846d523", SettingConstants.DefaultVisitSmsDelaySecond, "发送回访短信后等候市民回复短信的时间(秒)", 172800,
                "发送回访短信后等候市民回复短信的时间(秒), 如果超过这个时间就更新回访为默认满意. 默认 172800.");

        /// <summary>
        /// 通话记录同步时不推送省上的时间(默认:2024/11/19 18:08)
        /// </summary>
        public DateTime CallSyncUnPushDateTime =>
            GetOrDefault("08dc9bed-41da-4074-8289-e753e8fa8ea4", SettingConstants.CallSyncUnPushDateTime, "通话记录同步时不推送省上的时间(默认:2024/11/19 18:08)",
                DateTime.Parse("2024/11/19 18:08:00"), "通话记录同步时不推送省上的时间(默认:2024/11/19 18:08), 在兴唐数据库 callstarttime 字段时间小于设置 (默认:2024/11/19 18:08) 的时间都不会推送给省上");

        /// <summary>
        /// 即将超期列表调用方法的版本(有优化办法和老版本)
        /// </summary>
        public int GetAboutToExpireVersion =>
            GetOrDefault("08dc39bd-0ead-477c-87bc-97252dd8fb26", SettingConstants.GetAboutToExpireVersion, "前调用后端超期列表时后端控制调用优化的代码还是老代码", 0, "前调用后端超期列表时后端控制调用优化的代码还是老代码, 目前只有一个优化版本. 该值为 1 调用优化过的代码.");

        /// <summary>
        /// 工单开始办理如果获取的通话记录是呼出并且录音文件是空就不推送通话记录
        /// </summary>
        public bool OrderStartHandlerPushCallIsNull =>
            GetOrDefault("08dc9a54-d6ea-4757-8934-daff80efb86e", SettingConstants.OrderStartHandlerPushCallIsNull, "工单开始办理如果获取的通话记录是呼出并且录音文件是空就不推送通话记录", false, "工单开始办理如果获取的通话记录是呼出并且录音文件是空就不推送通话记录. true 不推通话记录, false 老逻辑继续推送");

        /// <summary>
        /// 微信小程序Secret
        /// </summary>
        public string WxOpenAppSecret =>
            GetOrDefault<string>("08dccbbc-4121-4f9c-87ba-ecdbce0bc15f", SettingConstants.WxOpenAppSecret, "微信小程序Secret", "bb29f684a9ea6b9d136062d68e867831", "微信小程序Secret");

        /// <summary>
        /// 微信小程序OpenId
        /// </summary>
        public string WxOpenAppId =>
            GetOrDefault("08dccbbc-090a-4446-842f-be95fc74c95e", SettingConstants.WxOpenAppId, "微信小程序OpenId", "wx22e6092dd504b567", "微信小程序OpenId");

        /// <summary>
        /// 微信小程序WebApi地址
        /// </summary>
        public string WxApiHost =>
            GetOrDefault("fafcd1b0-72fb-cfe0-7c82-3a1926c8a6cb", SettingConstants.WxApiHost, "微信小程序WebApi", "https://api.weixin.qq.com", "微信小程序WebApi");

        /// <summary>
        /// 文件服务器地址
        /// </summary>
        public string FileServerUrl =>
            GetOrDefault("08dc9a54-d6b1-46c9-8b9b-201025f629a1", SettingConstants.FileServerUrl, "文件服务器地址", "http://110.188.24.28:50120", "文件服务器地址");

        public string FileDownloadApi =>
            GetOrDefault("08dc9a54-d62e-4cdf-84ee-6c95859eec77", SettingConstants.FileDownloadApi, "文件服务器下载接口", "/file/downloadfile?Source=hotline&Id=", "文件服务器下载接口");

        /// <summary>
        /// 小程序Banner集合
        /// </summary>
        public string AppBanner =>
            GetOrDefault("08dcfe0a-e987-4981-8918-c272baaa4b04", SettingConstants.AppBanner, "小程序Bnner集合, 多个使用 | 分隔, 只写图片ID即可", "08dd136c-aed1-400a-8123-222987d4b087|08dd136c-aed1-400a-8123-222987d4b087", "小程序Bnner集合, 多个使用 | 分隔, 只写图片ID即可");

        /// <summary>
        /// 网格员回复等待时间(单位:小时)
        /// 超过该时间自动退回工单
        /// </summary>
        public double OvertimeBack =>
            GetOrDefault("08dd18e0-1c9e-4aa5-8dc6-f639e8d1b3ea", SettingConstants.OvertimeBack, "网格员回复等待时间(单元小时)", 4d, "网格员回复等待时间(单位:小时), 超过该时间自动退回工单");

        /// <summary>
        /// 天阙服务AppKey|AppSecret
        /// </summary>
        public string TianQueAppKeySecret =>
            GetOrDefault("08dcf4d7-3746-4f16-86b6-ef820421e5cb", SettingConstants.TianQueAppKeySecret, "天阙服务AppKey|AppSecret", "TAjYAYuA|c01eb299b9d784bf55681af4da86bab6ba428101", "天阙服务 AppKey|AppSecret, Key 和 Secret 使用 | 分隔");

        /// <summary>
        /// 天阙推送受理信息接口Url
        /// </summary>
        public string TianQuanPostAcceptInfoApi =>
            GetOrDefault("08dcd143-5f4b-477f-80e2-c2326d1d82e8", SettingConstants.TianQuanPostAcceptInfoApi, "天阙推送受理信息API接口地址", "http://10.0.188.11:6090/api/v1/test/accept/saveAcceptInfoApi", "测试: http://10.0.188.11:6090/api/v1/test/accept/saveAcceptInfoApi  正式: http://10.0.188.11:6090/api/v1/prod/accept/saveAcceptInfoApi");

        public ETianqueRequestMode TianQueRequestMode =>
            GetOrDefault("08dc941d-3344-420f-8c3a-fdb7a90d0948", SettingConstants.TianQueRequestMode, "天阙接口请求方式",
                ETianqueRequestMode.ProEnvProUrl, "天阙接口请求方式");

        /// <summary>
        /// 随手拍功能开关
        /// </summary>
        public bool Snapshot
        {
            get
            {
                var switchBtn = GetOrDefault("08dd0eca-66b8-4c98-8dec-0c76c29d77e3", SettingConstants.Snapshot, "随手拍功能开关", false, "随手拍功能开关");
                if (_senparcWeixin.Value.WxOpenAppId == null) return false;
                return switchBtn;
            }
        }

        /// <summary>
        /// 小程序同一个用户上报工单间隔时间(单位:分)
        /// </summary>
        public int SnapshotIntervalMinutes =>
                        GetOrDefault("08dcf5d6-fcda-40c4-8f25-65a636f4d99d",
                            SettingConstants.SnapshotIntervalMinutes,
                            "小程序同一个用户上报工单间隔时间(单位:分)",
                            20,
                            "小程序同一个用户上报工单间隔时间(单位:分)");

        /// <summary>
        /// 是否开启自动填写办理意见至汇总节点
        /// </summary>
        public bool IsAutoFillSummaryOpinion => GetOrDefault(null, SettingConstants.IsAutoFillSummaryOpinion, "是否开启自动填写办理意见至汇总节点", false, "是否开启自动填写办理意见至汇总节点");

        /// <summary>
        /// 是否不推送呼出的无文件的通话记录(true: 不推送, false: 推送)
        /// </summary>
        public bool IsNoPushCallNativeOutNoFile => GetOrDefault("08dd23d1-5c5b-4262-8c99-8c83710723ea", SettingConstants.IsNoPushCallNativeOutNoFile, "是否不推送呼出的无文件的通话记录(true: 不推送, false: 推送)", true, "是否不推送呼出的无文件的通话记录(true: 不推送, false: 推送)");

        public bool IsSendDissatisfiedScreenSms => GetOrDefault("08db29ad-9b54-44ca-8d4d-35c032748040", SettingConstants.IsSendDissatisfiedScreenSms, "回访不满意是否发送甄别短信", true, "true：发送；false：不发送");

    }
}
