using Hotline.Api.Filter;
using Hotline.Application.CallCenter;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Configs;
using Hotline.CallCenter.Tels;
using Hotline.EventBus;
using Hotline.Repository.SqlSugar;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.CallNative;
using Hotline.Share.Dtos.TrCallCenter;
using Hotline.Share.Enums.CallCenter;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SqlSugar;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XingTang.Sdk;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Share.Requests;
using Hotline.Share.Dtos.Order;
using Hotline.CallCenter.BlackLists;

namespace Hotline.Api.Controllers
{
    public class CallNativeContrroller : BaseController
    {
        private readonly ICallApplication _callApplication;
        private readonly Publisher _publisher;
        private readonly IMapper _mapper;
        private readonly IOptionsSnapshot<CallCenterConfiguration> _callcenterOptions;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
        private readonly IRepository<TelOperationXthx> _telOperationXthxRepository;
        private readonly IUserCacheManager _userCacheManager;
        private readonly ISessionContext _sessionContext;
        private readonly IRepository<TelActionRecord> _telActionRecordRepository;
        private readonly ITelRestRepository _telRestRepository;
        private readonly ISqlSugarClient _db;
        private readonly IRepository<WhiteBlackLog> _whiteBlackLogRepository;

        public CallNativeContrroller(
            ICallApplication callApplication,
            Publisher publisher,
            IMapper mapper,
            IOptionsSnapshot<CallCenterConfiguration> callcenterOptions,
            ISystemSettingCacheManager systemSettingCacheManager,
            IRepository<TelOperationXthx> telOperationXthxRepository,
            IUserCacheManager userCacheManager,
            ISessionContext sessionContext,
            IRepository<TelActionRecord> telActionRecordRepository,
            ITelRestRepository telRestRepository,
            ISugarUnitOfWork<XingTangDbContext> uow,
            IRepository<WhiteBlackLog> whiteBlackLogRepository)
        {
            _callApplication = callApplication;
            _publisher = publisher;
            _mapper = mapper;
            _callcenterOptions = callcenterOptions;
            _systemSettingCacheManager = systemSettingCacheManager;
            _telOperationXthxRepository = telOperationXthxRepository;
            _userCacheManager = userCacheManager;
            _sessionContext = sessionContext;
            _telActionRecordRepository = telActionRecordRepository;
            _telRestRepository = telRestRepository;
            _db = uow.Db;
            _whiteBlackLogRepository = whiteBlackLogRepository;
        }

        #region 黑白名单处理
        #region 黑名单
        /// <summary>
        /// 获取黑名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("get-black-phone-list")]
        public async Task<PagedDto<BlackPhoneListDto>> GetBlackPhoneList([FromQuery] PagedKeywordRequest dto)
        {
            var (total, items) = await _db.Queryable<XingtangBlackPhone>()
                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.StartPhone.Contains(dto.Keyword))
                .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<BlackPhoneListDto>(total, _mapper.Map<IReadOnlyList<BlackPhoneListDto>>(items));
        }

        /// <summary>
        /// 删除黑名单
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        [HttpDelete("delete-black-phone/{phone}")]
        [LogFilter("删除黑名单")]
        public async Task DeleteBlackPhone(string phone)
        {
            var row = await _db.Deleteable<XingtangBlackPhone>().Where(p => p.StartPhone == phone).ExecuteCommandAsync();
            if (row >= 0)
            {
                WhiteBlackLog whiteBlackLog = new()
                {
                    LogType = "1",
                    LogAction = "删除",
                    PhoneNum = phone
                };
                await _whiteBlackLogRepository.AddAsync(whiteBlackLog, HttpContext.RequestAborted);
            }
        }

        /// <summary>
        /// 新增黑名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("add-black-phone")]
        [LogFilter("新增黑名单")]
        public async Task AddBlackPhone([FromBody] AddBlackPhoneDto dto)
        {
            if (string.IsNullOrEmpty(dto.PhoneNum))
                throw UserFriendlyException.SameMessage("电话号码不能为空！");

            if (dto.ValidDateTime.HasValue == false)
                dto.ValidDateTime = Convert.ToDateTime("2099-01-01 23:59:59");

            var isEx = await _db.Queryable<XingtangBlackPhone>().Where(p => p.StartPhone == dto.PhoneNum).AnyAsync();
            if (isEx)
                throw UserFriendlyException.SameMessage("此号码已经是黑名单！");

            var id = await _db.Queryable<XingtangBlackPhone>().MaxAsync(p => p.BlackPhoneId);
            XingtangBlackPhone xingtangBlackPhone = new XingtangBlackPhone()
            {
                BlackPhoneId = id + 1,
                StartPhone = dto.PhoneNum,
                PhoneType = 0,
                ValidDateTime = dto.ValidDateTime,
                Enabled = 1,
                CreateDate = DateTime.Now,
                CreateUserId = _sessionContext.UserId
            };
            var row = await _db.Insertable(xingtangBlackPhone).ExecuteCommandAsync();
            if (row >= 0)
            {
                WhiteBlackLog whiteBlackLog = new()
                {
                    LogType = "1",
                    LogAction = "新增",
                    PhoneNum = dto.PhoneNum,
                    ValidDateTime = dto.ValidDateTime
                };
                await _whiteBlackLogRepository.AddAsync(whiteBlackLog, HttpContext.RequestAborted);
            }
        }
        #endregion

        #region 白名单
        /// <summary>
        /// 获取白名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("get-white-phone-list")]
        public async Task<PagedDto<WhitePhoneListDto>> GetWhitePhoneList([FromQuery] PagedKeywordRequest dto)
        {
            var (total, items) = await _db.Queryable<XingtangWhitePhone>()
                .WhereIF(!string.IsNullOrEmpty(dto.Keyword), p => p.Phone.Contains(dto.Keyword))
                .Select(p => new WhitePhoneListDto
                {
                    Id = p.Id,
                    StartPhone = p.Phone,
                    ValidDateTime = p.ValidDateTime,
                    Enabled = p.Enabled
                })
                .ToPagedListAsync(dto, HttpContext.RequestAborted);

            return new PagedDto<WhitePhoneListDto>(total, _mapper.Map<IReadOnlyList<WhitePhoneListDto>>(items));
        }

        /// <summary>
        /// 删除白名单
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        [HttpDelete("delete-white-phone/{phone}")]
        [LogFilter("删除白名单")]
        public async Task DeleteWhitePhone(string phone)
        {
            var row = await _db.Deleteable<XingtangWhitePhone>().Where(p => p.Phone == phone).ExecuteCommandAsync();
            if (row >= 0)
            {
                WhiteBlackLog whiteBlackLog = new()
                {
                    LogType = "2",
                    LogAction = "删除",
                    PhoneNum = phone
                };
                await _whiteBlackLogRepository.AddAsync(whiteBlackLog, HttpContext.RequestAborted);
            }
        }

        /// <summary>
        /// 新增白名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("add-white-phone")]
        [LogFilter("新增白名单")]
        public async Task AddWhitePhone([FromBody] AddBlackPhoneDto dto)
        {
            if (string.IsNullOrEmpty(dto.PhoneNum))
                throw UserFriendlyException.SameMessage("电话号码不能为空！");

            if (dto.ValidDateTime.HasValue == false)
                dto.ValidDateTime = Convert.ToDateTime("2099-01-01 23:59:59");

            var isEx = await _db.Queryable<XingtangWhitePhone>().Where(p => p.Phone == dto.PhoneNum).AnyAsync();
            if (isEx)
                throw UserFriendlyException.SameMessage("此号码已经是白名单！");

            var id = await _db.Queryable<XingtangWhitePhone>().MaxAsync(p => p.Id);
            XingtangWhitePhone xingtangPhone = new XingtangWhitePhone()
            {
                Id = id + 1,
                Phone = dto.PhoneNum,
                ValidDateTime = dto.ValidDateTime,
                Enabled = 1
            };
            var row = await _db.Insertable(xingtangPhone).ExecuteCommandAsync();
            if (row >= 0)
            {
                WhiteBlackLog whiteBlackLog = new()
                {
                    LogType = "2",
                    LogAction = "新增",
                    PhoneNum = dto.PhoneNum,
                    ValidDateTime = dto.ValidDateTime
                };
                await _whiteBlackLogRepository.AddAsync(whiteBlackLog, HttpContext.RequestAborted);
            }
        }
        #endregion

        /// <summary>
        /// 查询黑白名单操作记录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("get-white-black-log-list")]
        public async Task<PagedDto<WhiteBlackLog>> GetWhiteBlackLogList([FromQuery] BlackPhoneListQuery dto)
        {
            var (total, items) = await _whiteBlackLogRepository.Queryable()
                .WhereIF(dto.StartTime.HasValue, p => p.CreationTime >= dto.StartTime)
                .WhereIF(dto.EndTime.HasValue, p => p.CreationTime <= dto.EndTime)
                .WhereIF(!string.IsNullOrEmpty(dto.LogType), p => p.LogType == dto.LogType)
                .WhereIF(!string.IsNullOrEmpty(dto.LogAction), p => p.LogAction == dto.LogAction)
                .WhereIF(!string.IsNullOrEmpty(dto.UserName), p => p.CreatorName == dto.UserName)
                .WhereIF(!string.IsNullOrEmpty(dto.PhoneNum), p => p.PhoneNum == dto.PhoneNum)
                .OrderByDescending(p => p.CreationTime)
                .ToPagedListAsync(dto, HttpContext.RequestAborted);
            return new PagedDto<WhiteBlackLog>(total, items);
        }

        /// <summary>
        /// 验证号码是否是白名单
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        [HttpGet("verify-white-list/{phone}")]
        public async Task<bool> VerifyWhiteList(string phone)
        {
            try
            {
                var isEx = await _db.Queryable<XingtangWhitePhone>().Where(p => p.Phone == phone && p.ValidDateTime >= DateTime.Now).AnyAsync();
                if (isEx)
                    return true;
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion
    }
}
