using AutoMapper;
using Kean.Domain.Stock.Commands;
using Kean.Domain.Stock.Models;
using Kean.Domain.Stock.Repositories;
using Kean.Domain.Stock.SharedServices.Proxies;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Kean.Domain.Stock.CommandHandlers
{
    /// <summary>
    /// 命令处理程序
    /// </summary>
    public sealed class PreScanInboundCommandHandler : CommandHandler<PreScanInboundCommand>
    {
        private readonly ICommandBus _commandBus; // 命令总线
        private readonly INotification _notifications; // 总线通知
        private readonly IMapper _mapper; // 模型映射
        private readonly Kean.Infrastructure.Configuration.BarcodeInterpreter _barcodeInterpreter; // 条码解释器
        private readonly IStockRepository _stockRepository; // 存储仓库
        private readonly MaterialProxy _materialProxy; // 物料服务
        private readonly IWarehouseRepository _warehouseRepository; // 库房仓库

        /// <summary>
        /// 依赖注入
        /// </summary>
        public PreScanInboundCommandHandler(
            ICommandBus commandBus,
            INotification notifications,
            IMapper mapper,
            Kean.Infrastructure.Configuration.BarcodeInterpreter barcodeInterpreter,
            MaterialProxy materialProxy,
            IWarehouseRepository warehouseRepository,
            IStockRepository stockRepository)
        {
            _commandBus = commandBus;
            _notifications = notifications;
            _mapper = mapper;
            _barcodeInterpreter = barcodeInterpreter;
            _materialProxy = materialProxy;
            _warehouseRepository = warehouseRepository;
            _stockRepository = stockRepository;
        }

        /// <summary>
        /// 处理程序
        /// </summary>
        public override async Task Handle(PreScanInboundCommand command, CancellationToken cancellationToken)
        {
            if (command.ValidationResult.IsValid)
            {
                string operation = "";
                ScanInboundCommand scanInboundCommand = new ScanInboundCommand();

                scanInboundCommand.Operator = command.Operator;
                scanInboundCommand.RequestNo = command.RequestNo;
                scanInboundCommand.Barcode = command.Barcode;
                scanInboundCommand.Full = (command.Batchs.Count() == 2);
                scanInboundCommand.Destination = Convert.ToInt32(command.Source);
                scanInboundCommand.Tag = command.Tag;

                List<StockLine> lines = new List<StockLine>();
                if (command.Batchs.Count() == 0)
                {
                    if (!string.IsNullOrEmpty(command.Tag))
                    {
                        JObject jObj = JObject.Parse(command.Tag);

                        JToken bypassArea = jObj.SelectToken("BypassArea");
                        if (bypassArea != null)
                        {
                            StockLine line = new StockLine();

                            line.Quantity = 1;
                            //本地库存 1-本地 2-联机
                            line.IsLocal = "1";
                            //line.Supplier = "ok";
                            line.Enabled = true;

                            if (command.Barcode.StartsWith("W1JPB"))
                            {
                                line.Material = 19;
                            }
                            else
                            {
                                line.Material = 18;
                            }

                            line.Bill = System.DateTime.Now.ToString("yyyyMMddHHmmss");

                            lines.Add(line);

                            operation = "scanInbound";
                        }
                        else
                        {
                            await _commandBus.Notify("batchs", $"产品信息不能为空。", "batchs", cancellationToken: cancellationToken);
                            return;
                        }
                    }
                    else
                    {
                        await _commandBus.Notify("batchs", $"产品信息不能为空", "batchs", cancellationToken: cancellationToken);
                        return;
                    }


                }
                else
                {
                    operation = "scanInbound";

                    string goodsCode = "";
                    string batch = "";
                    string orderNo = "";

                    foreach (Batch b in command.Batchs)
                    {
                        if (string.IsNullOrEmpty(b.serialno))
                        {
                            await _commandBus.Notify(nameof(b.serialno), $"膜卷码({b.serialno})不能为空", b.serialno, cancellationToken: cancellationToken);
                            break;
                        }

                        var sGoods = await _materialProxy.GetMaterial(null, b.materialCode, false);
                        Models.Material goods = JsonConvert.DeserializeObject<Models.Material>(sGoods);
                        if (goods == null)
                        {
                            //@=@ 固定值 goodsClass
                            int category = 0;
                            try
                            {
                                if (b.serialno.Substring(2, 3) == "AMQ")
                                {
                                    category = 3;
                                }
                                if (b.serialno.Substring(2, 3) == "CMQ")
                                {
                                    category = 2;
                                }
                            }
                            catch { }

                            if (category == 0)
                            {
                                if (b.materialName.Contains("阴"))
                                {
                                    category = 2;
                                }
                                else if (b.materialName.Contains("阳"))
                                {
                                    category = 3;
                                }
                            }

                            if (category == 0)
                            {
                                if (command.Barcode.StartsWith("W1JPB"))
                                {
                                    category = 3;
                                }
                                if (command.Barcode.StartsWith("W1JPA"))
                                {
                                    category = 2;
                                }
                            }

                            if (category == 0)
                            {
                                await _commandBus.Notify("materialCode", $"物料编码({b.materialCode}),无法解析。", b.materialCode, cancellationToken: cancellationToken);
                                return;
                            }


                            //新建主物料信息
                            await this._materialProxy.CreateGoods(category, "1", b.materialCode, $"{b.materialCode}{b.materialName}");

                            sGoods = await _materialProxy.GetMaterial(null, b.materialCode, false);
                            goods = JsonConvert.DeserializeObject<Models.Material>(sGoods);
                            if (goods == null)
                            {
                                await _commandBus.Notify("materialCode", $"物料编码({b.materialCode}),无法解析。", b.materialCode, cancellationToken: cancellationToken);
                                return;
                            }
                        }

                        if (string.IsNullOrEmpty(goodsCode))
                        {
                            goodsCode = goods.Code;
                        }
                        else if (goodsCode!=goods.Code)
                        {
                            await _commandBus.Notify(nameof(b.serialno), $"膜卷物料不相同,不能放到一个托盘。{goodsCode}-{goods.Code}", b.serialno, cancellationToken: cancellationToken);
                            break;
                        }

                        if (string.IsNullOrEmpty(batch))
                        {
                            batch = b.serialno.Split('-')[0];
                        }
                        //else if (batch != sfc.Split('-')[0])
                        //{
                        //    await _commandBus.Notify(nameof(sfc), $"膜卷批次码不相同,不能放到一个托盘。{batch}-{sfc.Split('-')[0]}", sfc, cancellationToken: cancellationToken);
                        //    break;
                        //}

                        //if (string.IsNullOrEmpty(orderNo))
                        //{
                        //    orderNo = b.workOrderNo;
                        //}
                        //else if (orderNo != b.workOrderNo)
                        //{
                        //    await _commandBus.Notify(nameof(orderNo), $"膜卷的工单号不相同,不能放到一个托盘。{orderNo}-{b.workOrderNo}", orderNo, cancellationToken: cancellationToken);
                        //    break;
                        //}

                        StockLine line = new StockLine();

                        line.Quantity = 1;
                        //本地库存 1-本地 2-联机
                        line.IsLocal = "2";
                        //line.Supplier = "unupload";
                        line.Enabled = true;

                        line.Postuser = command.Postuser;
                        line.Remark = command.Remark;
                        line.Material = goods.Id;
                        //line.IsWms = production.data.is_WMS;

                        line.Bill = b.serialno;
                        line.Batch = b.serialno.Split('-')[0];
                        line.MesUnit = b.unit;
                        line.QualifiedNum = b.quantity;
                        try
                        {
                            Convert.ToDecimal(b.quantity);
                        }
                        catch
                        {
                            await _commandBus.Notify(nameof(b.quantity), $"EA数量({b.quantity})不对,请检查", b.quantity, cancellationToken: cancellationToken);
                            break;
                        }
                        line.WorkorderNo = b.workOrderNo;
                        try
                        {
                            line.ManufacturingDate = Convert.ToDateTime(b.productDate);
                        }
                        catch
                        {
                            await _commandBus.Notify(nameof(b.productDate), $"生产时间值({b.productDate})不对,请检查", b.productDate, cancellationToken: cancellationToken);
                            break;
                        }
                        line.IsAgv = b.qualityState;
                        if (b.materialType == "0")
                        {
                            line.QualityState = "ok";
                        }
                        else if (b.materialType == "1")
                        {
                            line.QualityState = "check";
                        }
                        else if (b.materialType == "2")
                        {
                            line.QualityState = "ng";
                        }
                        else
                        {
                            line.QualityState = b.materialType;
                        }
                        //else if (b.materialType == "N1")
                        //{
                        //    line.QualityState = "N1";
                        //}
                        //else if (b.materialType == "N2")
                        //{
                        //    line.QualityState = "N2";
                        //}
                        //else if (b.materialType == "N3")
                        //{
                        //    line.QualityState = "N3";
                        //}
                        //else if (b.materialType == "N4")
                        //{
                        //    line.QualityState = "N4";
                        //}
                        //else if (b.materialType == "N5")
                        //{
                        //    line.QualityState = "N5";
                        //}
                        //else if (b.materialType == "N6")
                        //{
                        //    line.QualityState = "N6";
                        //}
                        //else if (b.materialType == "N7")
                        //{
                        //    line.QualityState = "N7";
                        //}
                        //else
                        //{
                        //    await _commandBus.Notify(nameof(b.materialType), $"物料类型({b.materialType})未定义,请检查", b.materialType, cancellationToken: cancellationToken);
                        //    break;
                        //}
                        line.LineCode = b.productBatchNo;
                        line.LineName = b.sapBatchNo;
                        line.UploadNum = JsonConvert.SerializeObject(new
                        {
                            mouldNo = b.mouldNo,
                            maturity = b.maturity,
                            expDate = b.expDate
                        });


                        if (System.DateTime.Now.AddDays(-6) > line.ManufacturingDate.Value)
                        {
                            if (!string.IsNullOrEmpty(command.Tag))
                            {
                                JObject jObj = JObject.Parse(command.Tag);

                                JToken bypassArea = jObj.SelectToken("BypassArea");
                                if (bypassArea != null)
                                {
                                }
                                else
                                {
                                    await _commandBus.Notify(nameof(b.productDate), $"生产日期({b.productDate})超期(大于6天),不能自动入库。请联系生产管理者。", b.productDate, cancellationToken: cancellationToken);
                                    break;
                                }
                            }
                            else
                            {
                                await _commandBus.Notify(nameof(b.productDate), $"生产日期({b.productDate})超期(大于6天),不能自动入库。请联系生产管理者。", b.productDate, cancellationToken: cancellationToken);
                                break;
                            }


                        }

                        lines.Add(line);
                    }
                }

                if (!_notifications.Any())
                {
                    scanInboundCommand.Lines = lines;

                    switch (operation)
                    {
                        case "palletIn":
                            var palletInCommand = _mapper.Map<PalletInCommand>(scanInboundCommand);
                            await _commandBus.Execute(palletInCommand, cancellationToken);
                            Output(nameof(command.Source), palletInCommand.Tag);
                            break;
                        case "scanInbound":
                            await _commandBus.Execute(scanInboundCommand, cancellationToken);
                            Output(nameof(command.Source), scanInboundCommand.Tag);
                            break;
                    }
                }
            }
            else
            {
                await _commandBus.Notify(command.ValidationResult,
                    cancellationToken: cancellationToken);
            }
        }
    }
}