using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hotline.Caching.Interfaces;
using Microsoft.Extensions.Logging;
using Hotline.Repository.SqlSugar;
using SqlSugar;
using XingTang.Sdk;
using Hotline.CallCenter.Calls;
using Hotline.CallCenter.Tels;
using MapsterMapper;
using Hotline.Users;
using XF.Domain.Repository;
using Hotline.Share.Tools;
using Mapster;

namespace Hotline.Application.Jobs
{
    public class XingTangTelOperationSyncJob : IJob, IDisposable
    {
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<TelOperation> _telOperationRepository;
        private readonly IUserCacheManager _userCacheManager;
        private readonly IMapper _mapper;
        private readonly ILogger<XingTangTelOperationSyncJob> _logger;
        private readonly ISqlSugarClient _db;

        public XingTangTelOperationSyncJob(
            ISugarUnitOfWork<XingTangDbContext> uow,
            IRepository<User> userRepository,
            IRepository<TelOperation> telOperationRepository,
            IUserCacheManager userCacheManager,
            IMapper mapper,
            ILogger<XingTangTelOperationSyncJob> logger)
        {
            _db = uow.Db;
            _userRepository = userRepository;
            _telOperationRepository = telOperationRepository;
            _userCacheManager = userCacheManager;
            _mapper = mapper;
            _logger = logger;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            var xingtangOperations = await _db.Queryable<XingtangSeatOperation>()
                 .Where(d => (d.IsSync == null || !d.IsSync) && (d.Tries == null || d.Tries <= 20))
                 .Take(50)
                 .ToListAsync(context.CancellationToken);

            var occupyOperations = new List<XingtangSeatOperation>();
            foreach (var operation in xingtangOperations)
            {
                operation.IsSync = true;
                operation.Tries += 1;

                var rows = await _db.Updateable(operation)
                    .ExecuteCommandWithOptLockAsync();
                if (rows > 0)
                    occupyOperations.Add(operation);
            }

            try
            {
                if (occupyOperations.Any(m => m.UserData.IsNullOrEmpty() == true))
                {
                    var operations = _mapper.Map<List<TelOperation>>(occupyOperations);
                    //填充user信息
                    var staffNos = operations
                        .Where(d => !string.IsNullOrEmpty(d.StaffNo) && d.StaffNo != "0")
                        .Select(d => d.StaffNo).ToList();
                    var users = await _userRepository.Queryable()
                        .Where(d => staffNos.Contains(d.StaffNo))
                        .ToListAsync(context.CancellationToken);

                    foreach (var operation in operations)
                    {
                        var user = users.FirstOrDefault(d => d.StaffNo == operation.StaffNo);
                        if (user is not null)
                        {
                            operation.UserId = user.Id;
                            operation.UserName = user.Name;
                            var work = _userCacheManager.GetWorkByUserNoExp(user.Id);
                            if (work is not null)
                                operation.GroupId = work.QueueId;
                        }

                    }
                    await _telOperationRepository.AddRangeAsync(operations, context.CancellationToken);
                    //_logger.LogInformation($"旧方法同步分机操作记录成功，数量：{operations.Count}");
                }
                else
                {
                    var operations = new List<TelOperation>();
                    foreach (var occupyOperation in occupyOperations)
                    {
                        var operation = occupyOperation.Adapt<TelOperation>();
                        var userSplit = occupyOperation.UserData.Split(':');
                        operation.UserId = userSplit[0];
                        operation.UserName = userSplit[1];
                        var work = _userCacheManager.GetWorkByUserNoExp(operation.UserId);
                        if (work is not null)
                            operation.GroupId = work.QueueId;

                        operations.Add(operation);
                    }
                    await _telOperationRepository.AddRangeAsync(operations, context.CancellationToken);
                    //_logger.LogInformation($"新方法同步分机操作记录成功，数量：{operations.Count}");
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"获取分机操作记录异常：{e.Message} \n {e.StackTrace}");
                foreach (var occupyOperation in occupyOperations)
                {
                    occupyOperation.IsSync = false;
                }

                await _db.Updateable(occupyOperations)
                    .UpdateColumns(d => new { d.IsSync })
                    .ExecuteCommandAsync(context.CancellationToken);
            }
        }

        /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
        public void Dispose()
        {
            //_logger.LogInformation($"{nameof(XingTangTelOperationSyncJob)} disposed");
        }
    }
}
