package weaver.interfaces.htsc.payment;

import com.alibaba.fastjson.JSON;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetDataSource;
import weaver.conn.RecordSetTrans;
import weaver.interfaces.htsc.GlobatTools.JAVATools;
import weaver.interfaces.htsc.payment.domain.BudgetDetail;
import weaver.interfaces.schedule.BaseCronJob;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class LeaderViewJob extends BaseCronJob {

    Log log = LogFactory.getLog(LeaderViewJob.class);

    @Override
    public void execute() {
        List<BudgetDetail> allBudgetDetail = this.getAllBudgetDetail();
        log.info("allBudgetDetail" + JSON.toJSONString(allBudgetDetail));
        List<Map<String, Object>> leaderViewList = this.calBudgetDetailList(allBudgetDetail);
        log.info("leaderViewList" + JSON.toJSONString(leaderViewList));
        this.doDelete();
        this.doSave(leaderViewList);
    }
//////////////////////////////////////////////////////////////////////////////////////////////////////


    private void doDelete(){
        String strSql = " delete from UF_LEADERVIEW t ";
        RecordSet re = new RecordSet();
        re.execute(strSql);
    }

    private void doSave(List<Map<String, Object>> budgetDeptList){
        if(CollectionUtils.isEmpty(budgetDeptList)){
            return;
        }
        List<String> keyList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        Map<String, Object> objectMap = budgetDeptList.get(0);
        for(Map.Entry<String, Object> entry : objectMap.entrySet()){
            keyList.add(entry.getKey());
            valueList.add("?");
        }

        String keyStr = StringUtils.join(keyList, ",");
        String valueStr = StringUtils.join(valueList, ",");
//        List<List> values = budgetDeptList.stream().map(t -> (List<Object>)new ArrayList(t.values())).collect(Collectors.toList());
        List<List<Object>> values = new ArrayList<>();
        for(Map<String, Object> budgetDept : budgetDeptList){
//            int count = 0;
            List<Object> valueEle = new ArrayList<>();
            for(String key : keyList){
                valueEle.add(budgetDept.get(key));
            }
            values.add(valueEle);
        }
        String sql = " insert into uf_leaderView ( " + keyStr + " ) values ( " + valueStr + " )";
        JAVATools.writelog("insert sql : " + sql);
        JAVATools.writelog("insert values : " + JSON.toJSONString(values));
        try {
            RecordSetTrans rs = new RecordSetTrans();
            rs.executeBatchSql(sql, values);
            rs.setAutoCommit(false);
            rs.commit();
        }catch (Exception e){
            JAVATools.writelog("batch insert error: " + e);
        }
    }


/////////////////////////////////////////////////////////////////////////////////////////////////////
    //计算leaderViewList
    private List<Map<String, Object>> calBudgetDetailList(List<BudgetDetail> budgetDetails ){
        List<Map<String, Object>> leaderViewList = new ArrayList<>();
        Map<String, String> allBudget = JAVATools.getAllBudget();
        Map<String, Map<String, Object>> allDepartment = this.getAllDepartment();
        for (BudgetDetail detail : budgetDetails){
            Map<String, Object> leaverViewMap = this.calBudgetDetail(detail, allDepartment, allBudget);//二级科目
            if(!leaverViewMap.isEmpty()) {
                leaderViewList.add(leaverViewMap);
            }
        }
        //获取一级的执行情况
        Map<String, List<BudgetDetail>> level1DetailList = budgetDetails.stream().collect(Collectors.groupingBy(t -> t.getDeptCode()));
        for(Map.Entry<String, List<BudgetDetail>> entry : level1DetailList.entrySet()){
            String deptCode = entry.getKey();
            Map<String, List<BudgetDetail>> specialDeptLevel1Detail = entry.getValue().stream().collect(Collectors.groupingBy(t -> t.getLevel1Code()));
            List<Map<String, Object>> level1Value = this.getLevel1Value(specialDeptLevel1Detail, allDepartment, allBudget, deptCode);
            if(CollectionUtils.isNotEmpty(level1Value)) {
                leaderViewList.addAll(level1Value);
            }
        }

        return leaderViewList;
    }

    private List<Map<String, Object>> getLevel1Value(Map<String, List<BudgetDetail>> budgetDetailMap, Map<String, Map<String, Object>> deptMap, Map<String, String> budgetMap, String deptCode){
        List<Map<String, Object>> leaderViewList = new ArrayList<>();
        for(Map.Entry<String, List<BudgetDetail>> entry: budgetDetailMap.entrySet()){
            String level1Code = entry.getKey();
            if(!deptMap.containsKey(deptCode) || !budgetMap.containsKey(level1Code)){
                continue;
            }
            String level1Name = budgetMap.get(level1Code);
            String yskmbmlj = level1Code;
            String yskmmclj = level1Name;
            List<BudgetDetail> detailList = entry.getValue();
            BigDecimal YSS = detailList.stream().map(t -> new BigDecimal(Float.toString(t.getTotalValue()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal LJYZS = detailList.stream().map(t -> new BigDecimal(Float.toString(t.getPreUsedValue()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal LJZXS = detailList.stream().map(t -> new BigDecimal(Float.toString(t.getUsedValue()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal percent = YSS.equals(BigDecimal.ZERO) ? BigDecimal.ZERO: (LJYZS.add(LJZXS)).divide(YSS,4).multiply(BigDecimal.valueOf(100));
            String percentStr = percent.toString() +"%";
            String bmid = deptMap.get(deptCode).get("id").toString();
            String bmmc = deptMap.get(deptCode).get("departmentname").toString();
            Map<String, Object> leaderView = this.toLeaderView(level1Code, level1Name, yskmbmlj, yskmmclj, LJYZS, LJZXS, YSS, percentStr, bmid, bmmc, deptCode);
            leaderViewList.add(leaderView);
        }
        return leaderViewList;
    }

    //计算leaderView
    private Map<String, Object> calBudgetDetail(BudgetDetail budgetDetail, Map<String, Map<String, Object>> deptMap, Map<String, String> budgetMap){

        String yskmbm = budgetDetail.getLevel2Code();
        String bmbm = budgetDetail.getDeptCode();
        if(!budgetMap.containsKey(yskmbm) || !deptMap.containsKey(bmbm)){
            return new HashMap<>();
        }
        String yskmmc = budgetMap.get(yskmbm);
        String sjkmbm = budgetDetail.getLevel1Code();
        String sjkmmc = budgetMap.get(sjkmbm);
        String topkmbm = budgetDetail.getLevelTopCode();
        String topkmmc = budgetMap.get(topkmbm);
        String yskmbmlj = sjkmbm + "-" + yskmbm;
        String yskmmclj = sjkmmc + "-" + yskmmc;
        BigDecimal YSS = new BigDecimal(Float.toString(budgetDetail.getTotalValue()));
        BigDecimal LJYZS = new BigDecimal(Float.toString(budgetDetail.getPreUsedValue()));
        BigDecimal LJZXS = new BigDecimal(Float.toString(budgetDetail.getUsedValue()));
        BigDecimal percent = YSS.equals(BigDecimal.ZERO) ? BigDecimal.ZERO : (LJYZS.add(LJZXS)).divide(YSS,4).multiply(BigDecimal.valueOf(100));
        String percentStr = percent.toString() +"%";

        String bmid = deptMap.get(bmbm).get("id").toString();
        String bmmc = deptMap.get(bmbm).get("departmentname").toString();
        return this.toLeaderView(yskmbm, yskmmc, yskmbmlj, yskmmclj, LJYZS, LJZXS, YSS, percentStr, bmid, bmmc, bmbm);
    }

    private Map<String, Object> toLeaderView(String yskmbm, String yskmmc, String yskmbmlj, String yskmmclj, BigDecimal LJYZS, BigDecimal LJZXS, BigDecimal YSS, String percentStr, String bmid, String bmmc, String bmbm){
        Map<String, Object> leaverView = new HashMap<>();
        leaverView.put("yskmbm", yskmbm);
        leaverView.put("yskmmc", yskmmc);
        leaverView.put("yskmbmlj", yskmbmlj);
        leaverView.put("yskmmclj", yskmmclj);
        leaverView.put("ljyzs", LJYZS.toString());
        leaverView.put("ljzxs", LJZXS.toString());
        leaverView.put("yss", YSS.toString());
        leaverView.put("ljyybfb", percentStr);
        leaverView.put("bmid", bmid);
        leaverView.put("bmmc", bmmc);
        leaverView.put("bmbm", bmbm);
        return leaverView;
    }
/////////////////////////////////////////////////////////////////////////////
    //获取所有部门信息
    private Map<String, Map<String, Object>> getAllDepartment(){
        Map<String, Map<String, Object>> deptMapList = new HashMap<>();
        String sqlDept = " select distinct t.id,t.departmentname, t.departmentcode from hrmdepartment t";
        RecordSet recordSet = new RecordSet();
        try {
            recordSet.execute(sqlDept);
            while (recordSet.next()){
                Map<String, Object> deptMap = new HashMap<>();
                deptMap.put("id", recordSet.getString("id"));
                deptMap.put("departmentname", recordSet.getString("departmentname"));
                deptMap.put("departmentcode", recordSet.getString("departmentcode"));
                deptMapList.put(recordSet.getString("departmentcode"), deptMap);
            }
        }catch (Exception e){
            log.error("LeaderViewJob getAllDepartment error:", e);
            throw new RuntimeException("LeaderViewJob getAllDepartment error:");
        }
        return deptMapList;
    }




/////////////////////////////////////////////////////////////////
    //获取所有预算执行情况
    private List<BudgetDetail> getAllBudgetDetail(){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        String thisYear = dateFormat.format(new Date());
        String sql401 = "select distinct a.tbdata_ysdata as totalValue, a.tbdata_zxdata as usedValue, a.tbdata_zydata as preUsedValue, b.tbyszz_zzbh as deptcode,d.level2itemnumber ,d.level1itemnumber,d.topitemnumber\n" +
                "from tbdata_b401 a, tbyszz b, tbjcsj_fyxm c, mapingtable2kingdee d\n" +
                "where a.tbdata_dx01 = b.tbyszz_zznm\n" +
                "and a.tbdata_ysdata >0\n" +
                "and a.tbdata_dx04 = c.tbjcsj_sjnm\n" +
                "and c.tbjcsj_sjbh = d.inslevel2itemnumber\n" +
                "and a.tbdata_dx03='" + thisYear +"00101'";
        String sql301 = "select distinct  a.tbdata_ysdata as totalValue, a.tbdata_zxdata as usedValue, a.tbdata_zydata as preUsedValue, b.tbyszz_zzbh as deptcode, d.level2itemnumber,d.level1itemnumber,d.topitemnumber\n" +
                "from tbdata_a301 a, tbyszz b, ysysxm c, mapingtable2kingdee d\n" +
                "where a.tbdata_dx01 = b.tbyszz_zznm\n" +
                "and a.tbdata_ysdata > 0\n" +
                "and a.tbdata_dx02 = c.ysysxm_xmuid\n" +
                "and c.ysysxm_xmbh = d.inslevel2itemnumber\n" +
                "and a.tbdata_dx03 ='" + thisYear +"00101'";

        RecordSetDataSource rsd = new RecordSetDataSource("BudgetRecords");
        log.info("401 input" + sql401 + thisYear);
        List<BudgetDetail> budget401Detail = this.getBudgetDetail(sql401, rsd);
        log.info("301 input" + sql301 + thisYear);
        List<BudgetDetail> budget301Detail = this.getBudgetDetail(sql301, rsd);
        budget401Detail.addAll(budget301Detail);
        log.info("budget401Detail" + JSON.toJSONString(budget401Detail));
        return budget401Detail;
    }

    //获取预算明细
    private List<BudgetDetail> getBudgetDetail(String sql, RecordSetDataSource rsd){
        List<BudgetDetail> detailMapList = new ArrayList<>();
        try {
            rsd.execute(sql);
            while (rsd.next()){
                float totalValue = rsd.getFloat("totalValue");
                float usedValue = rsd.getFloat("usedValue");
                float preUsedValue = rsd.getFloat("preUsedValue");
                String deptCode = rsd.getString("deptcode");
                String level2itemnumber = rsd.getString("level2itemnumber");
                String level1itemnumber = rsd.getString("level1itemnumber");
                String topitemnumber = rsd.getString("topitemnumber");
                log.info("totalValue " + totalValue + " usedValue : " + usedValue + " preUsed :" + preUsedValue);
                BudgetDetail budgetDetail =  new BudgetDetail(totalValue, preUsedValue, usedValue, deptCode, level2itemnumber, level1itemnumber, topitemnumber);
                detailMapList.add(budgetDetail);
            }
        }catch (Exception e){
            log.error("LeaderViewJob getBudgetDetail error :" , e);
        }
        log.info("detailMapList " + JSON.toJSONString(detailMapList));
        return detailMapList;
    }

}
