using Hotline.CallCenter.Configs;
using Hotline.CallCenter.Devices;
using Hotline.Configurations;
using Hotline.Orders;
using Hotline.Share.Enums.Order;
using Hotline.Share.Requests;
using Hotline.Share.Tools;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using XF.Domain.Dependency;
using static Hotline.AppDefaults;

namespace Hotline.CallCenter.Calls
{
    public class CallDomainService : ICallDomainService, IScopeDependency
    {
        private readonly INewRockDeviceManager _newRockDeviceManager;
        private readonly ICallRepository _callRepository;
        private readonly ICallDetailRepository _callDetailRepository;
        private readonly IOptionsSnapshot<CallCenterConfiguration> _callcenterOptions;
        private readonly IOrderRepository _orderRepository;
        private readonly ICallNativeRepository _callNativeRepository;

        public CallDomainService(
            IServiceProvider serviceProvider,
            ICallRepository callRepository,
            ICallDetailRepository callDetailRepository,
            IOptionsSnapshot<AppConfiguration> appOptions,
            IOptionsSnapshot<CallCenterConfiguration> callcenterOptions,
            IOrderRepository orderRepository,
            ICallNativeRepository callNativeRepository)
        {
            _callRepository = callRepository;
            _callDetailRepository = callDetailRepository;
            _callcenterOptions = callcenterOptions;
            if (appOptions.Value.GetDefaultAppScopeConfiguration().CallCenterType == AppDefaults.CallCenterType.XunShi)
            {
                _newRockDeviceManager = serviceProvider.GetRequiredService<INewRockDeviceManager>();
            }

            _orderRepository = orderRepository;
            _callNativeRepository = callNativeRepository;
        }

        #region 来电

        /// <summary>
        /// 来电转分机
        /// </summary>
        /// <returns></returns>
        public async Task VisitorToTelAsync(VisitorIdToTelRequest request, CancellationToken cancellationToken)
        {
            ////调用设备拨打电话
            //await _newRockDeviceManager.VisitorToExtAsync(request.VisitorId, request.ToExtId, cancellationToken);
            //var model = await _callRepository.GetAsync(x =>
            //    x.CallType == ECallType.VisitorToExt && x.ConversationId == request.VisitorId &&
            //    x.ToNo == request.ToExtId && x.CallStatus != ECallStatus.Bye && x.CallStatus != ECallStatus.Failed, cancellationToken);
            //if (model != null)
            //{
            //    model.CallStatus = ECallStatus.PreIncoming;
            //    model.Modified();
            //    await _callRepository.UpdateAsync(model, cancellationToken);
            //}
            //else
            //{
            //    model = new Call()
            //    {
            //        CallStatus = ECallStatus.PreIncoming,
            //        CallDirection = ECallDirection.In,
            //        ConversationId = request.VisitorId,
            //        CallType = ECallType.VisitorToExt,
            //        ToNo = request.ToExtId,
            //    };
            //    model.Modified();
            //    await _callRepository.AddAsync(model, cancellationToken);
            //}
        }

        /// <summary>
        /// 来电转外线
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task VisitorToOuterAsync(VisitorToOuterRequest request, CancellationToken cancellationToken)
        {
            //调用设备接口转外线
            await _newRockDeviceManager.VisitorToOuterAsync(_callcenterOptions.Value.NewRock, request.VisitorId, request.OuterPhoneNum, cancellationToken);
            //写入数据库通话记录
        }

        /// <summary>
        /// 来电转IVR
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task VisitorToIvrAsync(VisitorToIvrRequest request, CancellationToken cancellationToken)
        {
            //调用设备接口转语音菜单
            await _newRockDeviceManager.VisitorToMenuAsync(_callcenterOptions.Value.NewRock, request.VisitorId, request.MenuId, cancellationToken);
            //写入数据库通话记录
        }

        /// <summary>
        /// 来电转分机组
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task VisitorToTelGroupAsync(VisitorToTelGroupRequest request, CancellationToken cancellationToken)
        {
            await _newRockDeviceManager.VisitorToGroupAsync(_callcenterOptions.Value.NewRock, request.VisitorId, request.GroupId, cancellationToken);
            //写入数据库通话记录
        }

        #endregion

        #region 去电

        /// <summary>
        /// 分机呼外部电话
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task ExtToOuterAsync(ExtToOuterRequest request, CancellationToken cancellationToken)
        {
            //var callModel = new Call()
            //{
            //    CallStatus = ECallStatus.ExtOuterReady,
            //    CallDirection = ECallDirection.Out,
            //    CallType = ECallType.ExtToOuter,
            //    FromNo = request.ExtId,
            //    ToNo = request.OuterPhoneNum,
            //};
            //callModel.Modified();
            //var callId = await _callRepository.AddAsync(callModel, cancellationToken);
            ////写入明细
            //var detail = new CallDetail()
            //{
            //    CallId = callId,
            //    CallStatus = ECallStatus.ExtOuterReady,
            //    EventName = "ExtOuterReady", //去电
            //};
            //await _callDetailRepository.AddAsync(detail, cancellationToken);
            //调用设备拨打电话
            await _newRockDeviceManager.ExtToOuterAsync(_callcenterOptions.Value.NewRock, request.ExtId, request.OuterPhoneNum, cancellationToken);
        }

        #endregion

        #region 来电受理

        /// <summary>
        /// 来电受理
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task AcceptVisitorAsync(AcceptVisitorRequest request, CancellationToken cancellationToken)
        {
            //调用设备受理
            await _newRockDeviceManager.AcceptVisitorAsync(_callcenterOptions.Value.NewRock, request.VisitorId, cancellationToken);
        }

        #endregion

        #region 监听和插播

        /// <summary>
        /// 监听分机
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task MonitorExt(MonitorExtRequest request, CancellationToken cancellationToken)
        {
            await _newRockDeviceManager.MonitorExtAsync(_callcenterOptions.Value.NewRock, request.firstTelNo, request.secondTelNo, cancellationToken);
        }

        /// <summary>
        /// 从监听到插播状态变换
        /// 1. 已知：分机 A 在监听分机 B 与其通话方的通话；
        /// 2. 执行分机 A 的从监听到插播状态变换的 API；
        /// 3. 执行成功时，分机 A 与分机 B 建立通话，分机 B 的原通话方听保持音。
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task MonitorExtToTalk(MonitorExtToTalkRequest request, CancellationToken cancellationToken)
        {
            await _newRockDeviceManager.MonitorExtToTalkAsync(_callcenterOptions.Value.NewRock, request.telNo, cancellationToken);
        }

        /// <summary>
        /// 从插播到监听状态变换
        /// 1. 已知：分机 A 在插播分机 B 的通话；
        /// 2. 执行分机 A 的从插播到监听状态变换的 API；
        /// 3. 执行成功时，分机 A 监听分机 B 及其原通话方的通话。
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task MonitorExtToListen(MonitorExtToListenRequest request, CancellationToken cancellationToken)
        {
            await _newRockDeviceManager.MonitorExtToListenAsync(_callcenterOptions.Value.NewRock, request.telNo, cancellationToken);
        }

        #endregion

        #region 强插

        /// <summary>
        /// 强插
        /// 1. 已知：分机 A 当前空闲，分机 B 正在通话中；
        /// 2. 执行分机 A 强插分机 B 的 API；
        /// 3. 执行成功时，分机 A 振铃，摘机后即可形成三方通话。
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task BargeinExt(BargeinExtRequest request, CancellationToken cancellationToken)
        {
            await _newRockDeviceManager.BargeinExtAsync(_callcenterOptions.Value.NewRock, request.firstTelNo, request.secondTelNo, cancellationToken);
        }

        #endregion


        #region 电话评价

        /// <summary>
        /// 根据OrderId 获取电话评价
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public async Task<CallNative?> GetByOrderIdAsync(string orderId)
        {
            var callId = await _orderRepository.Queryable()
                .Where(m => m.Id == orderId)
                .Select(m => m.CallId)
                .FirstAsync();
            if (callId.IsNullOrEmpty())
                return null;
            return await _callNativeRepository.GetAsync(callId);
        }

        #endregion
    }
}
