using Hotline.Caching.Interfaces;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Tels;
using Hotline.DI;
using Hotline.Realtimes;
using Hotline.Share.Dtos.Realtime;
using Hotline.Share.Enums.CallCenter;
using Hotline.Share.Notifications.NewRockCallCenter;
using MediatR;

namespace Hotline.Application.Handlers.CallCenter.FlowControl
{
    [Injection(EventHandlerType = EEventHandlerType.CallCenter, Label = AppDefaults.CallCenterType.XunShi)]
    public class CdrNotificationHandler : INotificationHandler<CdrNotification>
    {
        private readonly ICallRecordRepository _callRecordRepository;
        private readonly ICallDetailRepository _callDetailRepository;
        private readonly ITelHoldRepository _telHoldRepository;
        private readonly ICallRepository _callRepository;
        private readonly IUserCacheManager _userCacheManager;
        private readonly IRealtimeService _realtimeService;

        public CdrNotificationHandler(ICallRecordRepository callRecordRepository, ICallDetailRepository callDetailRepository, ICallRepository callRepository, ITelHoldRepository telHoldRepository, IUserCacheManager userCacheManager, IRealtimeService realtimeService)
        {
            _callRecordRepository = callRecordRepository;
            _callDetailRepository = callDetailRepository;
            _callRepository = callRepository;
            _telHoldRepository = telHoldRepository;
            _realtimeService = realtimeService;
            _userCacheManager = userCacheManager;
        }

        public async Task Handle(CdrNotification notification, CancellationToken cancellationToken)
        {
            //内部互拨
            if (notification.Type == "LO")
            {
                //获取最后一通内线电话
                //通知前端主叫
                //获取主叫工作信息
                var fromWork = _userCacheManager.GetWorkByTel(notification.CPN);
                if (fromWork != null)
                {
                    await _realtimeService.ByeAsync(fromWork.UserId, new ByeDto() { Id = notification.CPN }, cancellationToken);
                }
                //通知前端被叫
                var toWork = _userCacheManager.GetWorkByTel(notification.CDPN);
                if (toWork != null)
                {
                    await _realtimeService.ByeAsync(toWork.UserId, new ByeDto() { Id = notification.CDPN }, cancellationToken);
                }
            }
            else
            {
                var callDetail = await
                _callDetailRepository.GetAsync(x => x.OMCallId == notification.CallId, true, x => x.CreationTime, cancellationToken);

                if (callDetail != null)
                {
                    var model = new CallRecord()
                    {
                        CallId = callDetail.CallId,
                        CdrId = notification.Id,
                        CDRCallId = notification.CallId,
                        TimeStart = notification.TimeStart,
                        Group = notification.Group,
                        Type = (ECDRType)Enum.Parse(typeof(ECDRType), notification.Type),
                        Route = (ECDRRoute)Enum.Parse(typeof(ECDRRoute), notification.Route),
                        CPN = notification.CPN,
                        CDPN = notification.CDPN,
                        TimeEnd = notification.TimeEnd,
                        Duration = notification.Duration,
                        TrunkNumber = notification.TrunkNumber,
                        Recording = notification.Recording,
                        RecCodec = notification.RecCodec,
                    };
                    if (!string.IsNullOrEmpty(notification.VisitorId))
                        model.VisitorId = notification.VisitorId;

                    if (!string.IsNullOrEmpty(notification.OuterId))
                        model.OuterId = notification.OuterId;

                    await _callRecordRepository.AddAsync(model, cancellationToken);

                    var callModel = await _callRepository.GetAsync(x => x.Id == callDetail.CallId, cancellationToken);
                    if (callModel != null)
                    {
                        callModel.Duration = double.Parse(model.Duration);
                        await _callRepository.UpdateAsync(callModel, cancellationToken);
                    }

                    //处理Hold计算
                    await _telHoldRepository.HandleHoldTime(callDetail.CallId, notification.TimeEnd, cancellationToken);
                }
            }
        }
    }
}
