using AutoMapper;
using Kean.Domain.Task.Commands;
using Kean.Domain.Task.Repositories;
using Kean.Domain.Task.SharedServices.Proxies;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading;

namespace Kean.Domain.Task.CommandHandlers
{
    /// <summary>
    /// 创建下架命令处理程序
    /// </summary>
    public sealed class PreApplyOutCommandHandler : CommandHandler<PreApplyOutCommand>
    {
        private readonly ICommandBus _commandBus; // 命令总线
        private readonly INotification _notifications; // 总线通知
        private readonly IMapper _mapper; // 模型映射
        private readonly MaterialProxy _materialProxy; // 物料服务
        private readonly ITaskRepository _taskRepository; // 任务仓库
        private readonly IWarehouseRepository _warehouseRepository; // 库房仓库


        /// <summary>
        /// 依赖注入
        /// </summary>
        public PreApplyOutCommandHandler(
            ICommandBus commandBus,
            INotification notifications,
            IMapper mapper,
            MaterialProxy materialProxy,
            IWarehouseRepository warehouseRepository,
            ITaskRepository taskRepository)
        {
            _commandBus = commandBus;
            _notifications = notifications;
            _mapper = mapper;
            _materialProxy = materialProxy;
            _taskRepository = taskRepository;
            _warehouseRepository = warehouseRepository;
        }

        /// <summary>
        /// 处理程序
        /// </summary>
        public override async System.Threading.Tasks.Task Handle(PreApplyOutCommand command, CancellationToken cancellationToken)
        {
            if (command.ValidationResult.IsValid)
            {
                // 申请编号验证 任务
                if (await _taskRepository.HasTaskByRequestno(command.RequestNo))
                {
                    await _commandBus.Notify(nameof(command.RequestNo), $"申请编号{command.RequestNo}已经下达任务", command.RequestNo,
                            cancellationToken: cancellationToken);
                    return;
                }

                int qty = 0;
                if (command.Qty == null)
                {
                    await _commandBus.Notify(nameof(command.Qty), $"托盘数量{command.Qty}不能为空", command.Qty,
       cancellationToken: cancellationToken);
                    return;
                }

                try
                {
                    qty = Convert.ToInt32(command.Qty);
                }
                catch
                {
                    await _commandBus.Notify(nameof(command.Qty), $"托盘数量{command.Qty}不是数值", command.Qty,
                           cancellationToken: cancellationToken);
                    return;
                }

                ApplyOutCommand applyoutcommand = new ApplyOutCommand();
                applyoutcommand.RequestNo = command.RequestNo;
                applyoutcommand.Qty = 0;

                applyoutcommand.enable = true;
                //IsLocal 1-本地库存 2-联机库存
                applyoutcommand.IsLocal = "2";
                applyoutcommand.Operator = -4;
                applyoutcommand.Tag = JsonConvert.SerializeObject(new
                {
                    postUser = command.Postuser
                });


                var cache =await _warehouseRepository.GetCacheByCode(command.Target);
                if (cache == null)
                {
                    await _commandBus.Notify(nameof(command.Target), $"目标地址{command.Target}未知,请检查", command.Target, cancellationToken: cancellationToken);
                    return;
                }

                applyoutcommand.Destination = cache.Area;
                applyoutcommand.Priority = 0;
                applyoutcommand.Manual = false;

                List<int> lsGoods = new List<int>();
                List<string> lsCodes = new List<string>();

                var sGoods = await _materialProxy.GetMaterial(null, command.Code, false);
                Models.Material goods = JsonConvert.DeserializeObject<Models.Material>(sGoods);

                if (goods == null)
                {
                    await _commandBus.Notify("Material", $"未找到物料编码({command.Code})信息,请正确输入", command.Code, cancellationToken: cancellationToken);
                    return;
                }

                for (int i=0;i<qty;i++)
                {
                    lsGoods.Add(goods.Id);
                    //lsCodes.Add(command.Batch);
                }

                //@=@ 固定值
                if (goods.Category == 2 || goods.Category == 3)
                {
                    applyoutcommand.Transaction = "ApplyOut";
                }
                if (goods.Category == 5 || goods.Category == 6 || goods.Category == 9)
                {
                    applyoutcommand.Transaction = "PalletOut";
                }

                applyoutcommand.Materials = lsGoods;
                applyoutcommand.Batch = command.Batch;

                await _commandBus.Execute(applyoutcommand, cancellationToken);
                command.Barcode = applyoutcommand.Barcode;
            }
            else
            {
                await _commandBus.Notify(command.ValidationResult,
                    cancellationToken: cancellationToken);
            }
        }
    }
}