using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QMFrameWork.Data;
using QMAPP.FJC.DAL.QT;
using QMAPP.FJC.Entity.QT;
using QMAPP.FJC.TRACING.DAInterface;
using QMAPP.FJC.DAL.Produce;
using QMAPP.FJC.DAL.Basic;
using QMAPP.FJC.Entity.Operation;
using QMAPP.FJC.DAL.Operation;
using QMAPP.FJC.Entity.Basic;
using QMAPP.MD.Entity;
using QMAPP.MD.DAL;
using QMAPP.MD.Entity.View;
using WorkCellDAL = QMAPP.MD.DAL.WorkCellDAL;
using QMAPP.FJC.Entity;

namespace QMAPP.FJC.TRACING.StateActions
{
    /// <summary>
    /// 提交数据 上框架真空成型专用
    /// </summary>
    public class SubmitData_4UF:IStateAction
    {
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="data"></param>
        public void Execute(DAObject data)
        {
            

            WorkCellRunStateDAL wcrsdal = new WorkCellRunStateDAL();
            var state = wcrsdal.GetNextState(data.WorkLocState.WORKCELL_CODE, data.WorkLocState.CurrentState.STATE_SEQ);
            bool workcellend = state == null; //如果当前为工序最终状态

            foreach (var processcodeda in data.WorkLocState.DataCache.Where(p => p.ISPROCESSCODE == "1"&&!string.IsNullOrEmpty(p.DA_VALUE)))
            {   
                List<DAICache> dagroup = new List<DAICache>();
                dagroup.Add(processcodeda);
                dagroup.AddRange(data.WorkLocState.DataCache.Where(p => p.ISPROCESSCODE != "1"));

                //搜索确认产品物料号
                SearchMaterial(data,dagroup);

                var product = SaveProduct(data, workcellend,dagroup);
                SaveProcessRecord(product, data, workcellend);
                //List<DAICache> unsavedDai = new List<DAICache>();
                foreach (var dai in dagroup)
                {
                    if (!dai.SAVED.Contains(data.MouldCode) && !string.IsNullOrWhiteSpace(dai.DA_VALUE)) //过滤已保存过的和采集值为空值的
                    {
                        switch (dai.DATA_TYPE)
                        {
                            case "SN": //零件序列号
                            case "BN": //零件批次号
                                {
                                    SaveProductStructure(product, dai, data);
                                    break;
                                }
                            case "MN": //模具编号
                                {
                                    SaveProcessParam(product, dai, data);
                                    break;
                                }
                            case "PARM": //加工参数
                                {
                                    //SaveProcessParam(product,dai,data);
                                    break;
                                }
                        }
                        dai.SAVED = dai.SAVED + data.MouldCode;
                        data.AddToPersistentList(dai, dai.PID);
                    }
                }
                //DAICacheDAL dcdal = new DAICacheDAL();
                //dcdal.Update(unsavedDai, data.DataSession);
            }
        }
        /// <summary>
        /// 搜索确定加工后的产品物料号及加工消耗的物料号
        /// </summary>
        /// <param name="data"></param>
        /// <returns>返回加工消耗物料</returns>
        private string[] SearchMaterial(DAObject data, List<DAICache> dagroup)
        {
            var materials = (from da in dagroup
                             where !string.IsNullOrWhiteSpace(da.MATERIAL_CODE)
                             select da.MATERIAL_CODE).ToArray();
            if (materials.Length == 1) //单一物料加工
            {
                data.WorkLocState.CurrentState.MATERIAL_CODE = materials[0];
                var dai = dagroup.FirstOrDefault(p => p.MATERIAL_CODE == materials[0]);
                data.WorkLocState.CurrentState.PROCESS_CODE = dai.DA_VALUE;
                //data.WorkLocState.CurrentState.PRODUCT_PID = dai.OBJ_PID;
            }
            else //多物料组成
            {
                var bomlocation = GetBomLocation(materials.Distinct().ToArray());
                if (bomlocation == null) //未定位到
                {
                    materials = (from da in dagroup
                                 where !string.IsNullOrWhiteSpace(da.MATERIAL_CODE)
                                       && !string.Equals(da.DA_MODE, "2") //过滤掉可省略的采集点
                                 select da.MATERIAL_CODE).ToArray();
                    bomlocation = GetBomLocation(materials.Distinct().ToArray());
                    if (bomlocation == null) //仍未定位到BOM信息 抛出异常
                    {
                        throw new Exception("采集数据有误,无法确定生产BOM,请检查采集点配置和BOM配置!");
                    }
                }
                string upperlevelmaterial = "";
                if (bomlocation.ItemNo > 0) //如果Bom定位为明细项
                {
                    PbomDAL pbidal = new PbomDAL();
                    var bomitem = pbidal.GetByLocate(bomlocation);
                    if (bomitem != null)
                    {
                        upperlevelmaterial = bomitem.MATERIAL_CODE;
                    }
                }
                else //如果Bom定位为Bom头
                {
                    var bom = new PbomDAL().GetByCode(bomlocation.BOMCode);
                    if (bom != null)
                    {
                        upperlevelmaterial = bom.MATERIAL_CODE;
                    }
                }
                data.WorkLocState.CurrentState.MATERIAL_CODE = upperlevelmaterial; //取得产品物料号
            }
            return materials.Distinct().ToArray();
        }

        /// <summary>
        /// 保存产品组成信息
        /// </summary>
        /// <param name="product">产品</param>
        /// <param name="dai"></param>
        /// <param name="data"></param>
        private void SaveProductStructure(Product product, DAICache dai, DAObject data)
        {
            if (!dai.MATERIAL_CODE.Equals(product.MATERIAL_CODE)) //如果采集的物料号于产品物料号一直则不保存产品组成
            {
                QMAPP.FJC.DAL.Produce.ProductDAL proddal = new QMAPP.FJC.DAL.Produce.ProductDAL();
                Product part = null;
                part= data.GetPersistentEntity<Product>(dai.OBJ_PID);
                if (part == null)
                {
                    part = proddal.GetByPID(dai.OBJ_PID, data.DataSession);
                }
                part.USINGCOUNT = part.USINGCOUNT + 1;
                part.USINGSTATE = part.CAPACITY > part.USINGCOUNT ? "1" : "2";
                //part.UPDATEDATE = DateTime.Now;
                part.UPDATEUSER=data.UserID;
                part.WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE;

                //proddal.Update(part, data.DataSession);
                data.AddToPersistentList(part, dai.OBJ_PID);

                ProductStructure structure = new ProductStructure()
                {
                    PART_PID = part.PID,
                    PID = Guid.NewGuid().ToString(),
                    PROCESS_CODE = product.PRODUCTCODE,
                    PRODUCT_PID = product.PID,
                    IsNewInfo=true
                };
                //ProductStructureDAL psdal = new ProductStructureDAL();
                //psdal.Insert(structure, data.DataSession);
                data.AddToPersistentList(structure, structure.PID);
            }
        }
        /// <summary>
        /// 保存加工参数
        /// </summary>
        /// <param name="product"></param>
        /// <param name="dai"></param>
        private void SaveProcessParam(Product product, DAICache dai,DAObject data)
        {
            ProcessParameters param = new ProcessParameters()
            {
                DA_CODE = dai.DA_CODE,
                DA_MODEL = "1",
                DA_TIME = dai.UPDATEDATE,
                EQUIPMENT_CODE = "",
                MEMBER_CODE = "",
                PARM_ITEM = "",
                PARM_VAL = dai.DA_VALUE,
                PRODUCT_PID = product.PID,
                SHIFT_CODE = "",
                PID = Guid.NewGuid().ToString(),
                TEAM_CODE = "",
                WORKCELL_CODE = dai.WORKCELL_CODE,
                WORKLOC_CODE = dai.WORKLOC_CODE,
                IsNewInfo=true,
            };
            //ProcessParametersDAL ppdal = new ProcessParametersDAL();
            //ppdal.Insert(param, data.DataSession);
            data.AddToPersistentList(param, param.PID);
        }
        /// <summary>
        /// 保存加工记录
        /// </summary>
        private void SaveProcessRecord(Product product, DAObject data, bool workcellend)
        {
            //QMAPP.FJC.DAL.Operation.ProductDAL pdal = new DAL.Operation.ProductDAL();
            //pdal.BaseSession = data.DataSession;
            //product = pdal.Get(product);

            ProcessRecordDAL prdal = new ProcessRecordDAL();
            ProcessRecord record = null;
            record = data.GetPersistentEntity<ProcessRecord>(product.PID);//加工记录的ID使用PRODUCT的ID代替
            if (record == null)
            {
                record = prdal.Get(product.PID, data.WorkLocState.WORKCELL_CODE, data.DataSession);
            }
            if (record != null)
            {
                //
                record.MANUAL_PASS = data.DAI == null ? "1" : "0";

                //if (string.IsNullOrEmpty(record.PROCESS_STATE))
                //{
                    //record.PROCESS_STATE = workcellend ? "1" : "0";
                //}

                if (record.MANUAL_PASS == "1")
                {
                    record.PROCESS_STATE = "2";
                }
                else
                {
                    record.PROCESS_STATE = workcellend ? "1" : "0";
                }

                record.WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE;
                
                if (workcellend)
                {
                    record.WORK_END_TIME = DateTime.Now;
                }
                //prdal.Update(record, data.DataSession);
            }
            else
            {
                record = new ProcessRecord()
                {
                    IN_WORKCELL_TIME = DateTime.Now,
                    PID = Guid.NewGuid().ToString(),
                    MANUAL_PASS = data.DAI == null ? "1" : "0",
                    //PROCESS_STATE = workcellend ? "1" : "0",
                    PRODUCT_PID = product.PID,
                    WORK_START_TIME = DateTime.Now,
                    WORKCELL_CODE = data.WorkLocState.WORKCELL_CODE,
                    WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE,
                    MODULE_CODE = data.MouldCode,
                    IsNewInfo = true
                };

                if (record.MANUAL_PASS == "1")
                {
                    record.PROCESS_STATE = "2";
                }
                else
                {
                    record.PROCESS_STATE = workcellend ? "1" : "0";
                }

                if (workcellend)
                {
                    record.WORK_END_TIME = DateTime.Now;
                }
                //prdal.Insert(record, data.DataSession);
            }
            data.AddToPersistentList(record, product.PID);//加工记录的ID使用PRODUCT的ID代替
            if (workcellend)
            {
                #region 插入加工记录
                //闫永刚 20170923

                MainOperation mo = new MainOperation();
                mo.PID = record.PID;
                mo.PDID = product.PID;
                mo.PROCESSTYPE = data.WorkLocState.CURRENTPROCESS;
                mo.PRODUCTTYPE = "";
                mo.PRODUCTCODE = product.PRODUCTCODE;
                mo.MACHINECODDE = data.MachineCode;
                mo.MOLDNUMBER = data.MouldCode;
                mo.MACHINENAME = data.MachineName;
                mo.STATUS = EnumGeter.STATUS.QUALIFIED.GetHashCode().ToString();
                mo.OPERATESTATE = data.DAI == null ? EnumGeter.OPERATESTATE.RELEASED.GetHashCode().ToString(): EnumGeter.OPERATESTATE.COMPLETED.GetHashCode().ToString();
                //mo.OPERATEDDATE = System.DateTime.Now;
                mo.CURRENTPROCESS = "";
                //mo.PRODUCELINE = "B9";
                mo.MODELSTATION = "1";
                mo.OPERATEDDATE = DateTime.Now;
                mo.CREATEDATE = record.IN_WORKCELL_TIME;//DateTime.Now;
                mo.CURRENTPROCESS = data.WorkLocState.CURRENTPROCESS;
                mo.MATERIAL_CODE = product.MATERIAL_CODE;
                mo.MATERIAL_NAME = product.MATERIAL_NAME;
                mo.MATERIAL_TYPE_CODE = product.MATERIAL_TYPE;
                mo.WORKCENTER_CODE = product.WORKCENTER_CODE;
                mo.WORKCELL_CODE = data.WorkLocState.WORKCELL_CODE;
                mo.CREATEUSER = product.CREATEUSER;
                mo.IsNewInfo = true;

                //MainOperationDAL moDal = new MainOperationDAL();
                //moDal.Insert(mo);
                data.AddToPersistentList(mo, mo.PID);
                #endregion

                #region 更新产品状态

                #region 产品下道工序设置

                //直接获取下道工序信息
                QMAPP.MD.Entity.WorkCell nextCell = new WorkCellDAL().GetNextWorkCell(new QMAPP.MD.Entity.WorkCell() { WORKCELL_CODE = data.WorkLocState.WORKCELL_CODE });

                if (nextCell != null && string.IsNullOrEmpty(nextCell.PID) == false)
                {
                    product.WORKCELL_CODE = nextCell.WORKCELL_CODE;
                    product.WORKCENTER_CODE = nextCell.WORKCENTER_CODE;
                    product.TEAM_CODE = "";
                    product.WORKLOC_CODE = "";
                    product.CURRENTPROCESS = nextCell.CURRENTPROCESS;
                }
                else
                {
                    //获取其他工艺路线的

                    #region 通过零件号获取BOM


                    //判断当前零件号是否是总成零件号
                    //如果不是继续判断下一个工序
                    //List<Pbom> pbomList = new PbomDAL().GetList(new Pbom() { MATERIAL_CODE = product.MATERIAL_CODE });
                    //if (pbomList.Count == 0)
                    //{
                        ProcessRouteWithWorkCellSeqDAL seqdal = new ProcessRouteWithWorkCellSeqDAL();
                        ProcessRouteWithWorkCellSeq seq = seqdal.GetNextWorkCellBetweenRoute(new Product() { WORKCELL_CODE = product.WORKCELL_CODE, MATERIAL_CODE = product.MATERIAL_CODE }); ;
                        product.WORKCELL_CODE = seq != null ? seq.WORKCELL_CODE : "";

                        QMAPP.MD.Entity.WorkCell workcell = new WorkCellDAL().GetByCondition(new QMAPP.MD.Entity.WorkCell() { WORKCELL_CODE = product.WORKCELL_CODE });
                        product.CURRENTPROCESS = workcell.CURRENTPROCESS;

                    //}



                    #endregion
                }

                //pdal.Update(product);

                #endregion

                #endregion

                //product.STATUS = (int.Parse(record.PROCESS_STATE) - 1).ToString();
            }
        }
        /// <summary>
        /// 获取/创建产品信息
        /// </summary>
        /// <param name="data"></param>
        /// <param name="workcellend">工序结束</param>
        /// <returns></returns>
        private Product SaveProduct(DAObject data, bool workcellend, List<DAICache> dagroup)
        {
            MD.DAL.ProcessRouteDAL routedal = new MD.DAL.ProcessRouteDAL();
            var route = routedal.LocateRoute(data.WorkLocState.WORKCELL_CODE);
            if (route == null)
            {
                throw new Exception("无法定位工艺路线!请检查工序和工艺路线设置。");
            }

            DAL.Basic.ProcessRouteWithWorkCellSeqDAL routeseqdal = new ProcessRouteWithWorkCellSeqDAL();
            var endofroute = routeseqdal.EndOfRoute(route.RouteCode, data.WorkLocState.WORKCELL_CODE);

            var materialdal = new DAL.MD.MaterialDAL();
            var material = materialdal.Get(data.WorkLocState.CurrentState.MATERIAL_CODE);

            QMAPP.FJC.DAL.Produce.ProductDAL dal = new QMAPP.FJC.DAL.Produce.ProductDAL();
            
            Product product=null;
            if (!string.IsNullOrEmpty(data.WorkLocState.CurrentState.PROCESS_CODE)) //如果已存在产品条码则获取产品信息
            {
                product = dal.GetByCode(data.WorkLocState.CurrentState.PROCESS_CODE, data.WorkLocState.CurrentState.MATERIAL_CODE, data.DataSession);
            }
            if(product==null)
            {
                string sn = (from da in dagroup
                             where string.Equals(da.ISPROCESSCODE, "1")
                             select da.DA_VALUE).FirstOrDefault();
                product = dal.GetByCode(sn, data.WorkLocState.CurrentState.MATERIAL_CODE, data.DataSession);
            }
            if (product != null)
            {
                product.WORKCELL_CODE = data.WorkLocState.WORKCELL_CODE;
                product.WORKCENTER_CODE = data.WorkLocState.WORKCENTER_CODE;
                product.WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE;
                product.MATERIAL_TYPE = material == null ? "" : material.MATERIAL_TYPE_CODE;
                //product.UPDATEDATE = DateTime.Now;
                product.UPDATEUSER = data.UserID;
                if (workcellend)
                {
                    product.STATUS = workcellend ? "0" : "";
                    product.USINGSTATE = workcellend ? "0" : "";
                    product.OUTFLAG = workcellend ? "0" : "";
                }
                if (endofroute)
                {
                    product.ENDOFLINE = "1";
                }
                data.AddToPersistentList(product, product.PID);
                //dal.Update(product, data.DataSession);
                //data.WorkLocState.CurrentState.PRODUCT_PID = product.PID;
                return product;
            }
            else //不存在则创建产品信息
            {
                string sn = (from da in dagroup
                             where string.Equals(da.ISPROCESSCODE, "1")
                             select da.DA_VALUE).FirstOrDefault();
                if (string.IsNullOrEmpty(sn))
                {
                    //TODO:根据物料号的不同 分别生成产品序列号
                    sn = "";
                }
                product = new Product()
                {
                    CAPACITY = 1,
                    MATERIAL_CODE = data.WorkLocState.CurrentState.MATERIAL_CODE,
                    CREATEDATE = DateTime.Now,
                    CREATEUSER = data.UserID,
                    PID = Guid.NewGuid().ToString(),
                    PRODUCTCODE = sn,
                    STATUS = workcellend ? "0" : "",
                    TEAM_CODE = "",
                    USINGCOUNT = 0,
                    WORKCELL_CODE = data.WorkLocState.WORKCELL_CODE,
                    WORKCENTER_CODE = data.WorkLocState.WORKCENTER_CODE,
                    WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE,
                    PRODUCESHIFTTCODE = data.Shift.PRODUCESHIFTTCODE,
                    USINGSTATE = workcellend ? "0" : "",
                    PRODUCTSOURCE = "0",
                    OUTFLAG = workcellend ? "0" : "",
                    MACHINECODDE = data.MachineCode,
                    MACHINENAME = data.MachineName,
                    MATERIAL_TYPE = material == null ? "" : material.MATERIAL_TYPE_CODE,
                    IsNewInfo = true
                };
                if (endofroute)
                {
                    product.ENDOFLINE = "1";
                }
                data.AddToPersistentList(product, product.PID);
                //dal.Insert(product, data.DataSession);
                //data.WorkLocState.CurrentState.PROCESS_CODE = sn;
                //data.WorkLocState.CurrentState.PRODUCT_PID = product.PID;
                return product;
            }

        }
        /// <summary>
        /// 根据物料组获取上层物料号
        /// </summary>
        /// <param name="materials"></param>
        /// <returns></returns>
        private BomLocation GetBomLocation(params string[] materials)
        {
            PbomDAL pbidal = new PbomDAL();
            var bomlocations = pbidal.LocateBom(materials);
            //确定物料组成数量一致
            var bomlocation = bomlocations.FirstOrDefault(p => p.SubCount == materials.Length);
            return bomlocation;
        }
    }
}