package com.brilliance.isc.common.cbsmod;

import com.brilliance.isc.bo.*;
import com.brilliance.isc.common.counter.service.CounterService;
import com.brilliance.isc.common.exception.CommonServiceException;
import com.brilliance.isc.common.util.SettleExceptionUtils;
import com.brilliance.isc.common.util.Utils;
import com.brilliance.isc.mda.dao.*;
import com.brilliance.mda.runtime.mda.util.Dates;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
public class CbsRange {
    @Autowired
    private CbbMapper cbbMapper;

    @Autowired
    private XrtMapper xrtMapper;

    @Autowired
    private ZmqxrtMapper zmqxrtMapper;

    @Autowired
    private IrsMapper irsMapper;

    @Autowired
    private FecMapper fecMapper;

    @Autowired
    private CounterService counterService;

    public void sdbRngReadDefault(Fec fec, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String feeinr = fec.getFeeinr();
        String feepri = fec.getFeepri();
        String sql = "";
        sql += " WHERE FEEINR = '" + feeinr + "'";
        sql += " AND FEEPRI = '" + feepri + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Fec> fecList = fecMapper.selectFecByConditionSql(sql);
        if (fecList != null && fecList.size() > 0) {
            BeanUtils.copyProperties(fecList.get(0), fec); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Fec(), fec); //做清空处理
        }
    }

    public void sdbRngRead(Fec fec, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String objTyp = fec.getObjtyp();
        String objInr = fec.getObjinr();
        String feeinr = fec.getFeeinr();
        String feepri = fec.getFeepri();
        String sql = "";
        sql += " WHERE FEEINR = '" + feeinr + "'";
        sql += " AND FEEPRI = '" + feepri + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Fec> fecList = fecMapper.selectFecByConditionSql(sql);
        if (fecList != null && fecList.size() > 0) {
            BeanUtils.copyProperties(fecList.get(0), fec); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Fec(), fec); //做清空处理
        }
    }

    public void sdbRngRead(Irs irs, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String objTyp = irs.getObjtyp();
        String objInr = irs.getObjinr();
        String cur = irs.getCur();
        String sql = "";
        sql += " WHERE CUR = '" + cur + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Irs> irsList = irsMapper.selectIrsByConditionSql(sql);
        if (irsList != null && irsList.size() > 0) {
            BeanUtils.copyProperties(irsList.get(0), irs); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Irs(), irs); //做清空处理
        }

    }

    public void sdbRngRead(Cbb cbb, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String cbc = cbb.getCbc();
        String extid = cbb.getExtid();
        String objTyp = cbb.getObjtyp();
        String objInr = cbb.getObjinr();
        String sql = "";
        sql += " WHERE CBC = '" + cbc + "'";
        sql += " AND EXTID = '" + extid + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Cbb> cbbList = cbbMapper.getCbbByContiditionSql(sql);
        if (cbbList != null && cbbList.size() > 0) {
            BeanUtils.copyProperties(cbbList.get(0), cbb); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Cbb(), cbb); //做清空处理
        }
    }

    public void sdbRngRead(Xrt xrt, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String cur = xrt.getCur();
        String sql = "";
        sql += " WHERE CUR = '" + cur + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Xrt> xrtList = xrtMapper.getXrtByConditionSql(sql);
        if (xrtList != null && xrtList.size() > 0) {
            BeanUtils.copyProperties(xrtList.get(0), xrt); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Xrt(), xrt); //做清空处理
        }
    }
    public void sdbRngRead(Zmqxrt xrt, Date dat) {
        if (dat == null) {
            throw new CommonServiceException("RNGMOD.SdbRngRead: No PerDat specified in Call.");
        }
        String cur = xrt.getCur();
        String sql = "";
        sql += " WHERE CUR = '" + cur + "'";
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(dat) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(dat) + " ";
        List<Zmqxrt> zmqxrtList = zmqxrtMapper.getZmqxrtByConditionSql(sql);
        if (zmqxrtList != null && zmqxrtList.size() > 0) {
            BeanUtils.copyProperties(zmqxrtList.get(0), xrt); //需要深拷贝，不然调用得到的对象指向的还是原来的地址
        }else{
            BeanUtils.copyProperties(new Zmqxrt(), xrt); //做清空处理
        }
    }

    public void sdbRngInsert(Cbb cbb) {
        String cbc = cbb.getCbc();
        String extid = cbb.getExtid();
        String objTyp = cbb.getObjtyp();
        String objInr = cbb.getObjinr();
        String sql = "";
        sql += " WHERE CBC = '" + cbc + "'";
        sql += " AND EXTID = '" + extid + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        Date beginDate = cbb.getBegdat();
        Date endDate = cbb.getEnddat();
        if (beginDate == null) {
            SettleExceptionUtils.sysDump("No BEGDAT specified on SdbRngInsert");
        } else if (Dates.diff(beginDate, Utils.getMinDate())<0) {
            SettleExceptionUtils.sysDump("Invalid BEGDAT specified on SdbRngInsert. BEGDAT before 1.1.1900 is not supported.");
        }
        Date maxDate = Utils.getMaxDate();
        if (endDate == null || Dates.diff(endDate, maxDate) > 0) {
            endDate = maxDate;
        }
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(beginDate) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(beginDate) + " ";
        Cbb lastCbb = getCbbByContiditionSql(sql);
        if (lastCbb != null) {
            Date endDate2 = lastCbb.getEnddat();
            lastCbb.setEnddat(beginDate);
            cbbMapper.updateByPrimaryKey(lastCbb);
            if (Dates.diff(endDate2, endDate) > 0) {
                Cbb newCbb = new Cbb();
                BeanUtils.copyProperties(cbb, newCbb);
                newCbb.setBegdat(endDate);
                newCbb.setEnddat(endDate2);
                newCbb.setInr(counterService.dbCounterFormat("CBB"));
                cbbMapper.insert(newCbb);
            }
        }
        List<Cbb> cbbList = sdbRngSelectAfterDate(cbb, beginDate);
        Cbb nextCbb = null;
        if (cbbList != null && cbbList.size() > 0) {
            nextCbb = cbbList.get(0);
        }
        if (nextCbb != null && Dates.diff(nextCbb.getBegdat(), endDate) < 0) {
            endDate = nextCbb.getBegdat();
        }
        cbb.setEnddat(endDate);
        cbb.setInr(counterService.dbCounterFormat("CBB"));
        cbbMapper.insert(cbb);
    }

    public void sdbRngInsert(Fec fec) {
        String objTyp = fec.getObjtyp();
        String objInr = fec.getObjinr();
        String feeinr = fec.getFeeinr();
        String feepri = fec.getFeepri();
        String sql = "";
        sql += " WHERE FEEINR = '" + feeinr + "'";
        sql += " AND FEEPRI = '" + feepri + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        Date beginDate = fec.getBegdat();
        Date endDate = fec.getEnddat();
        if (beginDate == null) {
            SettleExceptionUtils.sysDump("No BEGDAT specified on SdbRngInsert");
        } else if (Dates.diff(beginDate, Utils.getMinDate())<0) {
            SettleExceptionUtils.sysDump("Invalid BEGDAT specified on SdbRngInsert. BEGDAT before 1.1.1900 is not supported.");
        }
        Date maxDate = Utils.getMaxDate();
        if (endDate == null || Dates.diff(endDate, maxDate) > 0) {
            endDate = maxDate;
        }
        sql += " AND date_format(BEGDAT, '%y%m%d') <= " + Utils.dbSqlDate(beginDate) + " AND date_format(ENDDAT, '%y%m%d') > " + Utils.dbSqlDate(beginDate) + " ";
        Fec lastFec = getFecByContiditionSql(sql);
        if (lastFec != null) {
            Date endDate2 = lastFec.getEnddat();
            lastFec.setEnddat(beginDate);
            fecMapper.updateByPrimaryKey(lastFec);
            if (Dates.diff(endDate2, endDate) > 0) {
                Fec newFec = new Fec();
                BeanUtils.copyProperties(fec, newFec);
                newFec.setBegdat(endDate);
                newFec.setEnddat(endDate2);
                newFec.setInr(counterService.dbCounterFormat("FEC"));
                fecMapper.insert(newFec);
            }
        }
        List<Fec> fecList = sdbRngSelectAfterDate(fec, beginDate);
        Fec nextFec = null;
        if (fecList != null && fecList.size() > 0) {
            nextFec = fecList.get(0);
        }
        if (nextFec != null && Dates.diff(nextFec.getBegdat(), endDate) < 0) {
            endDate = nextFec.getBegdat();
        }
        fec.setEnddat(endDate);
        fec.setInr(counterService.dbCounterFormat("FEC"));
        fecMapper.insert(fec);
    }

    public void sdbRngDelete(Fec fec){
        fec = fecMapper.selectByPrimaryKey(fec);
        String objTyp = fec.getObjtyp();
        String objInr = fec.getObjinr();
        String feeinr = fec.getFeeinr();
        String feepri = fec.getFeepri();
        Date beginDate = fec.getBegdat();
        Date endDate = fec.getEnddat();
        String inr = fec.getInr();
        //删掉当前fec记录
        fecMapper.deleteByPrimaryKey(fec);
        if (beginDate != null) {
            //更新上一笔fec数据的enddate
            String sql = "";
            sql += " WHERE FEEINR = '" + feeinr + "'";
            sql += " AND FEEPRI = '" + feepri + "'";
            sql += " AND OBJTYP = '" + objTyp + "'";
            sql += " AND OBJINR = '" + objInr + "'";
            sql += " AND date_format(ENDDAT, '%y%m%d') = " + Utils.dbSqlDate(beginDate) + "";
            /**
             *   老国结Inr为8位，新国结为16位并填了0，新国结的inr必定小于老国结的inr
             *   但老国结按照逻辑，应该要比新国结小因此加了or
             *   后面的order by 之所以不加length(inr)排序，因为BEGDAT已经做了排序，老国结的数据不会与新国结的在同一天，
             *   且新国结的数据begdat大于老国结的begdat
             */
            sql += " AND (length(INR) = 8 or INR < '" + inr + "') ORDER BY BEGDAT DESC, INR DESC";
            Fec lastFec = getFecByContiditionSql(sql);
            if (lastFec != null) {
                lastFec.setEnddat(endDate);
                fecMapper.updateByPrimaryKey(lastFec);
            }
        }
    }

    public List<Cbb> sdbRngSelectAfterDate(Cbb cbb, Date dat) {
        Date beginDate = cbb.getBegdat();
        String cbc = cbb.getCbc();
        String extid = cbb.getExtid();
        String objTyp = cbb.getObjtyp();
        String objInr = cbb.getObjinr();
        String sql = "";
        sql += " WHERE CBC = '" + cbc + "'";
        sql += " AND EXTID = '" + extid + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        if (beginDate == null) {
            sql += "AND date_format(BEGDAT, '%y%m%d') >= " + Utils.dbSqlDate(Utils.getMinDate());
        } else {
            sql += "AND date_format(BEGDAT, '%y%m%d') > " + Utils.dbSqlDate(beginDate);
        }
        sql += " ORDER BY BEGDAT, INR";
        return cbbMapper.getCbbByContiditionSql(sql);
    }

    public List<Fec> sdbRngSelectAfterDate(Fec fec, Date dat) {
        Date beginDate = fec.getBegdat();
        String objTyp = fec.getObjtyp();
        String objInr = fec.getObjinr();
        String feeinr = fec.getFeeinr();
        String feepri = fec.getFeepri();
        String sql = "";
        sql += " WHERE FEEINR = '" + feeinr + "'";
        sql += " AND FEEPRI = '" + feepri + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        if (beginDate == null) {
            sql += "AND date_format(BEGDAT, '%y%m%d') >= " + Utils.dbSqlDate(Utils.getMinDate());
        } else {
            sql += "AND date_format(BEGDAT, '%y%m%d') > " + Utils.dbSqlDate(beginDate);
        }
        sql += " ORDER BY BEGDAT, INR";
        return fecMapper.selectFecByConditionSql(sql);
    }

    public List<Cbb> sdbRngSelectAfterEntry(Cbb cbb) {
        Date beginDate = cbb.getBegdat();
        String inr = cbb.getInr();
        String cbc = cbb.getCbc();
        String extid = cbb.getExtid();
        String objTyp = cbb.getObjtyp();
        String objInr = cbb.getObjinr();
        String sql = "";
        sql += " WHERE CBC = '" + cbc + "'";
        sql += " AND EXTID = '" + extid + "'";
        sql += " AND OBJTYP = '" + objTyp + "'";
        sql += " AND OBJINR = '" + objInr + "'";
        if(beginDate == null) {
            sql = sql + " AND ((BEGDAT IS NULL";
            sql = sql + " AND INR > '" + inr + "')";
            sql = sql + " OR (BEGDAT IS NOT NULL))";
        } else {
            sql = sql + " AND ((date_format(BEGDAT, '%y%m%d') = " + Utils.dbSqlDate(beginDate);
            sql = sql + " AND INR > '" + inr + "' )";
            sql = sql + " OR (date_format(BEGDAT, '%y%m%d') > " + Utils.dbSqlDate(beginDate) + "))";
        }
        sql += " ORDER BY BEGDAT, INR";
        return cbbMapper.getCbbByContiditionSql(sql);
    }

    public void sdbRngDelete(Cbb cbb){
        //获取到当前cbb所有字段
        cbb = cbbMapper.selectByPrimaryKey(cbb);
        String cbc = cbb.getCbc();
        String extid = cbb.getExtid();
        String objTyp = cbb.getObjtyp();
        String objInr = cbb.getObjinr();
        Date beginDate = cbb.getBegdat();
        Date endDate = cbb.getEnddat();
        String inr = cbb.getInr();
        //删掉当前cbb记录
        cbbMapper.deleteByPrimaryKey(cbb);
        if (beginDate != null) {
            //更新上一笔cbb数据的enddate
            String sql = "";
            sql += " WHERE CBC = '" + cbc + "'";
            sql += " AND EXTID = '" + extid + "'";
            sql += " AND OBJTYP = '" + objTyp + "'";
            sql += " AND OBJINR = '" + objInr + "'";
            sql += " AND date_format(ENDDAT, '%y%m%d') = " + Utils.dbSqlDate(beginDate) + "";
            /**
             *   老国结Inr为8位，新国结为16位并填了0，新国结的inr必定小于老国结的inr
             *   但老国结按照逻辑，应该要比新国结小因此加了or
             *   后面的order by 之所以不加length(inr)排序，因为BEGDAT已经做了排序，老国结的数据不会与新国结的在同一天，
             *   且新国结的数据begdat大于老国结的begdat
             */
            sql += " AND (length(INR) = 8 or INR < '" + inr + "') ORDER BY BEGDAT DESC,  INR DESC";
            Cbb lastCbb = getCbbByContiditionSql(sql);
            if (lastCbb != null) {
                lastCbb.setEnddat(endDate);
                cbbMapper.updateByPrimaryKey(lastCbb);
            }
        }
    }

    public Cbb sdbRngSelectValidInRange(String objTyp, String objInr, String cbcArg, String extId, Date begDat, Date endDat) {
        String otherArgSql = "";
        otherArgSql += " AND CBC = '" + cbcArg + "'";
        otherArgSql += " AND EXTID = '" + extId + "'";
        String sql = Utils.sdbRngSelectValidInRange("CBB", begDat, endDat, objInr, objTyp, otherArgSql);
        return getCbbByContiditionSql(sql);
    }

    public Cbb getCbbByContiditionSql(String conditionSql) {
        List<Cbb> cbbList = cbbMapper.getCbbByContiditionSql(conditionSql);
        if (cbbList != null && cbbList.size() > 0) {
            return cbbList.get(0);
        }
        return null;
    }

    public Fec getFecByContiditionSql(String conditionSql) {
        List<Fec> fecList = fecMapper.selectFecByConditionSql(conditionSql);
        if (fecList != null && fecList.size() > 0) {
            return fecList.get(0);
        }
        return null;
    }
}
