using Hotline.Application.Xthx;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Tels;
using Hotline.Settings;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Enums.CallCenter;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Text.Json;
using XF.Domain.Authentications;
using XF.Domain.Exceptions;
using XF.Domain.Repository;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 兴唐恒信
    /// </summary>
    public class XthxController : BaseController
    {

        #region 注入

        private readonly IMapper _mapper;
        private readonly ISessionContext _sessionContext;
        private readonly IXthxApplication _xthxApplication;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;                //系统参数
        private readonly IRepository<TelOperationXthx> _telOperationXthxRepository;            //坐席动作类型
        private readonly IRepository<TelOperationXthxLog> _telOperationXthxLogRepository;      //坐席动作类型

        public XthxController(
           IMapper mapper,
           ISessionContext sessionContext,
           IXthxApplication xthxApplication,
           ISystemSettingCacheManager systemSettingCacheManager,
           IRepository<TelOperationXthx> telOperationXthxRepository,
            IRepository<TelOperationXthxLog> telOperationXthxLogRepository)
        {
            _mapper = mapper;
            _sessionContext = sessionContext;
            _xthxApplication = xthxApplication;
            _systemSettingCacheManager = systemSettingCacheManager;
            _telOperationXthxRepository = telOperationXthxRepository;
            _telOperationXthxLogRepository = telOperationXthxLogRepository;
        }

        #endregion

        #region 分机状态变更接收

        /// <summary>
        /// 分机状态变更接收
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("status/add")]
        [AllowAnonymous]
        public async Task<string> AddOperationAsync([FromBody] TelOperationXthxDto dto)
        {
            #region 描述

            /*
                1、根据分机号（telNo）和员工号（staffNo）确定唯一关系。

                2、设计话机动作状态【签入、示忙、小休】

                3、当【签入】时记录签入状态、开始时间，当【签出】时找到未结束的签入记录更新结束时间。
                   先结束之前的【签入】，再重新【签入】

                4、当【示忙】时记录示忙状态、开始时间，当传入非【示忙】状态，并且有未结束的【示忙】状态时更新结束时间。
                   先结束之前的【示忙】，再重新【示忙】

                5、当【小休】时记录小休状态、开始时间，当传入非【小休】状态，并且有未结束的【小休】状态时更新结束时间。
                   先结束之前的【小休】，再重新【小休】

                6、当【空闲】时，需要检查示忙、小休是否结束，未结束需要结束

                7、当【签出】时，需要检查示忙、小休是否结束，未结束需要结束

                8、除了【签入签出】状态，其他状态都要验证当前是否有【签入】，没有则新增签入
             */

            #endregion

            #region 鉴权

            var settingBase = _systemSettingCacheManager.GetSetting(SettingConstants.XthxVerificationStatusAdd)?.SettingValue[0];
            if (settingBase != null)
            {
                TelAppXthxDto telAppDto = JsonSerializer.Deserialize<TelAppXthxDto>(settingBase);
                if (dto.appId != telAppDto.appId || dto.appSecret != telAppDto.appSecret)
                    throw UserFriendlyException.SameMessage("appId或者appSecret错误");
            }

            #endregion

            // 查询日期间隔天数
            var day = 3;

            // 增加动作日志
            var id = await _xthxApplication.AddOperationLogAsync(dto, HttpContext.RequestAborted);
            if (!string.IsNullOrEmpty(id))
            {
                if (dto.Status == EOperationStatus.SignIn)
                {
                    #region 签入 100

                    var xthxList = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                    x.OperationStatus == EOperationStatus.SignIn &&
                                    SqlFunc.DateDiff(DateType.Day, x.CreationTime, DateTime.Now) < day).ToListAsync();
                    if (xthxList != null && xthxList.Count > 0)
                    {
                        // 判断是否存在数据，存在数据需要判断结束时间是否为空
                        var rowSign = xthxList.Where(x => x.EndTime == null).ToList();//.Select("EndTime is null");
                        if (rowSign != null && rowSign.Count > 0)
                        {// 如果结束时间为空 结束之前的（签收、示忙、小休）
                            foreach (var item in rowSign)
                            {
                                await _xthxApplication.UpdateOperationAsync(id, item.Id, HttpContext.RequestAborted);
                            }
                        }
                    }
                    await _xthxApplication.AddOperationAsync(dto, id, HttpContext.RequestAborted);

                    #endregion
                }
                if (dto.Status == EOperationStatus.ShowBusy)
                {
                    #region 示忙 202

                    var xthxList = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                    x.OperationStatus == EOperationStatus.ShowBusy &&
                                    SqlFunc.DateDiff(DateType.Day, x.CreationTime, DateTime.Now) < day).ToListAsync();
                    if (xthxList != null && xthxList.Count > 0)
                    {
                        // 判断是否存在数据，存在数据需要判断结束时间是否为空
                        var rowSign = xthxList.Where(x => x.EndTime == null).ToList();//.Select("EndTime is null");
                        if (rowSign != null && rowSign.Count > 0)
                        {// 如果结束时间为空 结束之前的（签收、示忙、小休）
                            foreach (var item in rowSign)
                            {
                                await _xthxApplication.UpdateOperationAsync(id, item.Id, HttpContext.RequestAborted);
                            }
                        }
                    }
                    await _xthxApplication.AddOperationAsync(dto, id, HttpContext.RequestAborted);

                    #endregion
                }
                if (dto.Status == EOperationStatus.ShortBreak)
                {
                    #region 小休 201

                    var xthxList = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                    x.OperationStatus == EOperationStatus.ShortBreak &&
                                    SqlFunc.DateDiff(DateType.Day, x.CreationTime, DateTime.Now) < day).ToListAsync();
                    if (xthxList != null && xthxList.Count > 0)
                    {

                        // 判断是否存在数据，存在数据需要判断结束时间是否为空
                        var rowSign = xthxList.Where(x => x.EndTime == null).ToList();//.Select("EndTime is null");
                        if (rowSign != null && rowSign.Count > 0)
                        {// 如果结束时间为空 结束之前的（签收、示忙、小休）
                            foreach (var item in rowSign)
                            {
                                await _xthxApplication.UpdateOperationAsync(id, item.Id, HttpContext.RequestAborted);
                            }
                        }
                    }
                    await _xthxApplication.AddOperationAsync(dto, id, HttpContext.RequestAborted);

                    #endregion
                }
                else if (dto.Status == EOperationStatus.FreeTime)
                {
                    #region 空闲 200

                    // 当【空闲】时，需要检查示忙、小休是否结束，未结束需要结束

                    var sign = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                   (x.OperationStatus == EOperationStatus.ShowBusy ||
                                    x.OperationStatus == EOperationStatus.ShortBreak) &&
                                    x.StartTime != null &&
                                    x.EndTime == null)
                        .ToListAsync();
                    if (sign != null)
                    {
                        // 判断是否有签入未结束的动作
                        foreach (var item in sign)
                        {
                            await _xthxApplication.UpdateOperationAsync(id, item.Id!, HttpContext.RequestAborted);
                        }
                    }

                    #endregion
                }
                else if (dto.Status == EOperationStatus.SignOut)
                {
                    #region 签出 0

                    // 当【签出】时，需要检查示忙、小休是否结束，未结束需要结束

                    var sign = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                   (x.OperationStatus == EOperationStatus.SignIn ||
                                    x.OperationStatus == EOperationStatus.ShowBusy ||
                                    x.OperationStatus == EOperationStatus.ShortBreak) &&
                                    x.StartTime != null &&
                                    x.EndTime == null)
                        .ToListAsync();
                    if (sign != null)
                    {
                        // 判断是否有签入未结束的动作
                        foreach (var item in sign)
                        {
                            await _xthxApplication.UpdateOperationAsync(id, item.Id!, HttpContext.RequestAborted);
                        }
                    }

                    #endregion
                }
                else
                {
                    #region 其他动作

                    // 除了【签入签出】状态，其他状态都要验证当前是否有【签入】，没有则新增
                    var sign = await _telOperationXthxRepository.Queryable()
                        .Where(x => x.TelNo == dto.TelNo &&
                                    x.StaffNo == dto.StaffNo &&
                                    x.OperationStatus == EOperationStatus.SignIn &&
                                    x.StartTime != null &&
                                    x.EndTime == null)
                        .ToListAsync();
                    if (sign.Count == 0)
                    {
                        // 未找到数据 新增
                        dto.Status = EOperationStatus.SignIn;
                        await _xthxApplication.AddOperationAsync(dto, id, HttpContext.RequestAborted);
                    }

                    #endregion
                }
            }
            return id;
        }

        #endregion

    }
}
