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

namespace MeterSceneLibrary
{
    public class InnerDoubleJISCO
    {
        // 一次计量数据
        private MeterWorkCarActualFirstService mwcfs = new MeterWorkCarActualFirstService();

        // 重量类型预处理表
        private MeterWorkPreWgttypeService wgttypeService = new MeterWorkPreWgttypeService();

        // 车辆委托表
        private PreTrackScaleService preTrackScaleService = new PreTrackScaleService();

        // 留期限皮操作
        private MeterBaseTermTareDataService termTareDate = new MeterBaseTermTareDataService();

        private MeterBaseSpotInfoService meterBaseSpotInfoService = new MeterBaseSpotInfoService();

        private rtInfo rt = new rtInfo();

        // 构建一次计量数据
        private MeterWorkCarActualFirst mwaf = new MeterWorkCarActualFirst();

        private MeterBaseCarService carService = new MeterBaseCarService();

        private MeterBaseSpecialUnitService meterBaseSpecialUnitService = new MeterBaseSpecialUnitService();

        // 结净最小值，默认取配置文件
        private double diffrentWgt = AppConfigCache.differenceWgt;

        // 根据称点查询监控信息
        private RESTfulResult<List<MeterWorkMonitor>> listMonitor;

        // 根据车号查询委托表中未使用和使用中的委托
        private List<PreTrackScale> listPreScale;

        private JISCO.SaveMethod saveMethod = new JISCO.SaveMethod();

        private ComBaseInfoService comBaseInfoService = new ComBaseInfoService();

        private MeterBaseTermTareDataService meterBaseTermTareDataService = new MeterBaseTermTareDataService();

        public rtInfo MeterMethod(PreTrackScale scale)
        {
            Log lg = Log.GetInstance();
            rt.isError = false;

            string ResultMessage = "";
            bool isError = false;

            //根据称点查询监控信息
            MeterWorkMonitorService meterWorkMonitorService = new MeterWorkMonitorService();
            listMonitor = meterWorkMonitorService.doQueryOneWf(new MeterWorkMonitor { pointNo = PbCache.sportInfo.baseSpotNo });

            mwaf.carNo = PbCache.lockCarNo;
            mwaf.weightType = "";  // 默认重量类型为空
            mwaf.actualFirstNo = DateTime.Now.ToString("yyyyMMdd");//10
            mwaf.meterWeight = PbCache.lockWgt;//计量重量
            mwaf.addWeight = PbCache.addWgt;//附加重量
            mwaf.createManNo = "admin";
            mwaf.createManName = "admin";
            mwaf.meterGroup = "";
            mwaf.meterClass = "";
            mwaf.createManNo = "SYSTEM";
            mwaf.createManName = "system";
            mwaf.createTime = DateTime.Now;
            mwaf.baseSpotNo = PbCache.sportInfo.baseSpotNo;//计量点编号
            mwaf.baseSpotName = PbCache.sportInfo.baseSpotName;
            //mwaf.memo = "";
            mwaf.valueFlag = "1"; //状态（0 = 作废，1 = 有效(已匹配)，2 = 结净）
            mwaf.updateManName = "";
            mwaf.updateManNo = "";
            mwaf.updateTime = null;
            mwaf.checkFlag = "1"; //0未审核,1已审核
            mwaf.meterMode = "2"; //1：远程计量；2：智能计量；3：手工录入；4：放行智能计量；5：滞后匹配
            mwaf.addWeight = PbCache.addWgt;
            mwaf.dataSource = "1"; //数据来源(1=智能终端，2=本地计量，3=应急计量，4=手动录入(计量票据录入))
            PbCache.isActual = false;
            PbCache.isInnerCar = false;
            PbCache.ResultMessage = "";
            PbCache.monitorResultMessage = "";
            PbCache.LEDResultMessage = "";

            PbCache.yardActual = null;
            PbCache.yardFirst = null;

            // 根据车号查询重量类型预处理表
            RESTfulResult<List<MeterWorkPreWgttype>> rmX = wgttypeService.doQueryWf(new MeterWorkPreWgttype { carNo = PbCache.lockCarNo, valueFlag = "1" });

            if (rmX.Succeed)
            {
                List<MeterWorkPreWgttype> list = rmX.Data;

                // 不存在一次预处理数据
                if (list == null || list.Count == 0)
                {
                    /* a. 程序报警
                     * b. 自动进行语音求助
                     */
                    rt = saveMethod.doError("未选择称重类型，请选择后开始计量");
                    PbCache.voiceType = 21;
                    PbCache.monitorResultMessage = "未选择称重类型，请选择后开始计量";
                    PbCache.LEDResultMessage = "未选择称重类型，请选择后开始计量";
                    PbCache.ResultMessage = "未选择称重类型，请选择后开始计量";
                    return rt;
                }
                else if (list == null || list.Count == 1)
                {
                    // 历史皮重验证
                    // 001033002：皮重
                    rt = saveMethod.validHisTare2(list[0].weightTypeNo);
                    if (list[0].weightTypeNo == "001033002" && PbCache.monitorResult.valid_wgt == false && listMonitor.Data[0].validWgt == "1")
                    {
                        PbCache.ResultMessage = "毛皮类型选错，请重新选择";
                        PbCache.LEDResultMessage = "计量失败，毛皮类型选错，请重新选择";
                        PbCache.voiceType = 26;
                        rt = saveMethod.doError(PbCache.ResultMessage);
                        rt.isWarn = true;
                        rt.WarnContent = "validWgt";
                        return rt;
                    }
                    // 001033001：毛重
                    if (list[0].weightTypeNo == "001033001" && PbCache.monitorResult.valid_wgt == true && listMonitor.Data[0].validWgt == "1")
                    {
                        PbCache.ResultMessage = "毛皮类型选错，请重新选择";
                        PbCache.LEDResultMessage = "计量失败，毛皮类型选错，请重新选择";
                        PbCache.voiceType = 23;
                        rt = saveMethod.doError(PbCache.ResultMessage);
                        rt.isWarn = true;
                        rt.WarnContent = "validWgt";
                        return rt;
                    }

                    // 查已选择的委托
                    RESTfulResult<List<PreTrackScale>> rmScale = preTrackScaleService.doQueryByFlag(new PreTrackScale { carNo = PbCache.lockCarNo, lineDesc = "1" });

                    // 查询一次计量数据表
                    RESTfulResult<List<MeterWorkCarActualFirst>> rmFirst = mwcfs.doQueryByFlag(new MeterWorkCarActualFirst { carNo = PbCache.lockCarNo });

                    //查询车辆是否存在配置
                    RESTfulResult<List<ComBaseInfo>> comBaseInfos = comBaseInfoService.doQueryBaseList(new ComBaseInfo { pBaseCode = "001048", validFlag = "1",baseName = PbCache.lockCarNo });

                    //查询车辆是否存在期限皮重信息
                    RESTfulResult<MeterBaseTermTareData> termTareData = meterBaseTermTareDataService.doQueryPageWf(new MeterBaseTermTareData { carNo = PbCache.lockCarNo, valueFlag = "0", spotAreaNo = PbCache.sportInfo.spotAreaNo });

                    List<MeterWorkCarActualFirst> firstList = rmFirst.Data;
                    //判断已选择的委托是否为1条
                    if (rmScale.Succeed && rmScale.Data.Count == 1)
                    {
                        mwaf.weightType = "0";

                        if (rmFirst.Succeed)
                        {
                            //不存在一次计量数据
                            if (firstList == null || firstList.Count == 0)
                            {
                                if (comBaseInfos.Succeed)
                                {
                                    //判断车辆是否满足期限皮
                                    if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                    {
                                        if (termTareData.Succeed)
                                        {
                                            //判断车辆是否存在期限皮重
                                            if (termTareData.Data == null)
                                            {
                                                // 只保存一次计量数据
                                                rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                                PbCache.voiceType = 15;
                                                rt.resultInfo = "计量成功，期限皮过期，请留存期限皮";
                                                PbCache.ResultMessage = "计量成功，期限皮过期，请留存期限皮";
                                                PbCache.monitorResultMessage = "计量成功，期限皮过期，请留存期限皮";
                                                PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，计量完成，期限皮过期", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                            }
                                            else
                                            {
                                                // 存在期限皮重，并使用期限皮重结净
                                                EntityBase<PreTrackScale> entityBase1 = new EntityBase<PreTrackScale>();
                                                mwaf = entityBase1.format<MeterWorkCarActualFirst>(rmScale.Data[0], mwaf);
                                                rt = saveMethod.doTermTareNetDouble(rmScale.Data[0], scale, mwaf, "0");
                                                rt.resultInfo += "，期限皮结净";
                                                PbCache.voiceType = 16;
                                                PbCache.ResultMessage = "计量完成，期限皮结净";
                                                PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，净重{2}吨，期限皮结净", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(PbCache.lockWgt - termTareData.Data.meterWeight.Value) / 1000), 2));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // 只保存一次计量数据
                                        rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                        PbCache.voiceType = 1;
                                        PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，计量完成", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                    }
                                }
                            }
                            //存在一条一次计量数据
                            else if (firstList.Count == 1)
                            {
                                //存在的一次数据为毛重
                                if (firstList[0].weightType == "0")
                                {
                                    if (comBaseInfos.Succeed)
                                    {
                                        //判断车辆是否满足期限皮
                                        if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                        {
                                            if (termTareData.Succeed)
                                            {
                                                //判断车辆是否存在期限皮重
                                                if (termTareData.Data == null)
                                                {
                                                    // 只保存一次计量数据
                                                    rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                                    PbCache.voiceType = 17;
                                                    rt.resultInfo = "计量成功，期限皮过期，存在未结净毛重";
                                                    PbCache.ResultMessage = "计量成功，期限皮过期，存在未结净毛重";
                                                    PbCache.monitorResultMessage = "计量成功，期限皮过期，存在未结净毛重";
                                                    PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，计量完成，期限皮过期", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                                }
                                                else
                                                {
                                                    // 存在期限皮重，并使用期限皮重结净
                                                    EntityBase<PreTrackScale> entityBase1 = new EntityBase<PreTrackScale>();
                                                    mwaf = entityBase1.format<MeterWorkCarActualFirst>(rmScale.Data[0], mwaf);
                                                    rt = saveMethod.doTermTareNetDouble(rmScale.Data[0], scale, mwaf, "0");
                                                    rt.resultInfo += "，期限皮结净";
                                                    PbCache.voiceType = 16;
                                                    PbCache.ResultMessage = "计量完成，期限皮结净";
                                                    PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，净重{2}吨，期限皮结净", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(PbCache.lockWgt - termTareData.Data.meterWeight.Value) / 1000), 2));
                                                }
                                            }
                                        }
                                        else
                                        {
                                            // 只保存一次计量数据
                                            rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                            rt.resultInfo += "，存在未结净毛重";
                                            PbCache.voiceType = 17;
                                            PbCache.ResultMessage = "存在未结净毛重";
                                            PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，存在未结净毛重，请联系", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                            PbCache.monitorResultMessage = "存在未结净毛重";
                                            rt.isWarn = true;
                                            rt.WarnContent = "validWgt";
                                        }
                                    }
                                }
                                //存在的一次数据为皮重
                                else
                                {
                                    if (comBaseInfos.Succeed)
                                    {
                                        //判断车辆是否满足期限皮
                                        if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                        {
                                            if (termTareData.Succeed)
                                            {
                                                // 存在期限皮重，并使用期限皮重结净
                                                EntityBase<PreTrackScale> entityBase1 = new EntityBase<PreTrackScale>();
                                                mwaf = entityBase1.format<MeterWorkCarActualFirst>(rmScale.Data[0], mwaf);
                                                rt = saveMethod.doTermTareNetDoubleRetain(rmScale.Data[0], scale, firstList[0], mwaf, "0");
                                                rt.resultInfo += "，留存期限皮成功";
                                                PbCache.voiceType = 16;
                                                PbCache.ResultMessage = "计量完成，留存期限皮成功";
                                                PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，净重{2}吨，留存期限皮成功", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(PbCache.lockWgt - firstList[0].meterWeight.Value) / 1000), 2));
                                            }
                                        }
                                        else
                                        {
                                            // 只保存一次计量数据
                                            rt = saveMethod.doAddDoubleNet(rmScale.Data[0], scale, firstList[0], mwaf,"0");
                                            PbCache.voiceType = 1;
                                            PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，净重{2}吨，双委托结净", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2),Math.Round((Math.Abs(PbCache.lockWgt - firstList[0].meterWeight.Value) / 1000), 2));
                                        }
                                    }
                                }
                            }
                            //存在多条一次计量数据
                            else
                            {
                                if (comBaseInfos.Succeed)
                                {
                                    //判断车辆是否满足期限皮
                                    if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                    {
                                        if (termTareData.Succeed)
                                        {
                                            //判断车辆是否存在期限皮重
                                            if (termTareData.Data == null)
                                            {
                                                // 只保存一次计量数据
                                                rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                                PbCache.voiceType = 15;
                                                rt.resultInfo = "计量成功，期限皮过期，存在多条未结净数据";
                                                PbCache.ResultMessage = "计量成功，期限皮过期，存在多条未结净数据";
                                                PbCache.monitorResultMessage = "计量成功，期限皮过期，存在多条未结净数据";
                                                PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，计量完成，期限皮过期", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                            }
                                            else
                                            {
                                                // 存在期限皮重，并使用期限皮重结净
                                                EntityBase<PreTrackScale> entityBase1 = new EntityBase<PreTrackScale>();
                                                mwaf = entityBase1.format<MeterWorkCarActualFirst>(rmScale.Data[0], mwaf);
                                                rt = saveMethod.doTermTareNetDouble(rmScale.Data[0], scale, mwaf, "0");
                                                rt.resultInfo += "，期限皮结净";
                                                PbCache.voiceType = 16;
                                                PbCache.ResultMessage = "计量完成，期限皮结净";
                                                PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，净重{2}吨，期限皮结净", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(PbCache.lockWgt - termTareData.Data.meterWeight.Value) / 1000), 2));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // 只保存一次计量数据
                                        rt = saveMethod.doAddDoubleFirst(rmScale.Data[0], scale, mwaf);
                                        rt.resultInfo += "，存在多条未结净数据";
                                        PbCache.voiceType = 11;
                                        PbCache.ResultMessage = "存在多条未结净数据";
                                        PbCache.LEDResultMessage = string.Format("车号{0}，毛重{1}吨，存在多条未结净数据，请联系", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                        PbCache.monitorResultMessage = "存在未结净毛重";
                                        rt.isWarn = true;
                                        rt.WarnContent = "validWgt";
                                    }
                                }
                            }
                        }
                    }
                    //判断已选择的委托是否为0条
                    else if (rmScale.Succeed && rmScale.Data.Count == 0)
                    {
                        mwaf.weightType = "1";
                        //不存在一次计量数据
                        if (firstList == null || firstList.Count == 0)
                        {
                            // 只保存一次计量数据
                            rt = saveMethod.doAddFirst(null, mwaf);
                            PbCache.voiceType = 1;
                            PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，计量完成", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                        }
                        //存在一条一次计量数据
                        else if (firstList.Count == 1)
                        {
                            //存在的一次数据为毛重
                            if (firstList[0].weightType == "0")
                            {
                                if (comBaseInfos.Succeed)
                                {
                                    //判断车辆是否满足期限皮
                                    if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                    {
                                        RESTfulResult<List<PreTrackScale>> scales = preTrackScaleService.doQueryWf(new PreTrackScale { predictionNo = firstList[0].predictionNo });
                                        // 存在期限皮重，并使用期限皮重结净
                                        EntityBase<PreTrackScale> entityBase1 = new EntityBase<PreTrackScale>();
                                        mwaf = entityBase1.format<MeterWorkCarActualFirst>(scales.Data[0], mwaf);
                                        rt = saveMethod.doTermTareNetDoubleRetain(scales.Data[0], scale, mwaf, firstList[0], "1");
                                        rt.resultInfo += "，留存期限皮成功";
                                        PbCache.voiceType = 16;
                                        PbCache.ResultMessage = "计量完成，留存期限皮成功";
                                        PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，净重{2}吨，留存期限皮成功", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(PbCache.lockWgt - termTareData.Data.meterWeight.Value) / 1000), 2));
                                    }
                                    else
                                    {
                                        // 只保存一次计量数据
                                        rt = saveMethod.doAddDoubleNet(rmScale.Data[0], scale, mwaf, firstList[0], "1");
                                        PbCache.voiceType = 1;
                                        PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，净重{2}吨，双委托结净", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2), Math.Round((Math.Abs(firstList[0].meterWeight.Value - PbCache.lockWgt) / 1000), 2));
                                    }
                                }
                            }
                            //存在的一次数据为皮重
                            else
                            {
                                //保存一条作废的皮重数据
                                mwaf.weightType = "1";
                                mwaf.valueFlag = "0";
                                PbCache.voiceType = 1;
                                rt = saveMethod.doAddFirst(null, mwaf);
                                PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，计量完成", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                            }
                        }
                        //存在多条一次计量数据
                        else
                        {
                            List<MeterWorkCarActualFirst> mwcafListDouble = new List<MeterWorkCarActualFirst>();
                            foreach (var item in firstList)
                            {
                                if (!string.IsNullOrEmpty(item.predictionCombination))
                                {
                                    mwcafListDouble.Add(item);
                                }
                            }
                            List<MeterWorkCarActualFirst> mwcafList = new List<MeterWorkCarActualFirst>();
                            MeterWorkCarActualFirst meterWorkCarActualFirst = mwcafListDouble[0];
                            mwcafList.Add(meterWorkCarActualFirst);
                            foreach (var item in mwcafListDouble)
                            {
                                if (!string.IsNullOrEmpty(item.predictionCombination))
                                {
                                    if (meterWorkCarActualFirst.predictionCombination == item.predictionCombination && meterWorkCarActualFirst.actualFirstNo != item.actualFirstNo) 
                                    {
                                        mwcafList.Add(item);
                                        break;
                                    };
                                }
                            }
                            if (comBaseInfos.Succeed)
                            {
                                //判断车辆是否满足期限皮
                                if (comBaseInfos.Data != null && comBaseInfos.Data.Count == 1)
                                {
                                    // 存在期限皮重，并使用期限皮重结净
                                    rt = saveMethod.doNetAddMuchGrossDouble(mwcafListDouble, mwaf);
                                    rt.resultInfo += "，留存期限皮成功";
                                    PbCache.voiceType = 16;
                                    PbCache.ResultMessage = "计量完成，留存期限皮成功";
                                    PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，留存期限皮成功", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));
                                }
                                else
                                {
                                    // 双委托不使用期限皮结净
                                    rt = saveMethod.doAddDoubleMuchNet(mwcafList, mwaf);
                                    PbCache.voiceType = 1;
                                    PbCache.LEDResultMessage = string.Format("车号{0}，皮重{1}吨，计量完成", PbCache.lockCarNo, Math.Round((PbCache.lockWgt / 1000), 2));

                                }
                            }
                        }
                    }
                    //判断已选择的委托是否为多条
                    else
                    {
                        rt = saveMethod.doError("存在多条已选择的委托，请联系计量大厅");
                        PbCache.LEDResultMessage = "存在多条已选择的委托，请联系计量大厅";
                        rt.isWarn = true;
                        PbCache.voiceType = 19;
                        rt.WarnContent = "validIsPre";
                        return rt;
                    }
                }
                else
                {
                    rt = saveMethod.doError("存在多条上称申请数据，请联系计量大厅");
                    PbCache.voiceType = 20;
                    PbCache.LEDResultMessage = "存在多条上称申请数据，请联系计量大厅";
                    return rt;
                }
            }

            // 后台失败处理
            if (!rt.result)
            {
                rt.resultInfo = "称重数据保存失败";
                PbCache.voiceType = 25;
                PbCache.LEDResultMessage = "计量失败，请联系计量大厅";
                PbCache.monitorResultMessage = "";
            }
            return rt;
        }
    }
}
