using Common;
using Common.vo.pb;
using MeterConditionLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using com.hnshituo.core.webapp.vo;

namespace MeterSceneLibrary
{
    /// <summary>
    /// 先皮后毛 一车多运非互锁式
    /// </summary
    public class FirstTaresSecondlyGrossesUnLock
    {
        private MeterBaseTermTareDataService termTareDate = new MeterBaseTermTareDataService();//期限皮操作

        public rtInfo MeterMethod(PreTrackScale scale, CoreAppUser appUser, RESTfulResult<List<MeterWorkPreLink>> rmDb)
        {
            rtInfo rt = new rtInfo();
            rt.isError = false;

            //0：批次预报；1：单次预报；2：联运预报；3：分检预报
            if (scale.predictionType != "2")
            {
                rt.result = false;
                rt.isError = false;
                return rt;
            }

            RESTfulResult<List<MeterWorkPreLink>> rm = rmDb;

            /******************************
             * 1、如果是第一次计量：走一次计量流程(若根据预报的PREDICTION_COMBINATION值使用in找不到一次计量数据，那么就是第一次计量)
             * 2、如果不是一次计量：根据预报的PREDICTION_COMBINATION值找到唯一一条未结净的数据，然后当前计量数据与找到的进行结净，而结净的预报信息使用找到的预报信息
             ******************************/
            //如果配置了则走下面的流程
            //如果存在一次计量未结净数据，则认为是结净计量，否则认为一次计量
            MeterWorkCarActualFirstService mwcfs = new MeterWorkCarActualFirstService();

            RESTfulResult<List<MeterWorkCarActualFirst>> rmX = mwcfs.doQueryWf(new MeterWorkCarActualFirst { valueFlag = "1", predictionCombination = scale.predictionCombination, carNo = scale.carNo });
            if (!rmX.Succeed)
            {
                rt.result = false;
                rt.resultInfo = "没有计量信息点语音求助";
                PbCache.ResultMessage = "获取一次计量数据异常！";
                rt.isError = true;
            }

            //因为前面已经验证过预报信息，所以这里只要有一次数据则认为已经过第一车了，后面都是结净+生成一条待结净数据
            if (rmX.Data != null && rmX.Data.Count > 0)
            {
                rm.Data[0].linkCode = "001021005";
            }

            if (rm.Data[0].linkCode == "001021003") //一次计量
            {
                #region 
                /*
                if (rmX.Data != null && rmX.Data.Count > 0)
                {
                    PbCache.ResultMessage = "计量环节为一次计量，存在未结净数据数据！";
                    rt.resultInfo = "已经存在一次计量信息";
                    rt.result = false;
                    rt.isError = true;
                }
                else
                //*/
                #endregion
                {
                    //验证两次计量时间间隔
                    validTimeInterval vti = new validTimeInterval();
                    vti.ValidMethod(scale, "2", null);
                    if (!PbCache.monitorResult.valid_time_interval)
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = PbCache.ResultMessage;
                        return rt;
                    }

                    //保存皮重信息***********************
                    MeterWorkCarActualFirst mwaf = new MeterWorkCarActualFirst();

                    //相同名称的均赋值一次
                    EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
                    mwaf = entityBase.format<MeterWorkCarActualFirst>(scale, mwaf);

                    mwaf.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
                    mwaf.meterWeight = PbCache.lockWgt;//计量重量
                                                       //mwaf.addWeight = 0;//附加重量
                    mwaf.weightType = "1"; //0=毛重；1=常规皮重；2=期限皮重；3=历史皮重；4=标识皮重；5=自重皮重
                    mwaf.createManNo = appUser.userid;
                    mwaf.createManName = appUser.username;
                    mwaf.meterGroup = appUser.userGroup;
                    mwaf.meterClass = appUser.userClass;
                    mwaf.createTime = DateTime.Now;
                    mwaf.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
                    mwaf.baseSpotName = PbCache.sportInfo.baseSpotName;
                    //mwaf.memo = "";
                    mwaf.valueFlag = "1"; //0有效
                    mwaf.updateManName = "";
                    mwaf.updateManNo = "";
                    mwaf.updateTime = null;
                    mwaf.checkFlag = "0"; //0未审核
                    mwaf.meterMode = string.IsNullOrEmpty(appUser.userid) ? "2" : "1"; //1远程计量，2智能计量
                    mwaf.addWeight = PbCache.addWgt;


                    MeterWorkPreLink mwpl = new MeterWorkPreLink();
                    mwpl.preLinkNo = rm.Data[0].preLinkNo;
                    mwpl.preProcessNo = rm.Data[0].preProcessNo;

                    //操作日志
                    MeterMonitorNote monitorNote = new MeterMonitorNote();
                    monitorNote.baseSpotNo = mwaf.baseSpotNo;
                    monitorNote.baseSpotName = mwaf.baseSpotName;
                    monitorNote.operationContent = string.Format("称重保存");
                    monitorNote.operationTime = mwaf.createTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                    monitorNote.carNo = mwaf.carNo;
                    monitorNote.meterNoteSource = string.IsNullOrEmpty(appUser.userid) ? "0" : "4";
                    monitorNote.meterManNo = appUser.userid;
                    monitorNote.meterManName = appUser.username;

                    RESTfulResult<string> rmI = mwcfs.doAddWf(mwaf, mwpl, monitorNote, "", "0");
                    if (rmI.Succeed)
                    {
                        rt.result = true;
                        rt.resultInfo = "称重完成";
                        PbCache.ResultMessage = "称重完成";
                        PbCache.actualFirstNo = rmI.Data;
                        PbCache.strQRCode = rmI.Message;
                        PbCache.isTareWeight = true;//皮重
                        RESTfulResult<string> RESTfulResult = termTareDate.abolishForCSharp(new MeterBaseTermTareData { carNo = mwaf.carNo });
                        if (RESTfulResult.Succeed)
                        {
                            if (!string.IsNullOrEmpty(RESTfulResult.Message))
                            {
                                PbCache.ResultMessage = PbCache.ResultMessage + "；请注意期限皮重已作废";
                            }
                        }
                        else
                        {
                            PbCache.ResultMessage = PbCache.ResultMessage + "；作废期限皮重异常，请点击【语音求助】联系计量员";
                        }
                    }
                    else
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = "称重数据保存失败";
                        PbCache.ResultMessage = "计量失败：" + rmI.ResultMessage;
                    }
                }
            }
            else if (rm.Data[0].linkCode == "001021005") //结净
            {
                if (string.IsNullOrEmpty(scale.forwardingUnitName) || string.IsNullOrEmpty(scale.receivingUintName))
                {
                    PbCache.ResultMessage = "结净时，预报中的发货单位以及收货单位均不允许为空，请点击[语音求助]！";
                    rt.result = false;
                    rt.isError = false;
                    return rt;
                }
                if (rmX.Data == null || rmX.Data.Count == 0)
                {
                    rt.resultInfo = "未找到一次计量数据！";
                    rt.result = false;
                    rt.isError = false;
                    PbCache.ResultMessage = "未找到一次计量数据,请先计量皮重！";
                }
                else if (rmX.Data.Count == 1) //存在未结净的数据，当前计量数据与找到的进行结净，而结净的预报信息使用找到的预报信息
                {
                    if (!PbCache.isNotValid)
                    {
                        if (Math.Abs(rmX.Data[0].meterWeight.Value - PbCache.lockWgt) < AppConfigCache.differenceWgt)
                        {
                            //重复计量
                            rt.result = false;
                            rt.isError = true;
                            rt.resultInfo = "第一次计量重量和第二次计量重量接近";
                            //PbCache.ResultMessage = "第一次计量重量和第二次计量重量接近";
                            PbCache.ResultMessage = "第一次计量重量【" + rmX.Data[0].meterWeight.Value / 1000 + "T】和第二次计量重量【" + PbCache.lockWgt / 1000 + "T】接近，小于结净最小值【" + AppConfigCache.differenceWgt / 1000 + " T】,请点击[语音求助]，由司秤工过磅！";
                            return rt;
                        }
                    }

                    //一次重量大于当前重量，所以一次的时候应该是毛重
                    if (rmX.Data[0].meterWeight.Value - PbCache.lockWgt > 0)
                    {
                        //将一次数据类型修改为皮重
                        mwcfs.doUpdateWf(new MeterWorkCarActualFirst { actualFirstNo = rmX.Data[0].actualFirstNo, weightType = "0" });
                        PbCache.ResultMessage = "请再次点击[保存]按钮";
                        rt.result = false;
                        rt.isError = false;
                        return rt;
                    }

                    PreTrackScale pts = new PreTrackScale();

                    if (rmX.Data[0].predictionNo == scale.predictionNo) //当前已经是一车联运的最后一车过磅了，所以上次的毛跟当前的皮用的同一个预报
                    {
                        pts = scale;
                    }
                    else
                    {   //当前不是一车联运的最后一个预报过磅
                        PreTrackScaleService pService = new PreTrackScaleService();
                        RESTfulResult<List<PreTrackScale>> rmp = pService.doQueryWf(new PreTrackScale { predictionNo = rmX.Data[0].predictionNo });
                        if (rmp.Succeed)
                        {
                            if (rmp.Data != null && rmp.Data.Count > 0)
                            {
                                pts = scale;
                            }
                            else
                            {
                                rt.result = false;
                                rt.isError = true;
                                rt.resultInfo = "计量预报已经过期";
                                PbCache.ResultMessage = string.Format("一车联运预报编号为[{0}]的信息未找到", rmX.Data[0].predictionNo);
                                return rt;
                            }
                        }
                        else
                        {
                            rt.result = false;
                            rt.isError = true;
                            rt.resultInfo = "称重数据保存失败";
                            PbCache.ResultMessage = "计量失败：获取预报信息异常";
                        }
                    }

                    MeterWorkCarActualFirst first = rmX.Data[0];

                    //一次皮与当前毛结合，此时要验证两次计量间隔以及毛重是否符合要求
                    #region 验证两次计量时间间隔
                    validTimeInterval vti = new validTimeInterval();
                    vti.ValidMethod(pts, "3", first);
                    if (!PbCache.monitorResult.valid_time_interval)
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = PbCache.ResultMessage;
                        return rt;
                    }
                    #endregion

                    #region 验证当前毛重是否符合要求
                    //验证物料时间段
                    validMatTime vmt = new validMatTime();
                    vmt.ValidMethod(scale, "1");
                    if (!PbCache.monitorResult.valid_mat_time)
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = PbCache.ResultMessage;
                        return rt;
                    }

                    //验证危化品验证
                    validExceedWgt vew = new validExceedWgt();
                    vew.validMatMethod(scale, "1", null);
                    if (!PbCache.monitorResult.valid_exceed_wgt)
                    {
                        rt.result = false;
                        rt.isError = true;
                        return rt;
                    }

                    //验证预报超差信息
                    validPredictionDiff vpd1 = new validPredictionDiff();
                    vpd1.ValidMethod(scale, "1", null); //验证毛重
                    if (!PbCache.monitorResult.valid_prediction_diff)
                    {
                        rt.result = false;
                        rt.isError = false;
                        return rt;
                    }

                    //验证联达码头；江西联达联达料场，预报超差
                    validLianDaWgtDiff lianDaWgtDiff = new validLianDaWgtDiff();
                    lianDaWgtDiff.ValidMethod(scale, "1", null); //验证毛重
                    if (!PbCache.monitorResult.valid_prediction_diff)
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = PbCache.ResultMessage;
                        return rt;
                    }
                    #endregion

                    #region 验证一次皮与当前毛结净是否符合要求
                    //验证预报超差信息
                    validPredictionDiff vpd = new validPredictionDiff();
                    vpd.ValidMethod(pts, "3", first); //验证净重
                    if (!PbCache.monitorResult.valid_prediction_diff)
                    {
                        rt.result = false;
                        rt.isError = false;
                        return rt;
                    }
                    //一车联运不存在历史皮重验证
                    #endregion

                    //验证计量区域：若二次计量数据的计量区域与一次计量的计量区域不一致，则禁止自助计量；
                    validMeterArea vMeterArea = new validMeterArea();
                    vMeterArea.ValidMethod(first.baseSpotNo);
                    if (!PbCache.monitorResult.valid_meter_area)
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = PbCache.ResultMessage;
                        return rt;
                    }

                    //验证均通过后，则存储数据到数据表中
                    //====所有验证均通过后，此时进行结净=====================
                    //保存皮重信息  即：二次计量信息***********************
                    MeterWorkCarActualFirst secondDb = new MeterWorkCarActualFirst();

                    //相同名称的均赋值一次
                    EntityBase<PreTrackScale> entityBase = new EntityBase<PreTrackScale>();
                    secondDb = entityBase.format<MeterWorkCarActualFirst>(scale, secondDb);

                    secondDb.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
                    secondDb.meterWeight = PbCache.lockWgt;//计量重量
                    secondDb.addWeight = PbCache.addWgt;//附加重量
                    secondDb.weightType = "0"; //0=毛重；1=常规皮重；2=期限皮重；3=历史皮重；4=标识皮重；5=自重皮重
                    secondDb.createManNo = appUser.userid;
                    secondDb.createManName = appUser.username;
                    secondDb.meterGroup = appUser.userGroup;
                    secondDb.meterClass = appUser.userClass;
                    secondDb.createTime = DateTime.Now;
                    secondDb.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
                    secondDb.baseSpotName = PbCache.sportInfo.baseSpotName;
                    //secondDb.memo = "";
                    secondDb.valueFlag = "1"; //0有效
                    secondDb.updateManName = "";
                    secondDb.updateManNo = "";
                    secondDb.updateTime = null;
                    secondDb.checkFlag = "0"; //0未审核
                    secondDb.meterMode = string.IsNullOrEmpty(appUser.userid) ? "2" : "1"; //1远程计量，2智能计量


                    //环节信息
                    MeterWorkPreLink link = new MeterWorkPreLink();
                    link.preLinkNo = rm.Data[0].preLinkNo;
                    link.preProcessNo = rm.Data[0].preProcessNo;

                    //结净数据
                    MeterWorkCarActual netDb = new MeterWorkCarActual();
                    EntityBase<MeterWorkCarActualFirst> entityActual = new EntityBase<MeterWorkCarActualFirst>();
                    netDb = entityActual.format<MeterWorkCarActual>(first, netDb);

                    //netDb.actualFirst1No = first.actualFirstNo; //毛重计量作业编号
                    netDb.grossTime = DateTime.Now;
                    netDb.grossWeight = PbCache.lockWgt;
                    netDb.baseSpot1No = PbCache.sportInfo.baseSpotNo;
                    netDb.baseSpot1Name = PbCache.sportInfo.baseSpotName;
                    netDb.grossMode = string.IsNullOrEmpty(appUser.userid) ? "2" : "1"; //1远程计量，2智能计量
                    netDb.grossGroup = appUser.userGroup;
                    netDb.grossClass = appUser.userClass;
                    netDb.grossManNo = appUser.userid;
                    netDb.grossManName = appUser.username;

                    netDb.actualFirst2No = first.actualFirstNo; //皮重计量作业编号
                    netDb.tareWeight = first.meterWeight; //皮重
                    netDb.tareTime = first.createTime;
                    netDb.baseSpot2No = first.baseSpotNo; //皮重计量点编号
                    netDb.baseSpot2Name = first.baseSpotName; //皮重计量点
                    netDb.tareMode = first.meterMode;//1：远程计量；2：智能计量；3：手工录入；4：放行智能计量；5：滞后匹配
                    netDb.tareClass = first.meterClass;
                    netDb.tareGroup = first.meterGroup;
                    netDb.tareManNo = first.createManNo;
                    netDb.tareManName = first.createManName;
                    netDb.tareTime = first.createTime;
                    //一车联运先皮后毛的附加重量使用的是前一次计量的时候的附加重量值
                    netDb.addWeight = (first.addWeight == null ? 0 : first.addWeight.Value);
                    //净重=毛-皮-附加重量
                    netDb.netWeight = netDb.grossWeight - netDb.tareWeight - netDb.addWeight;
                    netDb.netMode = "1"; //1：正常结净；2：匹配结净
                    netDb.valueFlag = "0"; //0=有效，1=作废
                    netDb.uploadFlag = "0"; //0=待审核；1：待上传；2=已上传
                    netDb.netTime = DateTime.Now;

                    netDb.netManNo = appUser.userid; //净重计量员编码 
                    netDb.netManName = appUser.username; //净重计量员名称
                    netDb.netSpot3No = PbCache.sportInfo.baseSpotNo; //净重计量点编号
                    netDb.netSpot3Name = PbCache.sportInfo.baseSpotName; //净重计量点

                    //操作日志
                    MeterMonitorNote monitorNote = new MeterMonitorNote();
                    monitorNote.baseSpotNo = secondDb.baseSpotNo;
                    monitorNote.baseSpotName = secondDb.baseSpotName;
                    monitorNote.operationContent = string.Format("结净称重保存");
                    monitorNote.operationTime = secondDb.createTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                    monitorNote.carNo = secondDb.carNo;
                    monitorNote.meterNoteSource = string.IsNullOrEmpty(appUser.userid) ? "0" : "4";
                    monitorNote.meterManNo = appUser.userid;
                    monitorNote.meterManName = appUser.username;

                    RESTfulResult<string> rmI = mwcfs.doAddNetWf(secondDb, netDb, link, monitorNote, "", "0");
                    if (rmI.Succeed)
                    {
                        rt.result = true;
                        rt.resultInfo = "称重完成";
                        PbCache.ResultMessage = "称重完成";
                        PbCache.actualFirstNo = rmI.Data;
                        PbCache.strQRCode = rmI.Message;
                        PbCache.isTareWeight = false;//毛重
                        RESTfulResult<string> RESTfulResult = termTareDate.abolishForCSharp(new MeterBaseTermTareData { carNo = netDb.carNo });
                        if (RESTfulResult.Succeed)
                        {
                            if (!string.IsNullOrEmpty(RESTfulResult.Message))
                            {
                                PbCache.ResultMessage = PbCache.ResultMessage + "；请注意期限皮重已作废";
                            }
                        }
                        else
                        {
                            PbCache.ResultMessage = PbCache.ResultMessage + "；作废期限皮重异常，请点击【语音求助】联系计量员";
                        }
                    }
                    else
                    {
                        rt.result = false;
                        rt.isError = true;
                        rt.resultInfo = "称重数据保存失败";
                        PbCache.ResultMessage = "计量失败：" + rmI.ResultMessage;
                    }
                }
                else
                {
                    PbCache.ResultMessage = string.Format("当前预报[{0}]存在多条未结净数据", scale.predictionNo);
                    rt.resultInfo = "找到多条未结净数据";
                    rt.result = false;
                    rt.isError = true;
                }
            }

            return rt;
        }
    }
}
