using System;
using System.Linq;
using Infrastructure;
using WebRepository;

namespace WebApp
{
    /// <summary>
    /// 出库单下发接口App
    /// </summary>

    public partial class IShipmentApp : ApiApp
    {
        public IRepository<ShipmentHeader> _app;
        public IShipmentApp(IUnitWork unitWork, IAuth auth, BaseDBContext context, IRepository<ShipmentHeader> shipmentHeader) : base(unitWork, auth, context)
        {
            _app = shipmentHeader;
        }

        public string InsertShipment(IShipmentModel shipments)
        {
            Response Response = new Response();

            if (!CheckLogin())
            {
                Response.Code = 500;
                Response.Status = false;
                Response.Message = "请先登录!";
                return JsonHelper.Instance.Serialize(Response);
            }
            using (var tran = _context.Database.BeginTransaction())
            {
                try
                {
                    #region 保存出库单接口主表
                    IshipmentHeader headdata = _unitWork.FindSingle<IshipmentHeader>(u => u.SourceCode.Equals(shipments.shipmentHeader.SourceCode));
                    shipments.shipmentHeader.ReceiveTime = DateTime.Now;
                    shipments.shipmentHeader.Id = headdata?.Id;
                    if (shipments.shipmentHeader.Id == null)
                    {
                        if (shipments.shipmentHeader.CreateBy == null)
                        {
                            shipments.shipmentHeader.CreateBy = "wms";
                            shipments.shipmentHeader.CreateTime = DateTime.Now;
                        }
                        _unitWork.Add(shipments.shipmentHeader);
                    }
                    else
                    {
                        if (shipments.shipmentHeader.UpdateBy == null)
                        {
                            shipments.shipmentHeader.UpdateBy = "wms";
                            shipments.shipmentHeader.UpdateTime = DateTime.Now;
                        }
                        _unitWork.Update(shipments.shipmentHeader);
                    }
                    #endregion

                    #region 保存出库单主表
                    ShipmentHeader shipmentHeader = _unitWork.FindSingle<ShipmentHeader>(u => u.SourceCode.Equals(shipments.shipmentHeader.SourceCode));
                    if (shipmentHeader != null)
                    {
                        if (shipmentHeader.FirstStatus != ShipmentHeaderStatus.新建)
                        {
                            throw new Exception("单据进入订单池后,不允许修改!");
                        }
                    }
                    else
                    {
                        shipmentHeader = new ShipmentHeader();
                    }

                    shipmentHeader.Type = shipments.shipmentHeader.Type;
                    shipmentHeader.SourceCode = shipments.shipmentHeader.SourceCode;
                    shipmentHeader.WarehouseType = shipments.shipmentHeader.WarehouseType;

                    shipmentHeader.Priority = (shipments.shipmentHeader.Priority == null ? 0 : shipments.shipmentHeader.Priority);
                    shipmentHeader.Station = shipments.shipmentHeader.Station;
                    shipmentHeader.CreateTime = shipments.shipmentHeader.CreateTime;
                    shipmentHeader.CreateBy = shipments.shipmentHeader.CreateBy;
                    shipmentHeader.UpdateTime = shipments.shipmentHeader.UpdateTime;
                    shipmentHeader.UpdateBy = shipments.shipmentHeader.UpdateBy;

                    shipmentHeader.Code = string.IsNullOrEmpty(shipmentHeader.Code) ? _unitWork.GetTaskNo(shipments.shipmentHeader.Type) : shipmentHeader.Code;
                    shipmentHeader.UploadStatus = 0;
                    shipmentHeader.FirstStatus = ShipmentHeaderStatus.新建;
                    shipmentHeader.LastStatus = ShipmentHeaderStatus.新建;
                    shipmentHeader.TotalLines = 0;
                    shipmentHeader.TotalQty = 0;

                    if (shipmentHeader.Id == null)
                    {
                        if (shipmentHeader.CreateBy == null)
                        {
                            shipmentHeader.CreateBy = "wms";
                            shipmentHeader.CreateTime = DateTime.Now;
                        }
                        _unitWork.Add(shipmentHeader);
                    }
                    else
                    {
                        if (shipmentHeader.UpdateBy == null)
                        {
                            shipmentHeader.UpdateBy = "wms";
                            shipmentHeader.UpdateTime = DateTime.Now;
                        }
                        _unitWork.Update(shipmentHeader);
                    }
                    #endregion

                    short? totalLines = 0;
                    decimal? qty = 0;
                    foreach (var item in shipments.shipmentDetails)
                    {
                        try
                        {
                            #region 保存出库单接口子表
                            IshipmentDetail data = _context.Set<IshipmentDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            item.ReceiveTime = DateTime.Now;
                            item.Id = data?.Id;

                            if (item.Id == null)
                            {
                                if (item.CreateBy == null)
                                {
                                    item.CreateBy = "wms";
                                    item.CreateTime = DateTime.Now;
                                }
                                _unitWork.Add(item);
                            }
                            else
                            {
                                if (item.UpdateBy == null)
                                {
                                    item.UpdateBy = "wms";
                                    item.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(item);
                            }
                            #endregion

                            #region 保存出库单子表
                            ShipmentDetail shipmentDetail = _context.Set<ShipmentDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            if (shipmentDetail == null)
                            {
                                shipmentDetail = new ShipmentDetail();
                            }

                            shipmentDetail.SourceCode = item.SourceCode;
                            shipmentDetail.MaterialCode = item.MaterialCode;
                            shipmentDetail.Lot = item.Lot;
                            shipmentDetail.InventoryStatus = item.InventoryStatus;
                            shipmentDetail.Qty = item.Qty;
                            shipmentDetail.CreateTime = item.CreateTime;
                            shipmentDetail.CreateBy = item.CreateBy;
                            shipmentDetail.UpdateTime = item.UpdateTime;
                            shipmentDetail.UpdateBy = item.UpdateBy;

                            shipmentDetail.ShipmentId = shipmentHeader.Id;
                            shipmentDetail.ShipmentCode = shipmentHeader.Code;
                            shipmentDetail.QtyDivided = 0;
                            shipmentDetail.QtyCompleted = 0;
                            shipmentDetail.Price = 0;
                            shipmentDetail.Status = ShipmentHeaderStatus.新建;

                            //成品库逻辑
                            var con = (from c in _unitWork.Find<Container>(n => n.IsLock == 0)
                                       join i in _unitWork.Find<Inventory>(n => n.MaterialCode == item.MaterialCode && n.TaskStatus == InventoryTaskType.无盘点任务)
                                       on c.Code equals i.ContainerCode
                                       select c).FirstOrDefault();
                            if (con != null)
                            {
                                if (con.Type == ContainerType.木栈板母板_1 || con.Type == ContainerType.木栈板母板_2)
                                {
                                    Station st = _unitWork.Find<Station>(n => n.Type == StationType.木板补给终点站台).FirstOrDefault();
                                    Station stdel = _unitWork.Find<Station>(n => n.Type == (con.Type == ContainerType.木栈板母板_1 ? StationType.木栈板母板补给站台s_1 : StationType.木栈板母板补给站台s_2)).FirstOrDefault();
                                    //判断“木板补给终点站台”是否有容器 如果有则判断“木栈板母板补给站台”是否有容器
                                    if (st.Containercode == "")
                                    {
                                        //如果没有容器则直接出库
                                        if (stdel.Containercode == "")
                                        {
                                            //建立容器出库任务
                                            if (!_unitWork.IsExist<TaskDetail>(n => (n.Status >= TaskStatus.新建任务 && n.Status < TaskStatus.已经完成) && n.MaterialCode == shipmentDetail.MaterialCode && n.OrderCode == shipmentDetail.ShipmentCode))
                                            {
                                                int ptdcount = _unitWork.Find<TaskDetail>(n => (n.Status >= TaskStatus.新建任务 && n.Status < TaskStatus.已经完成) && n.ContainerCode == con.Code && n.TaskType == TaskType.容器出库).Count();
                                                if (ptdcount < 1)
                                                {
                                                    Task ptask = new Task();
                                                    TaskDetail ptaskDetail = new TaskDetail();
                                                    var taskNo = _app.GetTaskNo(TaskNo.空板补充);
                                                    ptask.TaskNo = taskNo;
                                                    ptask.OrderCode = taskNo;
                                                    ptask.BusinessType = BusinessType.出库_其他出库单;
                                                    ptask.FirstStatus = TaskStatus.待下发任务;
                                                    ptask.LastStatus = TaskStatus.待下发任务;
                                                    _unitWork.Add(ptask);

                                                    ptaskDetail.TaskNo = taskNo;
                                                    ptaskDetail.OrderCode = taskNo;
                                                    ptaskDetail.TaskType = TaskType.空容器出库;
                                                    ptaskDetail.ContainerCode = con.Code;
                                                    ptaskDetail.SourceLocation = con.LocationCode;
                                                    if (con.Type == ContainerType.木栈板母板_1)
                                                    {
                                                        ptaskDetail.DestinationLocation = _unitWork.Find<Station>(n => n.Type == StationType.木栈板母板补给站台s_1).FirstOrDefault().Code;
                                                    }
                                                    else
                                                    {
                                                        ptaskDetail.DestinationLocation = _unitWork.Find<Station>(n => n.Type == StationType.木栈板母板补给站台s_2).FirstOrDefault().Code;
                                                    }
                                                    ptaskDetail.Station = ptaskDetail.DestinationLocation;
                                                    ptaskDetail.OderQty = 0;
                                                    ptaskDetail.ContainerQty = 0;
                                                    ptaskDetail.HadQty = 0;
                                                    ptaskDetail.Roadway = _unitWork.Find<Location>(n => n.ContainerCode == con.Code).FirstOrDefault().Roadway;
                                                    ptaskDetail.Status = TaskStatus.待下发任务;
                                                    ptaskDetail.Priority = 0;
                                                    _unitWork.Add(ptaskDetail);
                                                    Inventory inventory = _unitWork.Find<Inventory>(n => n.ContainerCode == con.Code && n.MaterialCode == item.MaterialCode).FirstOrDefault();
                                                    inventory.Qty -= 1;
                                                    _unitWork.Update(inventory);
                                                    st.Containercode = con.Code;
                                                    _unitWork.Update(st);
                                                    Location Location = _unitWork.Find<Location>(n => n.ContainerCode == con.Code).FirstOrDefault();
                                                    Location.IsStop = true;
                                                    _unitWork.Update(Location);
                                                    Container Container = _unitWork.Find<Container>(n => n.Code == con.Code).FirstOrDefault();
                                                    Container.IsLock = 1;
                                                    _unitWork.Update(Container);
                                                    stdel.Containercode = con.Code;
                                                    _unitWork.Update(stdel);
                                                    shipmentDetail.Status = ShipmentHeaderStatus.回传;
                                                }
                                            }
                                            else
                                            {
                                                Response.Code = 500;
                                                Response.Status = false;
                                                Response.Message = con.Code + "托盘已有任务!";
                                                return JsonHelper.Instance.Serialize(Response);
                                            }
                                        }
                                        else
                                        {
                                            Inventory inv = _unitWork.Find<Inventory>(n => n.ContainerCode == stdel.Containercode && n.MaterialCode == item.MaterialCode).FirstOrDefault();
                                            //如果有容器则判断该容器上的木栈板是否符合 符合则直接点对点出 不符合则回库 等回库完成再出
                                            if (inv != null)
                                            {
                                                //建立容器出库任务
                                                if (!_unitWork.IsExist<TaskDetail>(n => (n.Status >= TaskStatus.新建任务 && n.Status < TaskStatus.已经完成) && n.MaterialCode == shipmentDetail.MaterialCode && n.OrderCode == shipmentDetail.ShipmentCode))
                                                {
                                                    int ptdcount = _unitWork.Find<TaskDetail>(n => (n.Status >= TaskStatus.新建任务 && n.Status < TaskStatus.已经完成) && n.ContainerCode == con.Code && n.TaskType == TaskType.容器出库).Count();
                                                    if (ptdcount < 1)
                                                    {
                                                        Task ptask = new Task();
                                                        TaskDetail ptaskDetail = new TaskDetail();
                                                        var taskNo = _app.GetTaskNo(TaskNo.空板补充);
                                                        ptask.TaskNo = taskNo;
                                                        ptask.OrderCode = taskNo;
                                                        ptask.BusinessType = BusinessType.出库_其他出库单;
                                                        ptask.FirstStatus = TaskStatus.待下发任务;
                                                        ptask.LastStatus = TaskStatus.待下发任务;
                                                        _unitWork.Add(ptask);

                                                        ptaskDetail.TaskNo = taskNo;
                                                        ptaskDetail.OrderCode = taskNo;
                                                        ptaskDetail.TaskType = TaskType.空容器出库;
                                                        ptaskDetail.ContainerCode = stdel.Containercode;
                                                        ptaskDetail.SourceLocation = stdel.Code;
                                                        ptaskDetail.DestinationLocation = _unitWork.Find<Station>(n => n.Type == StationType.木板补给终点站台).FirstOrDefault().Code;
                                                        ptaskDetail.Station = ptaskDetail.DestinationLocation;
                                                        ptaskDetail.OderQty = 0;
                                                        ptaskDetail.ContainerQty = 0;
                                                        ptaskDetail.HadQty = 0;
                                                        ptaskDetail.Roadway = 0;
                                                        ptaskDetail.Status = TaskStatus.待下发任务;
                                                        ptaskDetail.Priority = 0;
                                                        _unitWork.Add(ptaskDetail);
                                                        inv.Qty -= 1;
                                                        _unitWork.Update(inv);
                                                        st.Containercode = con.Code;
                                                        _unitWork.Update(st);
                                                        shipmentDetail.Status = ShipmentHeaderStatus.回传;
                                                    }
                                                }
                                                else
                                                {
                                                    Response.Code = 500;
                                                    Response.Status = false;
                                                    Response.Message = con.Code + "托盘已有任务!";
                                                    return JsonHelper.Instance.Serialize(Response);
                                                }
                                            }
                                            else
                                            {
                                                //空栈板回库逻辑待优化
                                                Task ptask = new Task();
                                                TaskDetail ptaskDetail = new TaskDetail();
                                                var taskNo = _app.GetTaskNo(TaskNo.容器回库);
                                                ptask.TaskNo = taskNo;
                                                ptask.OrderCode = taskNo;
                                                ptask.BusinessType = BusinessType.入库_其他入库单;
                                                ptask.FirstStatus = TaskStatus.待下发任务;
                                                ptask.LastStatus = TaskStatus.待下发任务;
                                                _unitWork.Add(ptask);

                                                ptaskDetail.TaskNo = taskNo;
                                                ptaskDetail.OrderCode = shipmentDetail.ShipmentCode;
                                                ptaskDetail.TaskType = TaskType.空容器入库;
                                                ptaskDetail.ContainerCode = stdel.Containercode;
                                                ptaskDetail.SourceLocation = stdel.Code;
                                                ptaskDetail.DestinationLocation = _unitWork.Find<Location>(n => n.Status == LocationStatus.空仓位).FirstOrDefault().Code;
                                                ptaskDetail.Station = stdel.Code;
                                                ptaskDetail.OderQty = 0;
                                                ptaskDetail.ContainerQty = 0;
                                                ptaskDetail.HadQty = 0;
                                                ptaskDetail.Roadway = 0;
                                                ptaskDetail.Status = TaskStatus.待下发任务;
                                                ptaskDetail.Priority = 0;
                                                _unitWork.Add(ptaskDetail);
                                                shipmentDetail.Status = ShipmentHeaderStatus.分配完成;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Response.Code = 500;
                                        Response.Status = false;
                                        Response.Message = "请将" + st.Containercode + "托盘入库!";
                                        return JsonHelper.Instance.Serialize(Response);
                                    }
                                }
                            }
                            else
                            {
                                Response.Code = 500;
                                Response.Status = false;
                                Response.Message = "无可用托盘!";
                                return JsonHelper.Instance.Serialize(Response);
                            }


                            if (shipmentDetail.Id == null)
                            {
                                if (shipmentDetail.CreateBy == "")
                                {
                                    shipmentDetail.CreateBy = "wms";
                                    shipmentDetail.CreateTime = DateTime.Now;
                                }
                                _unitWork.Add(shipmentDetail);
                            }
                            else
                            {
                                if (shipmentDetail.UpdateBy == "")
                                {
                                    shipmentDetail.UpdateBy = "wms";
                                    shipmentDetail.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(shipmentDetail);
                            }
                            #endregion

                            totalLines += 1;
                            qty += item.Qty;
                        }
                        catch (Exception ex)
                        {
                            #region 记录出库单接口子表错误信息
                            IshipmentDetail data = _context.Set<IshipmentDetail>().AsQueryable().Where(u => u.SourceCode.Equals(item.SourceCode) && u.MaterialCode.Equals(item.MaterialCode)).SingleOrDefault();
                            if (data != null)
                            {
                                data.ErrorMessage = ex.Message;
                                if (data.UpdateBy == null)
                                {
                                    data.UpdateBy = "wms";
                                    data.UpdateTime = DateTime.Now;
                                }
                                _unitWork.Update(data);
                            }
                            #endregion

                            Response.Code = 500;
                            Response.Status = false;
                            Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "SourceCode:" + item.SourceCode + ",MaterialCode:" + item.MaterialCode + "同步失败:" + ex.Message;
                        }
                    }

                    #region 更新出库单主表汇总信息
                    shipmentHeader.TotalLines += (short)_unitWork.Find<ShipmentDetail>(n => n.ShipmentCode == shipmentHeader.Code).ToList().Count; ;
                    shipmentHeader.TotalQty += _unitWork.Find<ShipmentDetail>(n => n.ShipmentCode == shipmentHeader.Code).Sum(x => x.Qty); ;
                    if (shipmentHeader.UpdateBy == null)
                    {
                        shipmentHeader.UpdateBy = "wms";
                        shipmentHeader.UpdateTime = DateTime.Now;
                    }
                    _unitWork.Update(shipmentHeader);
                    #endregion
                    tran.Commit();
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    #region 记录出库单接口子表错误信息
                    try
                    {
                        IshipmentHeader data = _context.Set<IshipmentHeader>().AsQueryable().Where(u => u.SourceCode.Equals(shipments.shipmentHeader.SourceCode)).SingleOrDefault();
                        if (data != null)
                        {
                            data.ErrorMessage = ex.Message;
                            if (data.UpdateBy == null)
                            {
                                data.UpdateBy = "wms";
                                data.UpdateTime = DateTime.Now;
                            }
                            _unitWork.Update(data);
                        }
                    }
                    catch (Exception)
                    {
                    }
                    #endregion

                    Response.Code = 500;
                    Response.Status = false;
                    Response.Message = (Response.Message == "操作成功" ? "" : Response.Message) + "\r\n" + "同步失败:" + ex.Message;
                }
            }

            return JsonHelper.Instance.Serialize(Response);
        }
    }
}