using Hotline.Application.CallCenter;
using Hotline.Share.Tools;
using Hotline.Caching.Interfaces;
using Hotline.CallCenter.BlackLists;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Configs;
using Hotline.CallCenter.Tels;
using Hotline.EventBus;
using Hotline.Quality.Notifications;
using Hotline.Settings;
using Hotline.Share.Dtos;
using Hotline.Share.Dtos.CallCenter;
using Hotline.Share.Dtos.Quality;
using Hotline.Share.Dtos.TrCallCenter;
using Hotline.Share.Enums.CallCenter;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Threading;
using XF.Domain.Exceptions;
using XF.Utility.EnumExtensions;

namespace Hotline.Api.Controllers
{
    public class CallController : BaseController
    {
        private readonly ICallApplication _callApplication;
        private readonly Publisher _publisher;
        private readonly IOptionsSnapshot<CallCenterConfiguration> _callcenterOptions;
        private readonly ISystemSettingCacheManager _systemSettingCacheManager;

		public CallController(
            ICallApplication callApplication,
            Publisher publisher,
            IOptionsSnapshot<CallCenterConfiguration> callcenterOptions,
            ISystemSettingCacheManager systemSettingCacheManager)
        {
            _callApplication = callApplication;
            _publisher = publisher;
            _callcenterOptions = callcenterOptions;
            _systemSettingCacheManager = systemSettingCacheManager;
		}

        /// <summary>
        /// 查询分机
        /// </summary>
        [HttpGet("tels")]
        public async Task<IList<TelDto>> QueryTels()
            => (await _callApplication.QueryTelsAsync(new QueryTelsInDto(null) { PageSize = 99999}, HttpContext.RequestAborted)).Item2;

        /// <summary>
        /// 查询分机
        /// </summary>
        [HttpGet("tels-paged")]
        public async Task<PagedDto<TelDto>> QueryTelsAsync([FromQuery]QueryTelsInDto dto)
            => (await _callApplication.QueryTelsAsync(dto, HttpContext.RequestAborted)).ToPaged();

        /// <summary>
        /// 查询分机组
        /// </summary>
        [HttpGet("groups")]
        public Task<IReadOnlyList<TelGroupDto>> QueryTelGroups()
            => _callApplication.QueryTelGroupsAsync(HttpContext.RequestAborted);

        #region 黑名单

        //Task<string> AddBlackListAsync(AddBlacklistDto dto, CancellationToken cancellationToken);
        //Task RemoveBlackListAsync(string id, CancellationToken cancellationToken);
        //Task<List<Blacklist>> QueryBlackListsAsync(CancellationToken cancellationToken);

        #endregion

        /// <summary>
        /// 签入
        /// </summary>
        [HttpPost("signin")]
        public Task<TrOnDutyResponseDto> SignIn([FromBody] SignInDto dto)
            => _callApplication.SignInAsync(dto, HttpContext.RequestAborted);

        /// <summary>
        /// 签出
        /// </summary>
        [HttpPost("signout")]
        public Task SignOut()
            => _callApplication.SingOutAsync(HttpContext.RequestAborted);

        /// <summary>
        /// 签出
        /// </summary>
        [HttpPost("signout/{telNo}")]
        public Task SignOut(string telNo)
            => _callApplication.SingOutAsync(telNo, HttpContext.RequestAborted);

        /// <summary>
        /// 查询当前用户的分机状态
        /// </summary>
        /// <returns></returns>
        [HttpGet("tel-state")]
        public Task<TrOnDutyResponseDto> GetTelState()
            => _callApplication.GetTelStateAsync(HttpContext.RequestAborted);

        /// <summary>
        /// 查询通话记录（固定数据量）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("calls-fixed")]
        public Task<IReadOnlyList<CallNativeDto>> QueryCallsFixed([FromQuery] QueryCallsFixedDto dto)
            => _callApplication.QueryCallsFixedAsync(dto, HttpContext.RequestAborted);

        /// <summary>
        /// 查询通话记录
        /// </summary>
        /// <param name="callId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        [HttpGet("{callId}")]
        public Task<List<CallNative>> GetCall(string callId)
        {
            //为兼容天润通话记录返回集合
            if (string.IsNullOrEmpty(callId)) return default;
            return _callApplication.GetCallListAsync(callId, HttpContext.RequestAborted);
        }

        /// <summary>
        /// 通话记录基础数据
        /// </summary>
        /// <returns></returns>
        [HttpGet("base-data")]
        public object BaseData()
        {
            return new
            {
                Direction = EnumExts.GetDescriptions<ECallDirection>(),
                EndBy = EnumExts.GetDescriptions<EEndBy>(),
            };
        }

        /// <summary>
        /// 查询坐席操作记录(固定数据量)
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet("tel-operations-fixed")]
        public Task<IReadOnlyList<TelOperation>> QueryTelOperationsFixed([FromQuery] QueryTelOperationsFixedDto dto) => 
            _callApplication.QueryTelOperationsAsync(dto, HttpContext.RequestAborted);

        /// <summary>
        /// 查询坐席操作记录基础数据
        /// </summary>
        [HttpGet("base-data-tel-operation")]
        public object BaseDataTelOperation()
        {
            return new
            {
                Operations = _callApplication.GetTelOperationOptions()
            };
        }



        /// <summary>
        /// 通话转写
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("calls/transliteration")]
        public async Task CallTransliteration([FromBody] CallTransliteration dto)
        {
	        foreach (var id in dto.Ids)
	        {
				var call = await _callApplication.GetTianrunCallAsync(id, HttpContext.RequestAborted);
				if (call is null)
					throw UserFriendlyException.SameMessage("通话信息错误");
				if (call.TransliterationState == ECallTransliterationState.Underway)
					throw UserFriendlyException.SameMessage("正在转写中,请勿重复点击，请稍作等待");
				if (call.TransliterationState == ECallTransliterationState.Succeed)
					throw UserFriendlyException.SameMessage("转写成功，不能重新转写");
				call.InitTransliterationId();
				await _callApplication.EditTransliterationStateAsync(call.Id, ECallTransliterationState.Underway, call.TransliterationId, HttpContext.RequestAborted);
				var audioFile = call.RecordingAbsolutePath;
				var fromNo = call.CPN;
				var callStartTime = call.CreatedTime;
				var Id = call.TransliterationId;
				var setting = _systemSettingCacheManager.GetSetting(SettingConstants.ViteRecordPrefix);



				var handler = new AiQualityHandler()
				{
					Id = Id,
					Source = "AiAnswered",
					AudioFile = audioFile,
					FromNo = fromNo,
					CallStartTime = callStartTime,
					ViteRecordPrefix = setting?.SettingValue[0],
				};
				await _publisher.PublishAsync(new AiOrderQualityNotify(handler), PublishStrategy.ParallelNoWait, HttpContext.RequestAborted);
			}
        }
	}
}
