package com.sy.logic;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.sy.crossDomain.BuildBarCode;
import com.sy.model.*;
import com.sy.relation.VeManifestRelation;
import com.sy.service.EnterCancelServer;
import com.sy.service.LandBusListService;
import com.sy.service.LandRoadVeService;
import com.sy.service.ResMessageService;
import com.sy.socket.CommandClient;
import com.sy.utils.FileTool;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class LogicOperation {

    private static final Logger logger = Logger.getLogger(LogicOperation.class);

    @Autowired
    private LandBusListService listService;

    @Autowired
    private LandRoadVeService veService;

    @Autowired
    private ResMessageService resMessageService;

    @Autowired
    private EnterCancelServer enterCancelServer;

    private static LogicOperation logic = new LogicOperation();

    //读取配置文件里的载重与称重的可控范围
    private static String checkWt = FileTool.readProperties("grossWt");

    //逻辑判断后的结果定义
    private static String PERMITTHOUGH = "直接放行";
    private static String GROWSSEXCETION = "禁止通行,重量不在可控范围";
    private static String NORECORD = "车辆未备案或者识别错误,车牌号:";
    private static String INPUTSTATION = "此车辆未做进站申请";
    private static String ENTERSTATION = "此车辆未做出站申请";
    private static String ISVALID = "二维码数据异常,请使用正确的二维码数据";
    private static String ERRORWT = "出起始场站的重量和进目的场站的重量不一致";
    private static String IEPORSE = "无相对应进出场申请";

    @PostConstruct
    public void init() {
        logic = this;
        logic.listService = this.listService;
        logic.veService = this.veService;
        logic.resMessageService = this.resMessageService;
        logic.enterCancelServer = this.enterCancelServer;
    }

    /**
     * @Param info 卡口采集数据
     * @Result 计算卡口采集数据并发送报文
     */
    public static boolean operation(GatherInfo info) {
        if("综保区".equals(info.getAreaid())){
            //todo 加综保区的判断逻辑
        }
        PropertyConfigurator.configure("config/log4j.properties");
        boolean result = false;
        //转为double类型
        double growssWt = info.getGrosswt().doubleValue();
        //取车牌号,判定卡口是否取到车牌号
        String vaName = info.getVename();
        if (vaName.length() <= 0) {
            CommandClient.Client(info, NORECORD + vaName);
            return result;
        }
        //校验车辆是否备案
        LandRoadVe ve = logic.veService.selectByFrameNo(vaName);
        if (ve == null) {
            CommandClient.Client(info, NORECORD + vaName);
            return result;
        }

        /**
         * 车牌号,二维码,场站ID/号,通道ID/号,进出业务类型标识I/E
         * 查询是否已有此场站通道的申请
         */
        LandBusinessTypeList list = logic.listService.selectForOne(info.getVename(), info.getBarcode(), info.getAreaid(), info.getChnlno(), info.getIetype());
        if (list == null) {
            CommandClient.Client(info, IEPORSE);
            return result;
        }
        //判断是否失效
        if ("0".equals(list.getIsvalid())) {
            //获取总重
            double goodsWt = 0.0;
            if (list.getMasterList() != null || list.getMasterList().length() > 0) {
                String type = null;
                if ("进口提货".equals(list.getBusinesstype()) || "分拨业务".equals(list.getBusinesstype())) {
                    type = "I";
                }
                if ("出口送货".equals(list.getBusinesstype()) || "调拨业务".equals(list.getBusinesstype())) {
                    type = "E";
                }
                logger.info("=======================>>>>>>>>>>" + type + "<<<<<<<<<<========================");
                //获取车辆拉货重量
                goodsWt = logic.GoodsWt(list.getMasterList(), type);
            }
            //车自重
            double selfWt = Double.parseDouble(ve.getSelfWt());

            //重量误差判定,判断过磅重量减去(车备案重量+运单重量)/过磅重量是否在可控范围内
            if (!logic.checkFlag(growssWt, (selfWt + goodsWt))) {
                //根据二维码标识ID找进出场对应申请,并进行过卡数据与申请数据对碰
                List<LandBusinessTypeList> typeLists = logic.listService.selectMessageId(list.getMassageId());
                for (int i = 0; i < typeLists.size(); i++) {
                    //如果业务类型为进口提货,进出业务标识为出场(E),把已检验过进场过卡重量赋为空车重量,否则则取备案重量
                    if ("进口提货".equals(list.getBusinesstype())) {
                        //Turnoverflag()进出场标识
                        if ("E".equals(list.getTurnoverflag())) {
                            //Contrastflag检验标识,Aislewt过卡重量
                            if ("I".equals(typeLists.get(i).getTurnoverflag()) && typeLists.get(i).getContrastflag() != null) {
                                selfWt = typeLists.get(i).getAislewt() > 1 ? typeLists.get(i).getAislewt() : selfWt;
                                break;
                            }
                        }
                    }
                    //
                    if ("出口送货".equals(list.getBusinesstype())) {
                        if ("E".equals(list.getTurnoverflag())) {
                            //判断入场是否正常
                            if ("I".equals(typeLists.get(i).getTurnoverflag()) && typeLists.get(i).getContrastflag() != null) {
                                if ("1".equals(list.getIsfull())) {//
                                    if (list.getMasterList().length() > 0) {
                                        selfWt = typeLists.get(i).getAislewt() - Double.parseDouble(typeLists.get(i).getRemark());
                                    } else {
                                        selfWt = growssWt;
                                    }
                                }
                                break;
                            }
                        }
                    }

                    if (list.getBusinesstype().endsWith("业务")) {
                            if (list.getMasterList().length() > 0) {
                                if ("E".equals(list.getTurnoverflag())) {
                                    if ("I".equals(typeLists.get(i).getTurnoverflag()) && typeLists.get(i).getContrastflag() != null) {
                                        selfWt = typeLists.get(i).getAislewt() > 1 ? typeLists.get(i).getAislewt() : selfWt;
                                        break;
                                    }
                                }
                                if ("I".equals(list.getTurnoverflag())) {
                                    if ("E".equals(typeLists.get(i).getTurnoverflag()) && typeLists.get(i).getContrastflag() != null) {
                                        if (!logic.checkFlag(growssWt, typeLists.get(i).getAislewt())) {
                                            logger.info("-------->>>>>>>>出起始场站的重量和进目的场站的总量不一致<<<<<<<<--------");
                                            CommandClient.Client(info, ERRORWT);
                                            return result;
                                        }
                                    }
                                }
                            }
                        }
                }
            }
            //校验重量开始
            boolean checkResult = false;
            boolean check = false;
            boolean checkMainfest =false;

            if(!"普通货".equals(list.getCocode())){
                checkResult = true;
            }else if(list.getEndstation().equals("4600329012") || list.getEndstation().equals("4612199001")){
                checkResult = true;
            }else{
               check = logic.checkResult(growssWt, selfWt, goodsWt);
               checkMainfest = logic.checkManifest(list.getMasterList());

                if ("E".equals(list.getTurnoverflag())) {
                    checkResult = checkMainfest || check;
                } else {
                    checkResult = check || checkMainfest;
                }

                //宽进
                if ("I".equals(info.getIetype())) {
                    if (check == false && checkResult == false) {
                        checkResult = true;
                    }
                }
                logger.info("重量校验结果:" + check + ",运单校验结果:" + checkMainfest + ",最终校验结果:" + checkResult);
            }

            if (logic.sendBw(info, checkResult)) {
                if ("I".equals(info.getIetype())) {
                    //    LandRoadVe veName = logic.veService.selectByFrameNo(vaName);
                    list.setAislewt(info.getGrosswt().doubleValue());
                    list.setUpdateDate(new Date());
                    list.setRemark(String.format("%.1f", goodsWt));
                    list.setRemark2(ve.getSelfWt());
                    list.setContrastflag("已进站");
                    logic.checkData(list);
                } else {
                    List<LandBusinessTypeList> typeLists = logic.listService.selectMessageId(list.getMassageId());
                    //进出相差重量
                    double diffVal = 0;
                    for (int i = 0; i < typeLists.size(); i++) {
                        if ("I".equals(typeLists.get(i).getTurnoverflag()) && typeLists.get(i).getEndstation().equals(list.getEndstation())) {
                            System.out.println(typeLists.get(i).getAislewt());
                            System.out.println(growssWt);
                            diffVal = typeLists.get(i).getAislewt() - growssWt;
                            break;
                        }
                    }
                    LandRoadVe veName = logic.veService.selectByFrameNo(vaName);
                    list.setAislewt(info.getGrosswt().doubleValue());
                    list.setUpdateDate(new Date());
                    list.setRemark(String.format("%.1f", goodsWt));
                    list.setRemark1(String.format("%.1f", diffVal));
                    list.setRemark2(veName.getSelfWt());
                    list.setContrastflag("已出站");
                    logic.checkData(list);
                }
                int row = logic.listService.updateById(list);
                List<LandBusinessTypeList> businessTypeLists = logic.listService.selectByBarcode(info.getBarcode());
                int count = 0;
                for (int i = 0; i < businessTypeLists.size(); i++) {
                    String flag1 = businessTypeLists.get(i).getContrastflag();
                    if (flag1 != null) {
                        count++;
                    }
                }

                //决定所有业务走完 二维是否失效
                if (list.getBusinesstype().indexOf("业务") > 0) {
                    logic.inOrUpEnterCancel(list);
                    if (count == 4) {
                        BuildBarCode.cancleBarCode(vaName);
                        logic.listService.updateByBarcode(info.getBarcode());
                    }else if(count==6){
                        BuildBarCode.cancleBarCode(vaName);
                        logic.listService.updateByBarcode(info.getBarcode());
                    }
                } else if(list.getBusinesstype().equals("出口送货") && list.getEndport().equals("4620")){
                    if(list.getIsthree().equals("0")){
                        if(count==4){
                            BuildBarCode.cancleBarCode(vaName);
                            logic.listService.updateByBarcode(info.getBarcode());
                        }
                    }else{
                        if(count==2){
                            BuildBarCode.cancleBarCode(vaName);
                            logic.listService.updateByBarcode(info.getBarcode());
                        }
                    }


                }else{
                    if (count == 2 && !list.getEndport().equals("4620")) {
                        BuildBarCode.cancleBarCode(vaName);
                        logic.listService.updateByBarcode(info.getBarcode());
                    }
                }
                result = true;
            }
            if(list.getMasterList().length()>0){
                boolean flag = VeManifestRelation.createFile(list);
                if(flag){
                    logger.info(">>>>>>>>>>-----车单关系报文生成成功-----<<<<<<<<<<<<");
                }
            }
        } else {
            sendError(info);
            logger.error("------->>>>>>>二维码数据异常,请使用正确的二维码数据<<<<<<<-----");
        }
        return result;
    }

    //将获取的checkWt进行小数转化
    public static double valueDob() {
        NumberFormat nf = NumberFormat.getPercentInstance();
        Number m = null;
        try {
            m = nf.parse(checkWt);//将百分数转换成Number类型
        } catch (ParseException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        return m.doubleValue();
    }

    /**
     * 校验载重和称重是否在合理的范围
     *
     * @Param grossWt 地磅称重
     * @Param wt 车辆自重
     * @Param goodsWt 货物总重
     * @Result 获取运单重量
     */
    public boolean checkResult(double grossWt, double wt, double goodsWt) {
        DecimalFormat df = new DecimalFormat("0.00");
        boolean flag = false;
        double result = 0.0;
        if (goodsWt > 0) {
            result = Double.parseDouble(df.format(Math.abs((goodsWt + wt - grossWt)) / grossWt));
        } else {
            result = Double.parseDouble(df.format(Math.abs((grossWt - wt)) / grossWt));
        }
        if (result <= valueDob()) {
            flag = true;
        }
        return flag;
    }

    /**
     * @Param mainifast 主单列表
     * @Param ietype 进出标志
     * 获取货物总重
     */
    public double GoodsWt(String mainifast, String ietype) {
        Double sum = 0.0;
        if (mainifast.length() > 0) {
            String[] mainifastList = mainifast.split(",");
            for (String mainBill : mainifastList) {
                sum += getGrossWt(mainBill, ietype);
            }
        }
        return sum;
    }

    /**
     * @Param waybill 主单号
     * @Param imp 进出港标识
     * @Result 获取运单重量
     */
    public double getGrossWt(String waybill, String imp) {
        logger.info("进入获取重量action");
        if (!(waybill.indexOf("-") != -1)) {
            waybill = waybill.substring(0, 3) + "-" + waybill.substring(3);
        }
        String url = "http://10.50.3.82:8081/orig/orig?waybill=" + waybill + "&imp=" + imp;
        //  String url = "http://tjfx.15miaoo.com:8003/tj/orig/orig?waybill=" + waybill + "&imp=" + imp;
        StringBuilder json = new StringBuilder();
        Map map = null;
        double bg = 0;
        try {
            URL Url = new URL(url);
            URLConnection yc = Url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(), "utf-8"));
            String inputLine = null;
            while ((inputLine = in.readLine()) != null) {
                json.append(inputLine);
            }
            logger.info("返回数据:" + json);
            JSONArray array = JSONArray.parseArray(json.toString());
            for (int i = 0; i < array.size(); i++) {
                map = JSON.parseObject(array.getString(i));
                if (map.containsKey("receiptinformation")) {
                    if (map.get("receiptinformation").toString().startsWith("41301") || map.get("receiptinformation")
                            .toString().startsWith("41106") || map.get("receiptinformation")
                            .toString().startsWith("31301") || map.get("receiptinformation")
                            .toString().startsWith("31106") || map.get("receiptinformation")
                            .toString().indexOf("提运单放行") != -1) {
                        logger.info(map);
                        bg = Double.parseDouble((String) map.get("totalweight"));
                        logger.info("for循环取重量:" + bg);
                        return bg;
                    }
                }
            }
            logger.info("访问返回的数据重量:" + bg);
            in.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            logger.error(e);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e);
        }
        return bg;
    }

    /**
     * 查询运单是否全部放行
     *
     * @param manifestList
     * @return
     */
    public boolean checkManifest(String manifestList) {
        if (manifestList.length() < 1) return false;
        manifestList = manifestList.replace("-", "");
        String[] maifest = manifestList.split(",");
        boolean flag = false;
        int count = 0;
        for (int i = 0; i < maifest.length; i++) {
            RESMESSAGE resmessage = logic.resMessageService.selectByManifest(maifest[i]);
            if (resmessage != null) {
                if ("11".equals(resmessage.getResponsecode())) {
                    count++;
                }
            }
        }
        if (count == maifest.length) {
            flag = true;
        }
        return flag;
    }


    /**
     * 给码头发送卡口数据
     *
     * @param stationCode
     * @param carNo
     * @param IEtype
     */
    public static void sendData(String stationCode, String carNo, boolean IEtype) {
        String url = "http://10.50.3.73:8080/air-api/car/channelCar?stationCode=" + stationCode + "&carNo=" + carNo + "&isPickup=" + IEtype;
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity entity = httpResponse.getEntity();
            String entityStr = EntityUtils.toString(entity);
            logger.info("------------>>>>>>>>>>>>>>发送车辆信息:{stationCode:" + stationCode + ",carNo:" + carNo + ",isPickup:" + IEtype + "}");
            logger.info("------------>>>>>>>>>>>>>>响应返回内容:" + entityStr + "<<<<<<<<<<<<-----------");
        } catch (Exception e) {
            logger.info(e.toString());
        }
    }

    /**
     * 给码头发送卡口数据
     *
     * @param list
     */
    public void checkData(LandBusinessTypeList list) {
        String sationCode = null;
        boolean flag = false;
        if ("出口送货".equals(list.getBusinesstype()) || "出口流转".equals(list.getBusinesstype())) {
            flag = false;
        }
        if ("进口提货".equals(list.getBusinesstype()) || "进口流转".equals(list.getBusinesstype())) {
            flag = true;
        }
        if ("4604000000".equals(list.getEndstation())) {
            if ("I".equals(list.getTurnoverflag())) {
                sationCode = "HK05";
            } else {
                sationCode = "HK06";
            }
            //TODO:加场站判定
        }
        sendData(sationCode, list.getTrailerFrameNo(), flag);
    }


    /**
     * 校验重量并发送报文
     */

    public boolean sendBw(GatherInfo info, boolean check) {
        logger.info(String.format("开始发送指令:车牌%s,场站%s,通道%s,重量%s",info.getVename(),info.getAreaid(),info.getChnlno(),info.getGrosswt()));
        boolean flag = false;
        if (check) {
            CommandClient.Client(info, PERMITTHOUGH);
            logger.info("=============>>>>>>>>放行报文发送成功<<<<<<<<<==============");
            flag = true;
        } else {
            CommandClient.Client(info, GROWSSEXCETION);
            logger.info("=============>>>>>>>>重量异常报文发送成功<<<<<<<<<==============");
        }
        return flag;
    }

    /**
     * 排除当前系统问题发送错误commandInfo
     */
    public static void sendError(GatherInfo info) {
        CommandClient.Client(info, ISVALID);
    }

    /**
     * 判断空车加运单与地磅称重是否在合理范围
     *
     * @param grossWt
     * @param wt
     * @return
     */
    public boolean checkFlag(double grossWt, double wt) {
        DecimalFormat df = new DecimalFormat("0.00");
        boolean flag = false;
        double reult = Double.parseDouble(df.format(Math.abs((grossWt - wt)) / grossWt));
        if (reult <= valueDob()) {
            flag = true;
        }
        return flag;
    }

    /**
     * 生成或者更新货物冻结标识
     *
     * @param landBusinessTypeList
     */
    public void inOrUpEnterCancel(LandBusinessTypeList landBusinessTypeList) {
        if (landBusinessTypeList.getMasterList().length() < 1) return;
        String[] list = landBusinessTypeList.getMasterList().split(",");
        String flag = null;
        for (int i = 0; i < list.length; i++) {
            if("调拨业务".equals(landBusinessTypeList.getBusinesstype())){
                flag = "E";
            }else {
                flag = "I";
            }
            double wt = getGrossWt(list[i],flag);

            ENTERCANCCEL entercanccel = logic.enterCancelServer.selectByManifest(list[i]);
            if (entercanccel != null) {
                if(entercanccel.getVename().equals(landBusinessTypeList.getTrailerFrameNo())){
                    if ("0".equals(entercanccel.getIsfreeze())) {
                        entercanccel.setIsfreeze("1");
                        entercanccel.setEndport(landBusinessTypeList.getEndstation());
                        entercanccel.setUpdateBy(landBusinessTypeList.getCreateBy());
                        entercanccel.setUpdateTime(new Date());
                        logic.enterCancelServer.updateByPermaryKey(entercanccel);
                    }
                }
            }else {
                if("E".equals(landBusinessTypeList.getTurnoverflag())){
                    ENTERCANCCEL canccel = new ENTERCANCCEL();
                    canccel.setIsfreeze("0");
                    canccel.setVename(landBusinessTypeList.getTrailerFrameNo());
                    canccel.setId(String.valueOf(System.currentTimeMillis()));
                    canccel.setVeCompanyName(landBusinessTypeList.getAgentno());
                    canccel.setBusinesstype(landBusinessTypeList.getBusinesstype());
                    canccel.setManifest(list[i]);
                    canccel.setAgentname(landBusinessTypeList.getAgentname());
                    canccel.setStartport(landBusinessTypeList.getEndstation());
                    canccel.setGrosswt(landBusinessTypeList.getAislewt());
                    canccel.setCreateBy(landBusinessTypeList.getCreateBy());
                    canccel.setCreateTime(new Date());
                    canccel.setUpdateBy(landBusinessTypeList.getCreateBy());
                    canccel.setUpdateTime(new Date());
                    canccel.setWeight(wt);
                    logic.enterCancelServer.insertEntry(canccel);
                }

            }
        }
    }


}