using Hotline.Api.Filter;
using Hotline.Application.CallCenter;
using Hotline.Article;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Tels;
using Hotline.Realtimes;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.Article;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Article;
using Hotline.Share.Enums.CallCenter;
using Hotline.Tools;
using Hotline.Users;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers
{
    public class TelRestController : BaseController
    {
        private readonly ISystemDicDataCacheManager _systemDicDataCacheManager;
        private readonly IRepository<TelRestApply> _telRestApplyRepository;
        private readonly IPbxApplication _pbxApplication;
        private readonly ISessionContext _sessionContext;
        private readonly ITelDomainService _telDomainService;
        private readonly IMapper _mapper;
        private readonly IRealtimeService _realtimeService;
        private readonly ICircularRecordDomainService _circularRecordDomainService;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;
        private readonly IRepository<User> _userRepository;

        public TelRestController(ISystemDicDataCacheManager systemDicDataCacheManager,
             IRepository<TelRestApply> telRestApplyRepository,
              IPbxApplication pbxApplication,
              ISessionContext sessionContext,
              ITelDomainService telDomainService,
              IMapper mapper,
              IRealtimeService realtimeService,
              ICircularRecordDomainService circularRecordDomainService,
              ISystemSettingCacheManager systemSettingCacheManager,
              IRepository<User> userRepository)
        {
            _systemDicDataCacheManager = systemDicDataCacheManager;
            _telRestApplyRepository = telRestApplyRepository;
            _pbxApplication = pbxApplication;
            _sessionContext = sessionContext;
            _telDomainService = telDomainService;
            _mapper = mapper;
            _realtimeService = realtimeService;
            _circularRecordDomainService = circularRecordDomainService;
            _systemSettingCacheManager = systemSettingCacheManager;
            _userRepository = userRepository;
        }

        #region 小休审批

        /// <summary>
        /// 列表页面基础数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data")]
        public async Task<object> BaseData()
        {
            var rsp = new
            {
                RestReason = _systemDicDataCacheManager.GetSysDicDataCache(SysDicTypeConsts.RestReason),
                AuditStatus = EnumExts.GetDescriptions<ETelRestAuditStatus>()
            };
            return rsp;
        }

        /// <summary>
        /// 查询是否需要小休审批
        /// </summary>
        /// <returns></returns>
        [HttpGet("ischeckaudit")]
        public async Task<bool> IsCheckAudit()
        {
            try
            {
                //首先验证是否开启，如果开启需要审批进行下一步判断
                //未开启则不用审批
                var isRestApproval = bool.Parse(_systemSettingCacheManager.GetSetting(SettingConstants.IsRestApproval).SettingValue[0]);
                if (isRestApproval)
                {
                    var restAuditTime = _systemSettingCacheManager.GetSetting(SettingConstants.IsRestAuditTime).SettingValue;
                    if (restAuditTime == null || restAuditTime.Count == 0)
                        return false;
                    foreach (var item in restAuditTime)
                    {
                        var time = item.Split('-');
                        var nowTime = DateTime.Now;
                        var starTime = Convert.ToDateTime(nowTime.ToString("yyyy-MM-dd") + " " + time[0]);
                        var endTime = Convert.ToDateTime(nowTime.ToString("yyyy-MM-dd") + " " + time[1]);
                        if (starTime < nowTime && endTime > nowTime)
                            return true;
                    }

                    return false;
                }
                else
                    return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 小休申请
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="UserFriendlyException"></exception>
        [HttpPost("addtelrest")]
        public async Task<string> AddTelRest([FromBody] TelRestApplyAddDto dto)
        {
            if (string.IsNullOrEmpty(dto.TelNo))
                throw new  UserFriendlyException("分机号不能为空！", "分机号不能为空！");
                
            if (dto.Reason == null) 
                throw new UserFriendlyException("小休原因不能为空！", "小休原因不能为空！");

            var data = await _telRestApplyRepository.GetAsync(p => p.TelNo == dto.TelNo && p.CreatorId == _sessionContext.RequiredUserId &&
            p.AuditStatus == ETelRestAuditStatus.NoAudit, HttpContext.RequestAborted);
            if (data != null)
                throw new UserFriendlyException("小休申请审批中，暂时无法操作！", "小休申请审批中，暂时无法操作！");

            TelRestApply telRestApply = new()
            {
                TelNo = dto.TelNo,
                Reason = dto.Reason.Value,
                ReasonId = dto.Reason.Key,
                StaffNo = _sessionContext.StaffNo,
                AuditStatus = ETelRestAuditStatus.NoAudit
            };
            var id = await _telRestApplyRepository.AddAsync(telRestApply, HttpContext.RequestAborted);
            if (!string.IsNullOrEmpty(id))
            {
                //查询小休审批人
                var setting = _systemSettingCacheManager.GetSetting(SettingConstants.RestAuditRole).SettingValue;
                var list = await _userRepository.Queryable()
                        .Includes(u => u.Roles)
                         .Where(u => u.Roles.Any(x => setting.Contains(x.Name)))
                         .ToListAsync();

                //给审批人发送提醒
                if (list != null && list.Any())
                {
                    AddCircularDto circularDto = new()
                    {
                        Title = "小休审批",
                        Content = dto.TelNo + "申请了小休，请及时处理。",
                        CircularTypeId = "7",
                        CircularTypeName = "小休审批",
                        IsMustRead = true,
                        SourceOrgId = _sessionContext.RequiredOrgId,
                        SourceOrgName = _sessionContext.OrgName,
                        CircularType = ECircularType.Person
                    };
                    List<CircularReadGroupDto> users = [];
                    foreach (var user in list)
                    {
                        users.Add(new CircularReadGroupDto()
                        {
                            UserId = user.Id,
                            UserName = user.Name,
                        });
                    }
                    circularDto.CircularReadGroups = users;
                    //调用推送消息通用接口
                    await _circularRecordDomainService.AddCircularMessage(circularDto, HttpContext.RequestAborted);

                }
                return "小休申请成功！";
            }
            else
                return "小休申请失败！";

        }

        /// <summary>
        /// 小休审批
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="UserFriendlyException"></exception>
        [HttpPost("telrest_apply_audit")]
        public async Task<string> TelRestApplyAudit([FromBody] TelRestApplyAuditDto dto)
        {
            if (dto.IsPass != true && string.IsNullOrEmpty(dto.AuditOpinion))
                throw new UserFriendlyException("审批原因不能为空！", "审批原因不能为空！");

            foreach (var item in dto.Ids)
            {
                var data = await _telRestApplyRepository.GetAsync(item, HttpContext.RequestAborted);
                if (data != null)
                {
                    data.AuditUserName = _sessionContext.UserName;
                    data.AuditUserId = _sessionContext.RequiredUserId;
                    data.AuditOrgId = _sessionContext.RequiredOrgId;
                    data.AuditOrgName = _sessionContext.OrgName;
                    data.AuditTime = DateTime.Now;
                    data.AuditOpinion = dto.AuditOpinion;
                    data.AuditStatus = dto.IsPass == true ? ETelRestAuditStatus.Pass : ETelRestAuditStatus.NoPass;
                    await _telRestApplyRepository.UpdateAsync(data, HttpContext.RequestAborted);

                    //发送消息
                    var ispasstext = dto.IsPass == true ? "已通过" : "不通过";
                    AddCircularDto circularDto = new()
                    {
                        Title = "小休审批",
                        Content = "您在" + data.CreationTime.ToString("yyyy-MM-dd HH:mm:ss") + "申请的小休审批" + ispasstext,
                        CircularTypeId = "7",
                        CircularTypeName = "小休审批",
                        IsMustRead = true,
                        SourceOrgId = _sessionContext.RequiredOrgId,
                        SourceOrgName = _sessionContext.OrgName,
                        CircularType = ECircularType.Person
                    };
                    List<CircularReadGroupDto> users = [];
                    users.Add(new CircularReadGroupDto()
                    {
                        UserId = data.CreatorId,
                        UserName = data.CreatorName
                    });
                    circularDto.CircularReadGroups = users;
                    //调用推送消息通用接口
                    await _circularRecordDomainService.AddCircularMessage(circularDto, HttpContext.RequestAborted);
                    if (dto.IsPass)
                    {
                        //通知前端休息通过
                        await _realtimeService.RestApplyPassAsync(data.CreatorId, HttpContext.RequestAborted);
                    }
                }
            }
            return "审批完成";
        }

        /// <summary>
        /// 小修申请记录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("get_restapply_list")]
        public async Task<PagedDto<TelRestApplyListDto>> GetRestApplyList([FromQuery] TelRestApplyRequestDto dto)
        {
            var (total, items) = await _pbxApplication.GetRestApplyList(dto).ToPagedListAsync(dto.PageIndex, dto.PageSize, HttpContext.RequestAborted);

            return new PagedDto<TelRestApplyListDto>(total, items);
        }

        /// <summary>
        /// 小修申请记录--导出
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("get_restapply_list_export")]
		[LogFilterAlpha("导出日志")]
		public async Task<FileStreamResult> GetRestApplyListExport([FromBody] ExportExcelDto<TelRestApplyRequestDto> dto)
        {
            var query = _pbxApplication.GetRestApplyList(dto.QueryDto);

            List<TelRestApplyListDto> data;
            if (dto.IsExportAll)
            {
                data = await query.ToListAsync(HttpContext.RequestAborted);
            }
            else
            {
                var (_, items) = await query.ToPagedListAsync(dto.QueryDto, HttpContext.RequestAborted);
                data = items;
            }
            dynamic? dynamicClass = DynamicClassHelper.CreateDynamicClass<TelRestApplyListDto>(dto.ColumnInfos);
            var dtos = data
                .Select(stu => _mapper.Map(stu, typeof(TelRestApplyListDto), dynamicClass))
                .Cast<object>()
                .ToList();

            var stream = ExcelHelper.CreateStream(dtos);
            return ExcelStreamResult(stream, "小修申请记录数据");
        }


        #endregion
    }
}
