package com.jeeplus.modules.sg.financial.erpcredit.util;

import com.alibaba.fastjson.JSON;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.sg.audit.information.entity.Information;
import com.jeeplus.modules.sg.financial.erpcredit.entity.*;
import com.jeeplus.modules.sg.financial.expense.entity.Expense;
import com.jeeplus.modules.sg.financial.settlement.entity.MaintainData;
import com.jeeplus.modules.sg.managementcenter.project.entity.Project;
import net.oschina.j2cache.CacheChannel;
import net.oschina.j2cache.J2Cache;
import net.oschina.j2cache.redis.RedisCacheProvider;
import net.oschina.j2cache.redis.RedisClient;
import net.oschina.j2cache.redis.RedisUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ValidationUtils {

    public static final String JUDGE_KEY_PREFIX = "erpjudge:";//甲供材、费用入账存在性验证不通过，存储key
    public static final String CREDIT_KEY_PREFIX = "erpcredit:";//明细账转化中间数据存储key
    public static final String EXPENSE_KEY_PREFIX = "erpexpense:";//实付大于应付数据对象 存储key
    public static final String ARTIFICIAL_KEY_PREFIX = "erpartificial";//应付金额大于实付金额数据对象 存储key

    //验证概预算信息是否存在
    public static String getDataMainJudge(List<ErpCredit> erpCredits, List<MaintainData> maintainDatas){
        List<ErpJudgeAccount> list = new ArrayList<ErpJudgeAccount>();
        ErpJudgeAccount erpJudgeDataMain = new ErpJudgeAccount();
        boolean flag = true;
        for (ErpCredit erpCredit1:erpCredits){
            flag = true;
            for (MaintainData maintainData:maintainDatas){
                if (erpCredit1.getItemId().equals(maintainData.getProjectId())){
                    flag = false;
                }
            }
            if (flag){
                erpJudgeDataMain = new ErpJudgeAccount();
                erpJudgeDataMain.setItemId(erpCredit1.getItemId());
                erpJudgeDataMain.setItemName(erpCredit1.getItemName());
                erpJudgeDataMain.setFlagItem("无");
                erpJudgeDataMain.setItemSupplierName(erpCredit1.getSupplierName());
                list.add(erpJudgeDataMain);
            }
        }
        if (null!=list && list.size()>0){
            return getJoiningTogether(list);
        }
        return "";
    }

    //验证费用入账是否存在
    public static String getExpenseJudge(List<ErpCredit> erpCredits, List<Expense> expenses){
        List<ErpJudgeAccount> list = new ArrayList<ErpJudgeAccount>();
        ErpJudgeAccount erpExpense = new ErpJudgeAccount();
        boolean flag = true;
        for (ErpCredit erpCredit1:erpCredits){
            flag = true;
            for (Expense expense:expenses){
                if (erpCredit1.getItemId().equals(expense.getProjectId())){
                    flag = false;
                }
            }
            if (flag){
                erpExpense = new ErpJudgeAccount();
                erpExpense.setItemId(erpCredit1.getItemId());
                erpExpense.setItemName(erpCredit1.getItemName());
                erpExpense.setFlagItem("无");
                erpExpense.setItemSupplierName(erpCredit1.getSupplierName());
                list.add(erpExpense);
            }
        }
        if (null!=list && list.size()>0){
            return getJoiningTogether(list);
        }
        return "";
    }
    //验证需求基本信息
    public static String getProjectJudge(List<ErpCredit> erpCredits, List<Project> project1s){
        List<ErpJudgeAccount> list = new ArrayList<ErpJudgeAccount>();
        ErpJudgeAccount erpProject = new ErpJudgeAccount();
        boolean flag = true;
        for (ErpCredit erpCredit1:erpCredits){
            flag = true;
/*            for (Project project1 : project1s){
                if (erpCredit1.getItemId().equals(project1.getProjectNumber())){
                    flag = false;
                }
            }*/
            if (flag){
                erpProject = new ErpJudgeAccount();
                erpProject.setItemId(erpCredit1.getItemId());
                erpProject.setItemName(erpCredit1.getItemName());
                erpProject.setFlagItem("无");
                erpProject.setItemSupplierName(erpCredit1.getSupplierName());
                list.add(erpProject);
            }
        }
        if (null!=list && list.size()>0){
            return getJoiningTogether(list);
        }
        return "";
    }

    //验证是否甲供材存在
    public static String getInformationJudge(List<ErpCredit> erpCredits, List<Information> informationList){
        List<ErpJudgeAccount> list = new ArrayList<ErpJudgeAccount>();
        ErpJudgeAccount erpProject = new ErpJudgeAccount();
        boolean flag = true;
        for (ErpCredit erpCredit1:erpCredits){
            flag = true;
            for (Information information:informationList){
                if (erpCredit1.getItemId().equals(information.getProjectId())){
                    flag = false;
                    break;
                }
            }
            if (flag){
                erpProject = new ErpJudgeAccount();
                erpProject.setItemId(erpCredit1.getItemId());
                erpProject.setItemName(erpCredit1.getItemName());
                erpProject.setFlagItem("无");
                erpProject.setItemSupplierName(erpCredit1.getSupplierName());
                list.add(erpProject);
            }
        }
        if (null!=list && list.size()>0){
            return getJoiningTogether(list);
        }
        return "";
    }
    //验证是否甲供材存在
    public static String getInformationJudge1(List<ErpCredit> erpCredits, List<Information> informationList){
        List<ErpJudgeAccount> list = new ArrayList<ErpJudgeAccount>();
        ErpJudgeAccount erpProject = new ErpJudgeAccount();
        for (ErpCredit erpCredit:erpCredits){
            for (Information information:informationList){
                if (erpCredit.getItemId().equals(information.getProjectId())){
                    erpProject = new ErpJudgeAccount();
                    erpProject.setItemId(erpCredit.getItemId());
                    erpProject.setItemName(erpCredit.getItemName());
                    erpProject.setFlagItem("否");
                    erpProject.setItemSupplierName(erpCredit.getSupplierName());
                    list.add(erpProject);
                    break;
                }
            }
        }
        if (null!=list && list.size()>0){
            return getJoiningTogether(list);
        }
        return "";
    }

    /**
     * 拼接项目验证信息
     * @param erpJudgeAccounts
     * @return
     */
    public static String getJoiningTogether(List<ErpJudgeAccount> erpJudgeAccounts){
        String str = "";
        for (ErpJudgeAccount erpJudgeAccount:erpJudgeAccounts){
            str+=erpJudgeAccount.getItemId()+","+erpJudgeAccount.getItemName()+","+erpJudgeAccount.getFlagItem()+","+erpJudgeAccount.getItemSupplierName()+",";
        }
        str = str.substring(0,str.length()-1);
        return str;
    }

    //若应付金额（不含税价）>实付金额（不含税价）,需要进入人工判断，若人工判断通过，则费用入账核实无问题，若人工判断不通过则费用入账核实存在问题
    public static String getJudgeTwo(List<ErpCredit> listTwo){
        DecimalFormat decimalFormat   = new DecimalFormat("#0.00");
        List<ErpJudgeArtificial> erpJudgeArtificials = new ArrayList<ErpJudgeArtificial>();
        ErpJudgeArtificial erpJudgeArtificial = null;
        String str = "";
        for (ErpCredit erpCredit:listTwo){
            erpJudgeArtificial = new ErpJudgeArtificial();
            erpJudgeArtificial.setItemId(erpCredit.getItemId());
            //施工费
            if (null!=erpCredit.getConstructionStatus()){
               if (erpCredit.getConstructionStatus().equals("2")){
                   str+="施工费应付金额为"+decimalFormat.format(erpCredit.getConstructionFeePayable())+
                           ";实际金额"+decimalFormat.format(erpCredit.getConsTotalFee())+";";
               }
            }
            //设计费
            if (null!=erpCredit.getDesignStatus()){
                if (erpCredit.getDesignStatus().equals("2")){
                    str+="设计费应付金额为"+decimalFormat.format(erpCredit.getDesignFeePayable())+
                            ";实际金额为"+decimalFormat.format(erpCredit.getOtherDesignFee())+";";
                }
            }
            //监理费
            if (null!=erpCredit.getSupervisorStatus()){
               if (erpCredit.getSupervisorStatus().equals("2")){
                   str+="监理费应付金额为"+decimalFormat.format(erpCredit.getSupervisorFeePayable())+
                           ";实际金额为"+decimalFormat.format(erpCredit.getOtherSupervisorFee())+";";
               }
            }
            erpJudgeArtificial.setNotTheSame(str);
            erpJudgeArtificials.add(erpJudgeArtificial);
            str = "";
        }
        String string = "";
        for (ErpJudgeArtificial erpJudgeArtificial1:erpJudgeArtificials){
            string+=erpJudgeArtificial1.getItemId()+","+erpJudgeArtificial1.getNotTheSame()+",";
        }
        if (!"".equals(string)){
            string = string.substring(0,string.length()-1);
            return string;
        }
        return "";
    }


    //若应付金额（不含税价）<实付金额（不含税价）,需要导出差异情况，同时费用入账核实存在问题。
    public static String getJudgeThree(List<ErpCredit> listThree){
        DecimalFormat decimalFormat   = new DecimalFormat("#0.00");
        List<ErpJudgeExport> erpJudgeExports = new ArrayList<ErpJudgeExport>();
        ErpJudgeExport erpJudgeExport = null;
        for (ErpCredit erpCredit:listThree){
            erpJudgeExport = new ErpJudgeExport();
            erpJudgeExport.setItemId(erpCredit.getItemId());
            erpJudgeExport.setItemName(erpCredit.getItemName());
            erpJudgeExport.setConsTotalFee("");
            erpJudgeExport.setConstructionFeePayable("");
            erpJudgeExport.setOtherDesignFee("");
            erpJudgeExport.setDesignFeePayable("");
            erpJudgeExport.setOtherSupervisorFee("");
            erpJudgeExport.setSupervisorFeePayable("");
            //施工费
            if (null!=erpCredit.getConstructionStatus()){
                erpJudgeExport.setConsTotalFee(decimalFormat.format(erpCredit.getConsTotalFee()));
                erpJudgeExport.setConstructionFeePayable(decimalFormat.format(erpCredit.getConstructionFeePayable()));
            }
            //设计费
            if (null!=erpCredit.getDesignStatus()){
               erpJudgeExport.setOtherDesignFee(decimalFormat.format(erpCredit.getOtherDesignFee()));
               erpJudgeExport.setDesignFeePayable(decimalFormat.format(erpCredit.getDesignFeePayable()));
            }
            //监理费
            if (null!=erpCredit.getSupervisorStatus()){
                erpJudgeExport.setOtherSupervisorFee(decimalFormat.format(erpCredit.getOtherSupervisorFee()));
                erpJudgeExport.setSupervisorFeePayable(decimalFormat.format(erpCredit.getSupervisorFeePayable()));
            }
            erpJudgeExports.add(erpJudgeExport);
        }
        String str = "";
        for (ErpJudgeExport erpJudgeExport1:erpJudgeExports){
            str+=erpJudgeExport1.getItemId()+","+erpJudgeExport1.getItemName()+","
                    +erpJudgeExport1.getConstructionFeePayable()+","+erpJudgeExport1.getConsTotalFee()+","
                    +erpJudgeExport1.getDesignFeePayable()+","+erpJudgeExport1.getOtherDesignFee()+","
                    +erpJudgeExport1.getSupervisorFeePayable()+","+erpJudgeExport1.getOtherSupervisorFee()+",";
        }
        str = str.substring(0,str.length()-1);
        return str;
    }

    public static List<ErpJudgeExport> getOverPayExportList(List<ErpCredit> creditList){
        DecimalFormat decimalFormat  = new DecimalFormat("#0.00");
        List<ErpJudgeExport> exportList = new ArrayList<>();
        for(ErpCredit credit:creditList){
            ErpJudgeExport export = new ErpJudgeExport();
            export.setItemId(credit.getItemId());
            export.setItemName(credit.getItemName());
            boolean hasOverPay = false;
            if(CostAccountUnits.OVER_PAY_AMOUNT.equals(credit.getConstructionStatus())){
                hasOverPay = true;
                export.setConsTotalFee(decimalFormat.format(credit.getConsTotalFee()));
                export.setConstructionFeePayable(decimalFormat.format(credit.getConstructionFeePayable()));
            }
            if(CostAccountUnits.OVER_PAY_AMOUNT.equals(credit.getDesignStatus())){
                hasOverPay = true;
                export.setOtherDesignFee(decimalFormat.format(credit.getOtherDesignFee()));
                export.setDesignFeePayable(decimalFormat.format(credit.getDesignFeePayable()));
            }
            if(CostAccountUnits.OVER_PAY_AMOUNT.equals(credit.getSupervisorStatus())){
                hasOverPay = true;
                export.setOtherSupervisorFee(decimalFormat.format(credit.getOtherSupervisorFee()));
                export.setSupervisorFeePayable(decimalFormat.format(credit.getSupervisorFeePayable()));
            }
            if(hasOverPay){
                exportList.add(export);
            }
        }
        return exportList;
    }

    public static List<ErpJudgeArtificial> getPayLessArtificialList(List<ErpCredit> creditList){
        List<ErpJudgeArtificial> artificialList = new ArrayList<ErpJudgeArtificial>();
        String str = "";
        for (ErpCredit erpCredit:creditList){
            StringBuffer buffer = new StringBuffer();
            //施工费
            if(CostAccountUnits.PAY_LESS_AMOUNT.equals(erpCredit.getConstructionStatus())){
                buffer.append("施工费应付金额为");
                buffer.append(erpCredit.getConstructionFeePayable());
                buffer.append(";实际金额");
                buffer.append(erpCredit.getConsTotalFee());
                buffer.append(";");
            }
            //设计费
            if (CostAccountUnits.PAY_LESS_AMOUNT.equals(erpCredit.getDesignStatus())){
                buffer.append("设计费应付金额为");
                buffer.append(erpCredit.getDesignFeePayable());
                buffer.append(";实际金额");
                buffer.append(erpCredit.getOtherDesignFee());
                buffer.append(";");
            }
            //监理费
            if (CostAccountUnits.PAY_LESS_AMOUNT.equals(erpCredit.getSupervisorStatus())){
                buffer.append("监理费应付金额为");
                buffer.append(erpCredit.getSupervisorFeePayable());
                buffer.append(";实际金额");
                buffer.append(erpCredit.getOtherSupervisorFee());
                buffer.append(";");
            }
            String msg = buffer.toString();
            if(StringUtils.isNotBlank(msg)){
                ErpJudgeArtificial artificial = new ErpJudgeArtificial();
                artificial.setItemId(erpCredit.getItemId());
                artificial.setNotTheSame(msg);
                artificialList.add(artificial);
            }
        }
        return artificialList;
    }

    //导出差异
    public static List<ErpJudgeExport> getErpJudgeExport(String string){
        String[] split = string.split(",");
        List<ErpJudgeExport> erpJudgeExports = new ArrayList<ErpJudgeExport>();
        ErpJudgeExport erpJudgeExport = null;
        for (int i = 0; i < split.length; i+=8) {
            erpJudgeExport = new ErpJudgeExport();
            erpJudgeExport.setItemId(split[i]);
            erpJudgeExport.setItemName(split[i+1]);
            erpJudgeExport.setConstructionFeePayable(split[i+2]);
            erpJudgeExport.setConsTotalFee(split[i+3]);
            erpJudgeExport.setDesignFeePayable(split[i+4]);
            erpJudgeExport.setOtherDesignFee(split[i+5]);
            erpJudgeExport.setSupervisorFeePayable(split[i+6]);
            erpJudgeExport.setOtherSupervisorFee(split[i+7]);
            erpJudgeExports.add(erpJudgeExport);
        }
        return erpJudgeExports;
    }
    //所有erp信息
    public static String getAllListErpCredit(List<ErpCredit> erpCredits){
        String string = "";
        for (ErpCredit erpCredit:erpCredits){
            string +=erpCredit.getItemId()+",";
        }
        if (!"".equals(string)){
            string = string.substring(0,string.length()-1);
        }
        return string;
    }

    /**
     * 验证资本成本 返回提示信息
     * 判断方式 项目定义编码 ‘1’开头为资本项目，‘B’开头为成本项目
     * @param credits
     * @return
     */
    public static String verifyCapital(List<ErpCredit> credits){
        if(credits==null||credits.size()==0){
            return "未导入项目明细账！";
        }
        for(ErpCredit credit:credits){
            String itemId = credit.getItemId();
            if(itemId.trim().startsWith("B")){
                return "项目明细账中存在成本项目！";
            }
        }
        return "";
    }

    /**
     * 验证概预算信息 若存在明细账项目无相应概预算信息 返回错误信息 否则返回空字符串
     * @param ids   明细账项目编码
     * @param datas  找到的概预算信息
     * @return
     */
    public static String verifyMaintain(List<String> ids,List<MaintainData> datas){
        if(datas==null||datas.size()==0){
            return "项目明细账中项目都没有概预算信息！";
        }
        List<String> maintainIds = new ArrayList<>();
        for(MaintainData data:datas){
            maintainIds.add(data.getProjectId());
        }
        //标志验证通过
        boolean ok = true;
        StringBuffer buffer = new StringBuffer();
        for(String id:ids){
            if(!maintainIds.contains(id)){
                buffer.append(id);
                buffer.append(";");
                ok = false;
            }
        }
        if(ok){
            return "";
        }else{
            buffer.append(" 等项目不存在概预算信息！");
            return buffer.toString();
        }
    }


    //验证资本和成本
    public static String getTheCostOfCapital(List<ErpCredit> erpCredits,List<Project> project1s){
        String type = "";
        String strFlag1 = "0";
        String strFlag2 = "0";
        /*for (ErpCredit erpCredit:erpCredits){
            for (Project project1 : project1s){
                if (erpCredit.getItemId().equals(project1.getProjectNumber())){
                    if (project1.getType().equals("配网资本")){
                        strFlag1 = "1";
                    }
                    if (project1.getType().equals("配网成本")){
                        strFlag2 = "1";
                    }
                    break;
                }
            }
        }*/
        if (strFlag1.equals("1")&&!strFlag2.equals("1")){
            return "1";//配网资本
        }
        if (strFlag2.equals("1")&&!strFlag1.equals("1")){
            return "0";//配网成本
        }
        return "3";
    }

    /**
     * 获取credits所有id
     * @param erpCredits
     * @return
     */
    public static List<String> getItemIds(List<ErpCredit> erpCredits){
        List<String> ids = new ArrayList<>();
        if(erpCredits!=null&&erpCredits.size()!=0){
            for(ErpCredit credit:erpCredits){
                ids.add(credit.getItemId());
            }
        }
        return ids;
    }

    public static void verifyExpense(List<ErpCredit> creditList, List<Expense> expenseList, Map<String,ErpJudgeAccount> map){
        List<String> ids = new ArrayList<>();
        if(creditList.size()==expenseList.size()){
            return;
        }
        if(expenseList!=null){
            for(Expense expense:expenseList){
                ids.add(expense.getProjectId());
            }
        }
        for(ErpCredit credit:creditList){
            String itemId = credit.getItemId();
            if(!ids.contains(itemId)){
                ErpJudgeAccount judge = map.get(itemId);
                if(judge==null){
                    judge = new ErpJudgeAccount();
                    judge.setItemId(itemId);
                    judge.setItemName(credit.getItemName());
                    judge.setItemSupplierName(credit.getSupplierName());
                    map.put(itemId,judge);
                }
                judge.setExpenseStatus(ErpJudgeAccount.NO_DATA);
            }
        }
    }

    public static void verifyInformation(List<ErpCredit> creditList,List<Information> hasInfoList,
                                         List<Information> notFinishList,Map<String,ErpJudgeAccount> map){
        if(hasInfoList.size()<creditList.size()){
            List<String> ids = new ArrayList<>();
            if(hasInfoList!=null){
                for(Information info:hasInfoList){
                    ids.add(info.getProjectId());
                }
            }
            for(ErpCredit credit:creditList){
                String itemId = credit.getItemId();
                if(!ids.contains(itemId)){
                    ErpJudgeAccount judge = map.get(itemId);
                    if(judge==null){
                        judge = new ErpJudgeAccount();
                        judge.setItemId(itemId);
                        judge.setItemName(credit.getItemName());
                        judge.setItemSupplierName(credit.getSupplierName());
                        map.put(itemId,judge);
                    }
                    judge.setInformationStatus(ErpJudgeAccount.NO_DATA);
                }
            }
        }
        if(notFinishList!=null&&notFinishList.size()>0){
            List<String> ids = new ArrayList<>();
            for(Information info:notFinishList){
                ids.add(info.getProjectId());
            }
            for(ErpCredit credit:creditList){
                String itemId = credit.getItemId();
                if(ids.contains(itemId)){
                    ErpJudgeAccount judge = map.get(itemId);
                    if(judge==null){
                        judge = new ErpJudgeAccount();
                        judge.setItemId(itemId);
                        judge.setItemName(credit.getItemName());
                        judge.setItemSupplierName(credit.getSupplierName());
                        map.put(itemId,judge);
                    }
                    judge.setInformationStatus(ErpJudgeAccount.NOT_FINISHED);
                }
            }
        }
    }


    public static  void storeListToRedis(HttpServletRequest request,List list,String prefix){
        HttpSession session = request.getSession();
        String key = prefix+session.getId();
        CacheChannel channel = J2Cache.getChannel();
        RedisClient client = ((RedisCacheProvider)channel.getL2Provider()).getRedisClient();
        try {
            client.get().setex(key.getBytes(),120, SerializeUtil.serizlize(list));
        } finally {
            client.release();
        }
    }

    public static <T> List<T> getSessionRedisList(HttpServletRequest request,String prefix,Class T){
        List<T> list = null;
        HttpSession session = request.getSession();
        String key = prefix + session.getId();
        CacheChannel channel = J2Cache.getChannel();
        RedisClient client = ((RedisCacheProvider)channel.getL2Provider()).getRedisClient();
        try {
            list  = (List<T>) SerializeUtil.deserialize(client.get().get(key.getBytes()));
        } finally {
            client.release();
        }
        return list;
    }
}
