using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using QMAPP.BLL;
using QMFrameWork.Data;
using QMAPP.FJC.BLL.Dict;
using QMAPP.FJC.Entity.Operation;
using QMAPP.FJC.DAL.Operation;
using QMAPP.Entity;
using QMAPP.FJC.DAL.ProductIn;
using QMAPP.FJC.Entity;
using QMFrameWork.Log;
using QMAPP.FJC.DAL.ProductionPlan;
using QMAPP.FJC.Entity.ProductionPlan;
using System.Text.RegularExpressions;
using QMAPP.MD.Entity;
using QMAPP.MD.DAL;

namespace QMAPP.FJC.BLL.Operation
{
    public class MainCodeChangeBLL : BaseBLL
    {
        #region 获取列表
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="condition">条件</param>
        /// <param name="page">数据页</param>
        /// <returns>数据页</returns>
        public DataPage GetList(MainCodeChange condition, DataPage page)
        {
            try
            {
                page = new MainCodeChangeDAL().GetList(condition, page);

                List<MainCodeChange> list = page.Result as List<MainCodeChange>;
                page.Result = list;

                return page;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 获取列表web
        /// </summary>
        /// <param name="condition">条件</param>
        /// <param name="page">数据页</param>
        /// <returns>数据页</returns>
        public DataResult<DataPage> GetListWeb(MainCodeChange condition, DataPage page)
        {
            DataResult<DataPage> result = new DataResult<DataPage>();
            try
            {
                //获取信息列表
                page = new MainCodeChangeDAL().GetList(condition, page);

                #region 转换状态显示类型
                //List<Epidermis> fisOrderList = page.Result as List<Epidermis>;
                ////处理字典信息
                //DictManageBLL dictSCANSTATE = new DictManageBLL(DictKind.SCANSTATE);

                //foreach (var info in fisOrderList)
                //{
                //    info.SCANSTATE = dictSCANSTATE.GetDictValue(info.SCANSTATE);
                //}
                #endregion

                result.Result = page;
            }
            catch (Exception ex)
            {
                LogManager.LogHelper.Error(new LogInfo()
                {
                    ErrorInfo = ex,
                    Tag = ex.StackTrace,
                    Info = "成品信息逻辑层-获取列表!"
                });
                result.IsSuccess = false;
                result.Msg = Resource.SystemException;
                throw ex;
            }
            result.IsSuccess = true;
            return result;
        }

        #endregion

        #region 插入信息
        /// <summary>
        /// 插入信息(单表)
        /// </summary>
        /// <param name="">信息</param>
        /// <returns>插入行数</returns>
        public int Insert(MainCodeChange model)
        {
            try
            {
                //基本信息
                model.PID = Guid.NewGuid().ToString();
                model.CREATEUSER = this.LoginUser.UserID;
                model.CREATEDATE = DateTime.Now;
                MainDAL cmdDAL = new MainDAL();
                if (ExistsMain(model) == true)
                    return -1;
                return new MainCodeChangeDAL().Insert(model);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region 信息是否重复
        /// <summary>
        /// 判断名称是否存在
        /// </summary>
        /// <param name="info"></param>
        /// <returns>true:已存在;fasel:不存在。</returns>
        public bool ExistsMain(MainCodeChange model)
        {
            try
            {
                return new MainCodeChangeDAL().ExistsMain(model);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        #endregion

        #region 获取生成新的Maincode
        /// <summary>
        /// 获取生成新的Maincode
        /// </summary>
        /// <returns></returns>
        public DataResult<string> Generate(string materialCode)
        {
            using (IDataSession session = AppDataFactory.CreateMainSession())
            {
              try
                {
                DataResult<string> result = new DataResult<string>();
                DAL.Operation.MainDAL maindal = new DAL.Operation.MainDAL();
                maindal.BaseSession = session;
                PrintCode condition = maindal.GetMaxMainCode(materialCode);

                string newcode = "1";
                if (!string.IsNullOrEmpty(condition.MAINCODE))
                {
                    string mainCode = (Convert.ToInt32(condition.MAINCODE.Substring(1, 6))).ToString();
                    newcode = (Convert.ToInt32(mainCode) + 1) + "";
                }
                newcode = "052 4XR" + condition.MAINCODE.Substring(0, 1) + newcode.PadLeft(6, '0');
                result.Result = newcode + CalculateChecksum(newcode);

                PrintCode pc = new PrintCode();
                pc.PID = condition.PID;
                pc.MAINCODE = result.Result;
                pc.PRODUCTCODE = condition.PRODUCTCODE;
                pc.ISCOMPLETE = 0;
                pc.CREATETIME = System.DateTime.Now;
                DAL.Operation.PrintCodeDAL dal = new DAL.Operation.PrintCodeDAL();
                dal.BaseSession = session;
                dal.UpdateForChangeCode(pc);

                session.CommitTs();
                return result;
                }
               catch (Exception ex)
               {
                   session.RollbackTs();
                   return new DataResult<string> { IsSuccess = false, Ex = ex, Msg = ex.Message };
               }
            }
        }
        /// <summary>
        /// 计算验证码
        /// </summary>
        /// <returns></returns>
        public static string CalculateChecksum(string barcode)
        {
            string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%";
            int sum = 0;
            foreach (var c in barcode)
            {
                sum += chars.IndexOf(c);
            }
            int rem = sum % chars.Length;
            return chars[rem].ToString();
        }
        #endregion

        #region 导出数据
        /// <summary>
        /// 获取导出的数据
        /// </summary>
        /// <param name="user">查询条件</param>
        /// <returns>数据</returns>
        public DataResult<DataTable> GetExportData(MainCodeChange model)
        {
            DataResult<DataTable> result = new DataResult<DataTable>();
            try
            {
                result.IsSuccess = true;
                result.Result = new MainCodeChangeDAL().GetExportData(model);
            }
            catch (Exception ex)
            {
                LogManager.LogHelper.Error(new LogInfo()
                {
                    ErrorInfo = ex,
                    Tag = ex.StackTrace,
                    Info = "导出错误!"
                });
                result.IsSuccess = false;
                result.Msg = "导出错误!";
            }
            return result;
        }
        #endregion

        #region 门板条码重新生成

        public Product DPRegenerate(Product product)
        {
            using (IDataSession session = AppDataFactory.CreateMainSession())
            {
                try
                {
                    string oldcode=product.PRODUCTCODE;
                    product.OUTFLAG = "2";
                    string regexp="(?<=\\d)R\\d";
                    var flag=System.Text.RegularExpressions.Regex.Match(oldcode,regexp);
                    if(flag.Success)
                    {
                        var nflag = "R" + (int.Parse(flag.Value[1] + "") + 1);
                        product.PRODUCTCODE = System.Text.RegularExpressions.Regex.Replace(oldcode, regexp, nflag);
                    }
                    else
                    {
                        product.PRODUCTCODE = oldcode.Insert(oldcode.Length - 6, "R0");
                    }
                    
                        //GenerateCode(product.MATERIAL_CODE, product.CREATEDATE);
                    var changelog = new MainCodeChange
                    {
                        CREATEDATE = DateTime.Now,
                        CREATEUSER = LoginUser.UserID,
                        MATERIAL_NAME = product.MATERIAL_NAME,
                        MATERIALCODE = product.MATERIAL_CODE,
                        NEWMAINCODE = product.PRODUCTCODE,
                        ORIGMAINCODE = oldcode,
                        PRODUCELINE = product.PRODUCELINE,
                        PRODUCTCODE = product.PRODUCTCODE,
                        PID = Guid.NewGuid().ToString()
                    };

                    DAL.Operation.ProductDAL dal = new ProductDAL();
                    dal.BaseSession = session;
                    DAL.QT.ProductStructureDAL psdal = new DAL.QT.ProductStructureDAL();
                    psdal.BaseSession = session;
                    DAL.Operation.MainCodeChangeDAL cdal = new MainCodeChangeDAL();
                    cdal.BaseSession = session;
                    DAL.Operation.MainOperationDAL modal = new MainOperationDAL();
                    modal.BaseSession = session;

                    session.OpenTs();

                    dal.ReplaceBarcode(oldcode, product.PRODUCTCODE);
                    psdal.ReplaceProcesscode(oldcode, product.PRODUCTCODE);
                    modal.ReplaceBarcode(oldcode, product.PRODUCTCODE);
                    modal.DPParamReplace(oldcode, product.PRODUCTCODE);

                    cdal.Insert(changelog);

                    session.CommitTs();
                    return product;
                }
                catch (Exception ex)
                {
                    session.RollbackTs();
                    throw ex;
                }
            }
        }

        private string GenerateCode(string materialcode, DateTime time)
        {
            QMAPP.FJC.DAL.MD.MaterialDAL mdal = new QMAPP.FJC.DAL.MD.MaterialDAL();
            var material = mdal.Get(new QMAPP.FJC.Entity.MD.Material { MATERIAL_CODE = materialcode });
            if (material == null)
            {
                throw new Exception("查找物料信息失败!");
            }
            DAL.Basic.MaterialCodeInitDAL mcdal = new DAL.Basic.MaterialCodeInitDAL();
            var materialinit = mcdal.GetByCondition(new Entity.Basic.MaterialCodeInit { MATERIAL_TYPE = material.MATERIAL_TYPE_CODE });

            string prefix = "";
            if (materialinit != null)
            {
                prefix = materialinit.PRODUCT_TYPES;
            }

            var productdal = new DAL.Produce.ProductDAL();

            string maxcode = productdal.GetMaxCode(material.MATERIAL_TYPE_CODE, time);
            string newcode = "1";
            if (!string.IsNullOrEmpty(maxcode))
            {
                newcode = (Convert.ToInt32(maxcode) + 1) + "";
            }
            newcode = prefix + time.ToString("yyyyMMdd") + newcode.PadLeft(6, '0');

            return newcode;
        }

        #endregion

        public DataResult ReplacePlanNo(Product product,string newplanno)
        {
            using (IDataSession session = AppDataFactory.CreateMainSession())
            {
                try
                {
                    var changelog = new MainCodeChange
                    {
                        CREATEDATE = DateTime.Now,
                        CREATEUSER = LoginUser.UserID,
                        MATERIAL_NAME = product.MATERIAL_NAME,
                        MATERIALCODE = product.MATERIAL_CODE,
                        NEWMAINCODE = newplanno,
                        ORIGMAINCODE = product.PLAN_NO,
                        PRODUCELINE = product.PRODUCELINE,
                        PRODUCTCODE = product.PRODUCTCODE,
                        PID = Guid.NewGuid().ToString()
                    };

                    DAL.Operation.ProductDAL dal = new ProductDAL();
                    dal.BaseSession = session;
                    DAL.Operation.MainCodeChangeDAL cdal = new MainCodeChangeDAL();
                    cdal.BaseSession = session;



                    if (product.ENDOFLINE != "1")
                    {
                        var order = SetOrder(session, newplanno, product);
                        dal.ReplacePlanNo(product.PRODUCTCODE, newplanno, order.ORDERPLANID);
                    }
                    else
                    {
                        dal.ReplacePlanNo(product.PRODUCTCODE, newplanno, "");
                    }

                    cdal.Insert(changelog);

                    session.CommitTs();
                    return new DataResult { IsSuccess = true };
                }
                catch (Exception ex)
                {
                    session.RollbackTs();
                    return new DataResult { IsSuccess = false, Ex = ex, Msg = ex.Message };
                }
            }
        }

        public DataResult ExchangePlanNo(Product oproduct, Product nproduct)
        {
            using (IDataSession session = AppDataFactory.CreateMainSession())
            {
                try
                {
                    var changelog = new MainCodeChange
                    {
                        CREATEDATE = DateTime.Now,
                        CREATEUSER = LoginUser.UserID,
                        MATERIAL_NAME = oproduct.MATERIAL_NAME,
                        MATERIALCODE = oproduct.MATERIAL_CODE,
                        NEWMAINCODE = nproduct.PLAN_NO,
                        ORIGMAINCODE = oproduct.PLAN_NO,
                        PRODUCELINE = oproduct.PRODUCELINE,
                        PRODUCTCODE = oproduct.PRODUCTCODE,
                        PID = Guid.NewGuid().ToString()
                    };
                    var changelog1 = new MainCodeChange
                    {
                        CREATEDATE = DateTime.Now,
                        CREATEUSER = LoginUser.UserID,
                        MATERIAL_NAME = nproduct.MATERIAL_NAME,
                        MATERIALCODE = nproduct.MATERIAL_CODE,
                        NEWMAINCODE = oproduct.PLAN_NO,
                        ORIGMAINCODE = nproduct.PLAN_NO,
                        PRODUCELINE = nproduct.PRODUCELINE,
                        PRODUCTCODE = nproduct.PRODUCTCODE,
                        PID = Guid.NewGuid().ToString()
                    };

                    DAL.Operation.ProductDAL dal = new ProductDAL();
                    dal.BaseSession = session;
                    DAL.Operation.MainCodeChangeDAL cdal = new MainCodeChangeDAL();
                    cdal.BaseSession = session;



                    if (nproduct.ENDOFLINE != "1")
                    {
                        var norder= SetOrder(session, oproduct.PLAN_NO, nproduct);
                        dal.ReplacePlanNo(nproduct.PRODUCTCODE, oproduct.PLAN_NO,norder.ORDERPLANID);
                    }
                    else
                    {
                        dal.ReplacePlanNo(nproduct.PRODUCTCODE, oproduct.PLAN_NO,"");
                    }
                    if (oproduct.ENDOFLINE != "1")
                    {
                        var oorder = SetOrder(session, nproduct.PLAN_NO, oproduct);
                        dal.ReplacePlanNo(oproduct.PRODUCTCODE, nproduct.PLAN_NO,oorder.ORDERPLANID);
                    }
                    else
                    {
                        dal.ReplacePlanNo(oproduct.PRODUCTCODE, nproduct.PLAN_NO,"");
                    }

                    

                    cdal.Insert(changelog);

                    session.CommitTs();
                    return new DataResult { IsSuccess = true };
                }
                catch (Exception ex)
                {
                    session.RollbackTs();
                    return new DataResult { IsSuccess = false, Ex = ex, Msg = ex.Message };
                }
            }
        }

        private  Entity.ProductionPlan.WorkOrder SetOrder(IDataSession session , string orderno,Product product)
        {
            string regexp_full = "^D\\d{2}\\w+[RF][LR]\\d{2}(10|11|12|0[1-9])(30|31|2\\d|1\\d|0[1-9])\\w\\d{5}$";
            string regexp_prefix = "^D\\d{2}\\w+(?=[RF][LR]\\d{6})";
            string regexp_position = "[RF][LR](?=\\d{6})";
            string regexp_date = "(?<=[RF][LR])\\d{2}(10|11|12|0[1-9])(30|31|2\\d|1\\d|0[1-9])";
            string regexp_seq = "\\d{5}$";
            string regexp_sdSeq = "(?<=SD)\\d{4}$";
            var plandal = new DAL.FIS.OrderPlanDAL();
            var workorderdal = new DAL.ProductionPlan.WorkOrderDAL();
            //Entity.FIS.OrderPlan plan = null;
            Entity.ProductionPlan.WorkOrder order = null;
            order = workorderdal.GetOneByOrderNO(orderno);

            if (order == null)
            {
                var plan=plandal.GetInfo(new Entity.FIS.OrderPlan { PLAN_NO = Regex.Replace(orderno,regexp_sdSeq, "") });
                if (plan == null)
                {
                    
                        
                    
                    string codeprefix = Regex.Match(orderno, regexp_prefix).Value;
                    string positioncode = Regex.Match(orderno, regexp_position).Value;
                    string date = Regex.Match(orderno, regexp_date).Value;
                    string seq = "";
                    if (Regex.IsMatch(orderno, regexp_full))
                    {
                        seq = Regex.Match(orderno, regexp_seq).Value;
                    }
                    else
                    {
                        seq = Regex.Match(orderno, regexp_sdSeq).Value;
                    }

                    string materialcode = new DAL.FIS.FISPhraseDAL().GetMESModulCode(codeprefix, positioncode);
                    if (string.IsNullOrWhiteSpace(materialcode))
                    {
                        throw new Exception("FIS短语字典配置不准确或未更新!");
                    }

                    DateTime plandate
                    = new DateTime(2000 + int.Parse(date.Substring(0, 2))
                        , int.Parse(date.Substring(2, 2))
                        , int.Parse(date.Substring(4, 2)));

                    plandal.BaseSession = session;
                    plan = new Entity.FIS.OrderPlan
                    {
                        CREATEDATE = DateTime.Now,
                        COMPLETE_QTY = 0,
                        CREATEUSER = "",
                        MATERIAL_CODE = materialcode,//////////////////
                        PID = Guid.NewGuid().ToString(),
                        PLAN_DATE = plandate,////////////
                        PLAN_NO = orderno,
                        PLAN_SEQ = seq,//////////////////
                        PLAN_STATE = "1",
                        PLANSOURCE = Regex.IsMatch(orderno, regexp_full)?"0":"1",
                        QTY = 1,
                        UPDATEUSER = "",
                        UPDATEDATE = DateTime.Now,
                    };

                    Pbom pbomcode = new PbomDAL().Get(new Pbom { MATERIAL_CODE = plan.MATERIAL_CODE });
                    if (pbomcode != null)
                    {
                        plan.PBOM_CODE = pbomcode.PBOM_CODE;
                    }
                    QMAPP.MD.Entity.ProcessRoute routecode = new QMAPP.MD.DAL.ProcessRouteDAL().RouteWithMaterial(plan.MATERIAL_CODE);
                    if (routecode != null)
                    {
                        plan.ROUTE_CODE = routecode.ROUTE_CODE;
                    }
                    string workcentercode = new WorkCellDAL().GetWorkcenterWithMaterial(plan.MATERIAL_CODE);
                    if (workcentercode != null)
                    {
                        plan.WORKCENTER_CODE = workcentercode;
                    }
                    //赋值新session后插入 zxd20171101
                    plandal.Insert(plan);
                }




                var wodDal = new WorkOrderDAL();
                //List<QMAPP.MD.Entity.ProcessRouteWorkCellSeq> list = new WorkCellDAL().GetFirstWorkCell(plan.PBOM_CODE);

                wodDal.BaseSession = session;

                //DataRow workOrder = workOrderDt.NewRow();
                order = new WorkOrder();

                order.PID = Guid.NewGuid().ToString();
                order.ORDERPLANID = plan.PID;
                order.ORDERPLAN_NO = plan.PLAN_NO;
                if (Regex.IsMatch(orderno, regexp_full))
                    order.ORDER_TYPE = EnumGeter.WORKORDERTYPE.FIS.GetHashCode().ToString();
                else
                    order.ORDER_TYPE = EnumGeter.WORKORDERTYPE.STOCK.GetHashCode().ToString();
                order.SEQ = plan.PLAN_SEQ;
                order.MATERIAL_CODE = plan.MATERIAL_CODE;
                order.PBOM_CODE = plan.PBOM_CODE;
                order.QTY = 1;
                order.COMPLETE_QTY = 0;
                order.PLAN_DATE = plan.PLAN_DATE;
                order.SHIFT_CODE = plan.SHIFT_CODE;
                order.WORKCENTER_CODE = plan.WORKCENTER_CODE;
                //WorkCell workcellcode = new WorkCellDAL().Get(new WorkCell { WORKCENTER_CODE = info.WORKCENTER_CODE });
                order.WORKCELL_CODE = product.WORKCELL_CODE;
                order.WORKLOC_CODE = "";
                order.REMARK = product.PRODUCTCODE;
                order.EQPT_NAME = "";
                order.EQPT_CODE = "";
                order.STATE = EnumGeter.WORKPLANSTATE.READY.GetHashCode();
                order.PRI = 1;
                //order.UPDATEDATE = DateTime.Now;
                order.PRINTED = "1";
                wodDal.Insert(order);
            }
            else
            {
                order.WORKCELL_CODE = product.WORKCELL_CODE;
                order.REMARK = product.PRODUCTCODE;
                var wodDal = new WorkOrderDAL();
                
                wodDal.BaseSession = session;
                wodDal.Update(order);
            }
            return order;
        }
    }
}