package com.steering.pss.plnsaleord.ordAmCal;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import CoreFS.SA08.CoreXmlSqlParsersFactory;

import com.steering.pss.plnsaleord.lenthCal.CoreLenCalculate;
import com.steering.pss.plnsaleord.lenthCal.CoreLenRecalCulation;
import com.steering.pss.plnsaleord.lenthCal.LenCalculateInObject;
import com.steering.pss.plnsaleord.lenthCal.LenCalculateOutObject;
import com.steering.pss.plnsaleord.ordAmCal.model.InZgOrdCalEntity;
import com.steering.pss.plnsaleord.ordAmCal.model.OutZgOrdCalEntity;

/**
 * 轧管工序投料量计算
 * @author xiaohai
 */
public class PlnZgProcCal {
    /**
     * 圆周率
     */
    private static double pi = 3.1415926;

    private static String errMessage = "";

    /**
     * 计算轧管工序投料量
     * @param _ordEntity
     * @return
     */
    public static OutZgOrdCalEntity getZgOrdCal(Connection conn,
            InZgOrdCalEntity _ordEntity, Boolean flag) {
        OutZgOrdCalEntity ordCal = new OutZgOrdCalEntity();
        LenCalculateInObject lenCalIn = new LenCalculateInObject();
        LenCalculateOutObject lenCalOut = new LenCalculateOutObject();
        PreparedStatement ps = null;
        ResultSet rs = null;

        double dimete = 0;// 管坯断面（mm）
        double weightMi = 0;// 管坯米单重（t/m）
        double lenGp = 0;// 管坯长度（m）
        int cutNum = 0;// 单坯分切数
        double invenWt = 0;
        int invenNum = 0;
        double aimWallthick = 0;
        if (!confirmInf(_ordEntity)) {
            ordCal.setErrCode(-1);
            ordCal.setErrMessage(errMessage);
            return ordCal;
        }
        try {
            // 查询测量J值和平均长度大于
            String sql = CoreXmlSqlParsersFactory
                    .getSql("CoreGetOrdAmount.getChekJAve");
            ps = conn.prepareStatement(sql);
            ps.setObject(1, _ordEntity.getOrdLnDlyPk());
            rs = ps.executeQuery();
            if (rs.next()) {
                lenCalIn.setAvgLenMin(rs.getDouble("AVG_LEN_MIN"));
                lenCalIn.setCheckJVal(rs.getDouble("CHECK_J_VAL"));
            }
            else {
                lenCalIn.setAvgLenMin(0.0);
                lenCalIn.setCheckJVal(0.0);
            }
            rs.close();
            ps.close();

            aimWallthick = _ordEntity.getWallthick();
            lenCalIn.setTubeEndRatio(_ordEntity.getTubeEndRatio());
            lenCalIn.setOutdiameter(_ordEntity.getDiameter());
            lenCalIn.setWallthick(_ordEntity.getWallthick());
            lenCalIn.setWallUpper(_ordEntity.getWallUpper());
            lenCalIn.setWallLower(_ordEntity.getWallLower());
            lenCalIn.setAimUpper(_ordEntity.getAimUpper());
            lenCalIn.setAimLower(_ordEntity.getAimLower());
            lenCalIn.setShrtstove(_ordEntity.getShrtstove());
            lenCalIn.setSigllen(_ordEntity.getSigllen());
            lenCalIn.setBurning(_ordEntity.getBurning());
            lenCalIn.setDiameter(_ordEntity.getDiame());
            lenCalIn.setLengthmax(_ordEntity.getLengmax());
            lenCalIn.setLengthmin(_ordEntity.getLengmin());
            lenCalIn.setLengthmaxZg(_ordEntity.getLengthmax());
            lenCalIn.setLengthminZg(_ordEntity.getLengthmin());
            lenCalIn.setCutheadtail(_ordEntity.getCutHeadEnd() / 1000);
            lenCalIn.setBilletmax(_ordEntity.getLengthMaxRing());
            lenCalIn.setSizing(_ordEntity.getLengthColdbed());
            lenCalIn.setFootmin(_ordEntity.getShortest());
            lenCalIn.setLengthMinTube(_ordEntity.getLengthMinTube());
            lenCalIn.setLengthMaxTube(_ordEntity.getLengthMaxTube());
            lenCalIn.setToleranceZone(_ordEntity.getToleranceZone());
            // lenCalIn.setPassMame(_ordEntity.getPassMame());
            // lenCalIn.setDiameterMandrel(_ordEntity.getDiameterMandrel());
            lenCalIn.setPlineCode(_ordEntity.getPlineCode());
            lenCalIn.setOrderUnit(_ordEntity.getOrderUnit());
            lenCalIn.setWeighType(_ordEntity.getWeighType());
            lenCalIn.setCutMax(_ordEntity.getCutMax());
            lenCalIn.setEndlenSpecstd(_ordEntity.getEndlenSpecstd());
            // lenCalIn.setAvgLenMin(_ordEntity.getAvgLenMin());
            // 粗算
            LenCalculateOutObject outParams1 = CoreLenCalculate.comput(
                    lenCalIn, false);
            if (!outParams1.getisOutput()) {
                ordCal.setErrCode(-1);
                ordCal.setErrMessage(ordCal.getErrMessage() + "\r\n"
                        + outParams1.getReason());
                return ordCal;
            }
            double lenSingerBiLl = 0;
            if (flag) {// 下发时才取孔型芯棒
                //&& !_ordEntity.getPlineCode().trim().equals("C072")
                // 如果不是外购管，则计算投料管坯
                if (!_ordEntity.getPlineCode().trim().equals("C065")

                        && !_ordEntity.getPlineCode().trim().equals("C066")) {
                    PreparedStatement ps1 = null;
                    // 查询孔型
                    sql = CoreXmlSqlParsersFactory
                            .getSql("CorePlnProcessOrd.queryPlnPassCode");
                    ps = conn.prepareStatement(sql);
                    /*
                     * ps.setObject(1, outParams1.getAimoutdiameter());
                     * ps.setObject(2, outParams1.getAimwallthick());
                     */
                    ps.setObject(1, _ordEntity.getDiameter());
                    ps.setObject(2, _ordEntity.getWallthick());
                    ps.setObject(3, _ordEntity.getPlineCode());
                    ps.setObject(4, _ordEntity.getDimeterGp());
                    rs = ps.executeQuery();
                    if (rs.next()) {
                        if (rs.getString("PASS_CODE") != null
                                && rs.getString("PASS_NAME") != null) {
                            lenCalIn.setPassCode(rs.getString("PASS_CODE"));
                            lenCalIn.setPassMame(rs.getString("PASS_NAME"));

                            // 验证是否存在孔型计划
                            String sqlJudgePassCode = CoreXmlSqlParsersFactory
                                    .getSql("CorePlnProcessOrd.queryJudgePassCode");
                            ps1 = conn.prepareStatement(sqlJudgePassCode);
                            ps1.setObject(1, _ordEntity.getPlineCode());
                            ps1.setObject(2, rs.getString("PASS_CODE"));
                            ps1.setObject(3, _ordEntity.getOrdLnDlyPk());
                            ps1.setObject(4, _ordEntity.getPlnDivideId());
                            ResultSet rstSet = ps1.executeQuery();
                            if (rstSet.next()) {

                            }
                            else {
                                ordCal.setErrCode(-1);
                                ordCal.setErrMessage("该产线【"
                                        + _ordEntity.getPlineName()
                                        + "】在该排产月份【"
                                        + _ordEntity.getRollMonth()
                                        + "】下无对应的孔型【"
                                        + rs.getString("PASS_NAME") + "】计划！");
                                return ordCal;
                            }
                            rstSet.close();
                            ps1.close();
                        }
                        else {
                            ordCal.setErrCode(-1);
                            ordCal.setErrMessage("孔型不能为空，找不到对应孔型！");
                            return ordCal;
                        }
                    }
                    else {
                        ordCal.setErrCode(-1);
                        ordCal.setErrMessage("找不到对应孔型,产线为:"
                                + _ordEntity.getPlineName() + ",轧管名义外径:"
                                + _ordEntity.getDiameter() + ",壁厚:"
                                + _ordEntity.getWallthick() + ",管坯规格为:"
                                + _ordEntity.getDimeterGp() + "！");
                        return ordCal;
                    }
                    rs.close();
                    ps.close();

                    // 查询芯棒适用规格
                    sql = CoreXmlSqlParsersFactory
                            .getSql("CorePlnProcessOrd.queryPlnMandrelIdSpec");
                    if (_ordEntity.getPlineCode().equals("C010")) {//168
                        sql += " ORDER BY T.DIAMETER_MANDREL DESC";
                    }
                    else {
                        sql += " ORDER BY T.DIAMETER_MANDREL ASC";
                    }
                    ps = conn.prepareStatement(sql);
                    ps.setObject(1, _ordEntity.getPlineCode());
                    ps.setObject(2, lenCalIn.getPassCode());
                    ps.setObject(3, outParams1.getAimoutdiameter());
                    ps.setObject(4, outParams1.getAimwallthick());
                    rs = ps.executeQuery();
                    if (rs.next()) {
                        lenCalIn.setDiameterMandrel(String.valueOf(rs
                                .getString("DIAMETER_MANDREL")));
                        lenSingerBiLl = rs.getDouble("LEN_SINGER_BILL");
                        // 验证是否存在芯棒直径
                        // String sqlJudgePassCode = CoreXmlSqlParsersFactory
                        // .getSql("CorePlnProcessOrd.queryPlnMandrelId");
                        // ps1 = conn.prepareStatement(sqlJudgePassCode);
                        // ps1.setObject(1, rs.getString("DIAMETER_MANDREL"));
                        // ResultSet rstSet = ps1.executeQuery();
                        // if (rstSet.next()) {
                        //
                        // }
                        // else {
                        // ordCal.setErrCode(-1);
                        // ordCal.setErrMessage(ordCal.getErrMessage()+" 无对应的芯棒直径！");
                        // return ordCal;
                        //
                        // }
                        // rstSet.close();
                        // ps1.close();
                    }
                    // else {
                    // ordCal.setErrCode(-1);
                    // ordCal.setErrMessage(ordCal.getErrMessage()+" 找不到产线为："
                    // + _ordEntity.getPlineName() + ",孔型为："
                    // + _ordEntity.getPassMame() + ",外径："
                    // + outParams1.getAimoutdiameter() + ",壁厚："
                    // + outParams1.getAimwallthick() + "的对应芯棒适用规格！");
                    // return ordCal;
                    // }
                    rs.close();
                    ps.close();
                }
            }
            double floorBilletLen = 0;
            // 芯棒单倍坯最长与第一次算的单倍坯长比较
            if (Double.parseDouble(outParams1.getBillet()) < lenSingerBiLl
                    || lenSingerBiLl == 0) {
                floorBilletLen = 10 * Math.floor((Double.parseDouble(outParams1
                        .getBillet())) / 10);
            }
            else {
                floorBilletLen = 10 * Math.floor((lenSingerBiLl) / 10);
            }
            // 圆整最佳单倍坯长并代入重算
            // floorBilletLen = 10 * Math.floor((Double.parseDouble(outParams1
            // .getBillet())) / 10);
            lenCalIn.setBilletmax(floorBilletLen);
            if (floorBilletLen >_ordEntity.getLengthMaxRing()) {
                ordCal.setErrCode(-1);
                ordCal.setErrMessage("单倍坯长圆整后必须小于等于环形炉最长，分切数："
                        + outParams1.getCutnum()
                        + ",目标长度："
                        + new BigDecimal(outParams1.getAimlength()).setScale(3,
                                RoundingMode.HALF_UP).doubleValue()
                        + ",轧制长："
                        + new BigDecimal(outParams1.getLengthZz()).setScale(3,
                                RoundingMode.HALF_UP).doubleValue() + "单倍坯长："
                        + floorBilletLen + "mm,环形炉最长："
                        + _ordEntity.getLengthMaxRing() + "mm！");
                return ordCal;
            }

            lenCalIn.setCutnum(Integer.parseInt(outParams1.getCutnum()));
            lenCalIn
                    .setAimlength(Double.parseDouble(outParams1.getAimlength()));
            lenCalOut = CoreLenRecalCulation.recaComput(lenCalIn, flag);
            if (!lenCalOut.getisOutput()) {
                ordCal.setErrCode(-1);
                ordCal.setErrMessage(ordCal.getErrMessage() + "\r\n"
                        + lenCalOut.getReason());
                return ordCal;
            }

            int demandNum = 0;
            dimete = Double.parseDouble(lenCalOut.getBestDiame());
            weightMi = 7.8 * pi / 4 * dimete * dimete / 1000 / 1000;
            lenGp = floorBilletLen / 1000;
            cutNum = Integer.parseInt(lenCalOut.getCutnum());

            invenNum = (int) Math.ceil((float) (_ordEntity.getPlanNum())
                    / cutNum);
            // 需求支= (轧管排产吨+轧管加投吨）/（轧管管单重*（轧制长度-管余长-切头尾）)
            demandNum = (int) Math
                    .ceil((_ordEntity.getPlanWeight() + _ordEntity
                            .getAddWeight())
                            / (lenCalOut.getMiGtWt() * (Double
                                    .parseDouble(lenCalOut.getLengthZz())
                                    - lenCalOut.getTubeYuLong() - _ordEntity
                                    .getCutHeadEnd() / 1000)));

            invenWt = invenNum * lenGp * weightMi;
            aimWallthick = Double.parseDouble(lenCalOut.getAimwallthick());
            // addWeight = _ordEntity.getAddNum() * lenGp * weightMi;

            // 需求吨
            double demandWt = demandNum
                    * Double.parseDouble(lenCalOut.getBilletWeight());

            int demandNumMin = (int) Math
                    .ceil((_ordEntity.getWeigthSMin() + _ordEntity
                            .getAddWeight())
                            / (lenCalOut.getMiGtWt() * (Double
                                    .parseDouble(lenCalOut.getLengthZz())
                                    - lenCalOut.getTubeYuLong() - _ordEntity
                                    .getCutHeadEnd() / 1000)));
            // 需求吨MIN
            double demandWtMin = demandNumMin
                    * Double.parseDouble(lenCalOut.getBilletWeight());
            ordCal.setAimWallthick(aimWallthick);
            ordCal.setAimoutdiameter(lenCalOut.getAimoutdiameter());
            ordCal.setLenZz(Double.parseDouble(lenCalOut.getLengthZz()));
            ordCal.setAimZgLen(Double.parseDouble(lenCalOut.getAimlength()));
            ordCal.setInvenNum(invenNum);
            ordCal.setInvenWt(invenWt);
            ordCal.setCutNum(Integer.parseInt(lenCalOut.getCutnum()));
            ordCal.setLenGp(lenGp);
            ordCal.setWeightGpOne(weightMi * lenGp);
            ordCal.setWeightMi(weightMi);
            // ordCal.setAddWtIn(String.valueOf(addWeight));
            // ordCal.setAddNumIn(String.valueOf(_ordEntity.getAddNum()));
            ordCal.setPassCode(lenCalIn.getPassCode());
            ordCal.setPassMame(lenCalIn.getPassMame());
            ordCal.setDiameterMandrel(lenCalIn.getDiameterMandrel());
            ordCal.setVerify1(lenCalOut.getVerify1());
            ordCal.setVerify2(lenCalOut.getVerify2());
            ordCal.setVerify3(lenCalOut.getVerify3());
            ordCal.setGpreqNum(demandNum);
            ordCal.setGpreqWeight(new BigDecimal(demandWt).setScale(3,
                    RoundingMode.HALF_UP).doubleValue());
            ordCal.setGpreqWeightMin(new BigDecimal(demandWtMin).setScale(3,
                    RoundingMode.HALF_UP).doubleValue());
        }
        catch (Exception ex) {
            ordCal.setErrCode(-1);
            ordCal.setErrMessage(ex.getMessage());
        }
        return ordCal;
    }

    /**
     * 确认信息是否异常
     * @param _ordEntity
     * @return
     */
    private static boolean confirmInf(InZgOrdCalEntity _ordEntity) {
        if (_ordEntity == null) {
            errMessage = "";
            return false;
        }
        if (_ordEntity.getPlanNum() <= 0) {
            errMessage = "计划支数必须大于零。";
            return false;
        }
        if (_ordEntity.getDiameter() <= 0) {
            errMessage = "轧管工序，轧管规格外径必须大于零！";
            return false;
        }
        if (_ordEntity.getWallthick() <= 0) {
            errMessage = "轧管工序，轧管规格壁厚必须大于零！";
            return false;
        }
        if (_ordEntity.getDiameter() < _ordEntity.getWallthick()) {
            errMessage = "轧管规格外径不能小于壁厚！";
            return false;
        }
        if (_ordEntity.getDiame() == null || _ordEntity.getDiame().size() == 0) {
            errMessage = "轧管工序，坯料断面规格未知！";
            return false;
        }
        else {
            for (int i = 0; i < _ordEntity.getDiame().size(); i++) {
                if (_ordEntity.getDiame().get(i) <= 0) {
                    errMessage = "轧管工序，坯料断面必须大于零！";
                    return false;
                }
            }
        }
        if (_ordEntity.getCutHeadEnd() < 0) {
            errMessage = "轧管工序，切头尾不能为负数！";
            return false;
        }
        if (_ordEntity.getLengthMaxRing() <= 0) {
            errMessage = "轧管工序，坯料最长长度必须大于零！";
            return false;
        }
        if (_ordEntity.getLengthColdbed() <= 0) {
            errMessage = "轧管工序，产线冷床长度必须大于零！";
            return false;
        }
        if (_ordEntity.getSigllen() < 0) {
            errMessage = "单倍尺长不能为负数！";
            return false;
        }
        if (_ordEntity.getBurning() < 0 || _ordEntity.getBurning() > 100) {
            errMessage = "烧损率有误！";
            return false;
        }
        if (_ordEntity.getShortest() < 0) {
            errMessage = "短尺最短不能为负数！";
            return false;
        }
        return true;
    }
}