using Hotline.CallCenter.BlackLists;
using Hotline.CallCenter.Calls;
using Hotline.Permissions;
using Hotline.Repository.SqlSugar.Extensions;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Enums.CallCenter;
using Hotline.Share.Enums.Order;
using Hotline.Share.Requests;
using MapsterMapper;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using XF.Domain.Repository;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers
{
    /// <summary>
    /// 通话相关接口
    /// </summary>
    public class CalloldController : BaseController
    {
        private readonly ICallRepository _callRepository;
        private readonly IMapper _mapper;
        private readonly IBlacklistDomainService _blacklistDomainService;
        private readonly IBlacklistRepository _blacklistRepository;
        private readonly IRepository<WexCallRecord> _wexCallRecordRepository;

        /// <summary>
        /// 通话相关接口构造
        /// </summary>
        /// <param name="callRepository"></param>
        /// <param name="mapper"></param>
        /// <param name="blacklistDomainService"></param>
        /// <param name="blacklistRepository"></param>
        /// <param name="wexCallRecordRepository"></param>
        public CalloldController(
            ICallRepository callRepository,
            IMapper mapper,
            IBlacklistDomainService blacklistDomainService,
            IBlacklistRepository blacklistRepository,
            IRepository<WexCallRecord> wexCallRecordRepository)
        {
            _callRepository = callRepository;
            _mapper = mapper;
            _blacklistDomainService = blacklistDomainService;
            _blacklistRepository = blacklistRepository;
            _wexCallRecordRepository = wexCallRecordRepository;
        }

        #region 威而信通话记录
        /// <summary>
        /// 威而信通话记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet("wexpaged")]
        public async Task<PagedDto<CallWexDto>> GetCallListWex([FromQuery] GetCallListWexRequest request)
        {
             var (total,items) = await _wexCallRecordRepository.Queryable()
                .WhereIF(!string.IsNullOrEmpty(request.CDPN), d => d.CDPN.Contains(request.CDPN!))
                .WhereIF(!string.IsNullOrEmpty(request.CPN), d => d.CPN.Contains(request.CPN!))
                .WhereIF(request.Direction is not null, d => d.Direction == request.Direction)
                .WhereIF(request.OnState is not null, d => d.OnState == request.OnState)
                .WhereIF(!string.IsNullOrEmpty(request.StaffNo), d => d.StaffNo.Contains(request.StaffNo))
                .OrderByDescending(d => d.BeginTime)
                .ToPagedListAsync(request.PageIndex, request.PageSize);
            return new PagedDto<CallWexDto>(total, _mapper.Map<IReadOnlyList<CallWexDto>>(items));
        }

        /// <summary>
        /// 页面基础信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data")]
        public async Task<object> BaseData()
        {
            var rsp = new
            {
                CallDirectionOption = EnumExts.GetDescriptions<ECallDirection>(),
                OnStateOption = EnumExts.GetDescriptions<EOnState>()
            };
            return rsp;
        }



        #endregion


        #region 通话记录

        /// <summary>
        /// 分页通话记录列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet("paged")]
        public async Task<PagedDto<CallDto>> GetCallList([FromQuery] GetCallListRequest request)
        {
            var (total, items) = await _callRepository.Queryable()
                .Includes(d => d.CallDetails)
                .WhereIF(!string.IsNullOrEmpty(request.PhoneNum), d => d.FromNo.Contains(request.PhoneNum!))
                .WhereIF(!string.IsNullOrEmpty(request.ToNum), d => d.ToNo.Contains(request.ToNum!))
                .WhereIF(request.Direction is not null, d => d.CallDirection == request.Direction)
                .WhereIF(request.CallState is not null, request.CallState == ECallState.On ? d => d.CallDetails.Any(q => q.EventName == "ANSWERED") : d => !d.CallDetails.Any(q => q.EventName == "ANSWERED"))
                .WhereIF(!string.IsNullOrEmpty(request.UserName), d => d.UserName.Contains(request.UserName))
                .OrderByDescending(d => d.CreationTime)
                .ToPagedListAsync(request.PageIndex, request.PageSize);
            return new PagedDto<CallDto>(total, _mapper.Map<IReadOnlyList<CallDto>>(items));
        }

        /// <summary>
        /// 查询未接通话记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet("messed-paged")]
        public async Task<PagedDto<CallDto>> GetCallListMissed([FromQuery] GetCallListRequest request)
        {
            var (total, items) = await _callRepository.Queryable()
                .Where(x => !x.CallDetails.Any(d => d.EventName == "ANSWERED"))
                .WhereIF(!string.IsNullOrEmpty(request.PhoneNum), d => d.FromNo.Contains(request.PhoneNum!))
                .WhereIF(!string.IsNullOrEmpty(request.ToNum), d => d.ToNo.Contains(request.ToNum!))
                .WhereIF(request.Direction is not null, d => d.CallDirection == request.Direction)
                .Includes(d => d.CallDetails)
                .OrderByDescending(d => d.CreationTime)
                .ToPagedListAsync(request.PageIndex, request.PageSize);
            return new PagedDto<CallDto>(total, _mapper.Map<IReadOnlyList<CallDto>>(items));
        }


        #endregion

        #region 对外通话记录

        /// <summary>
        /// 通话记录（外部对接）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet("out-calllist")]
        public async Task<IReadOnlyList<OutCallDto>> GetOutCallList([FromQuery] GetOutCallListRequest request)
        {
            var list = await _callRepository.QueryPartAsync(request.time);
            List<OutCallDto> outCallList = new List<OutCallDto>();
            foreach (var item in list)
            {
                OutCallDto outCallDto = new OutCallDto();
                outCallDto.CallId = item.Id;
                outCallDto.InfoType = EInfoType.Call;//TODO目前写死（只有电话）
                outCallDto.Direction = item.CallDirection;
                outCallDto.Cpn = item.FromNo ?? "";
                outCallDto.Cdpn = item.ToNo ?? "";
                outCallDto.Answered = item.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.AnswerNo ?? "";
                outCallDto.BeginTime = item.CreationTime;
                outCallDto.OnTime = item.CallDetails?.FirstOrDefault(x => x.EventName == "ANSWERED")?.CreationTime;//TODO 接通时间是否可以为空
                outCallDto.ByeTime = item.CallDetails?.FirstOrDefault(x => x.EventName == "BYE")?.CreationTime;
                outCallDto.TalkTime = item.Duration;
                outCallDto.SoundFileName = item.CallDetails?.FirstOrDefault(x => x.EventName == "BYE")?.Recording ?? "";
                outCallDto.EvaluateResult = "";
                outCallDto.EndBy = item.EndBy;
                outCallDto.OnState = item.CallDetails?.Any(x => x.EventName == "ANSWERED") == true ? EOnState.On : EOnState.NoOn;
                outCallList.Add(outCallDto);
            }
            return outCallList;
        }

        #endregion

        #region 黑名单

        /// <summary>
        /// 添加电话号至黑名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("blacklist")]
        public async Task AddBlacklist([FromBody] AddBlacklistDto dto)
        {
            await _blacklistDomainService.AddAsync(dto, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 删除黑名单数据
        /// </summary>
        /// <param name="phone"></param>
        [HttpDelete("blacklist/{phone}")]
        public void RemoveBlacklist(string phone)
        {
            _blacklistDomainService.RemoveAsync(phone);
        }

        /// <summary>
        /// 分页查询黑名单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("blacklist/paged")]
        public async Task<PagedDto<Blacklist>> QueryPaged([FromQuery] BlacklistPagedDto dto)
        {
            var (total, items) = await _blacklistRepository.QueryPagedAsync(
                d => !d.IsDeleted,
                d => d.OrderByDescending(x => x.CreationTime),
                dto.PageIndex,
                dto.PageSize,
                whereIfs: (!string.IsNullOrEmpty(dto.PhoneNo), d => d.PhoneNo.Contains(dto.PhoneNo!)));
            return new PagedDto<Blacklist>(total, items);
        }

        #endregion

    }
}
