package com.engine.htsc.payment.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.core.impl.Service;
import com.engine.htsc.financialadjustment.excel.ExcelDataListener;
import com.engine.htsc.financialadjustment.util.BizUtil;
import com.engine.htsc.payment.pojo.HTPaymentCostDetail;
import com.engine.htsc.payment.pojo.PayLhExcelData;
import com.engine.htsc.payment.service.PaymentExcelTemplateService;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.general.IOUtils;
import weaver.general.Util;
import weaver.interfaces.htsc.GlobatTools.JAVATools;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PaymentExcelTemplateServiceImpl extends Service implements PaymentExcelTemplateService {
    public static final String COST_DEPT = "费用实际承担部门编号";//标题行
    public static final String BUDGET_ITEM = "预算科目编号";
    public static final String NOTTAX_MONEY = "不含税金额";
    public static final String TAX_RATE = "税率";
    public static final String CURRENCY = "币种";
    public static final String FOREIGN_CURRENCY_MONEY = "外币金额";
    public static final String REASON = "事由";
    public static final String CURRENCY_KIND = "货币类型";
    public static final String TYPE_HTZXYSKM = "HTZXYSKM";//专项预算科目
    public static final String TYPE_HTYBYSKM = "HTYBYSKM";//一般预算科目
    public static final String TYPE_HTZBYSKM = "HTZBYSKM";//资本预算科目
    public static final String TYPE_HTQTYSKM = "HTQTYSKM";//其他预算科目
    public static final String TYPE_HTZJYSKM = "HTZJYSKM";//资金预算科目

    @Override
    public List<HTPaymentCostDetail> getDetailByExcel(Map<String, Object> params) throws Exception {
        JAVATools.SetCmdwritelog("-------总部通用付款Excel解析文件参数:-------" + params.toString());
        int fileId = Util.getIntValue((String) params.get("fileId"));
        InputStream inputStream = ImageFileManager.getInputStreamById(fileId);
        XSSFWorkbook book = new XSSFWorkbook(inputStream);
        List<XSSFRow> rowList = getXSSFRowList(book);
        List<HTPaymentCostDetail> detailList = getDataList(rowList);
        return detailList;
    }

    //只取第一个sheet
    private List<XSSFRow> getXSSFRowList(XSSFWorkbook xssfWorkbook) {
        List<XSSFRow> rowList = new ArrayList<XSSFRow>();
        // 循环工作表Sheet
        XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
        List<XSSFRow> list = getRowObj(sheetAt);
        rowList.addAll(list);
        //只取第一个sheet，后续sheet为标识，不能处理
//        for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
//            XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
//            if (xssfSheet == null) {
//                continue;
//            } else {
//                List<XSSFRow> list = getRowObj(xssfSheet);
//                rowList.addAll(list);
//            }
//        }
        return rowList;
    }

    // 将表变成行对象返回
    private List<XSSFRow> getRowObj(XSSFSheet pageObj) {
        // 循环工作表Sheet
        List<XSSFRow> rowList = new ArrayList<XSSFRow>();
        // 循环行Row
        for (int rowNum = 0; rowNum <= pageObj.getLastRowNum(); rowNum++) {
            XSSFRow xssfRow = pageObj.getRow(rowNum);
            if (xssfRow == null) {
                continue;
            }
            //将不为空的行放入
            rowList.add(xssfRow);
        }
        return rowList;
    }

    private List<HTPaymentCostDetail> getDataList(List<XSSFRow> rowList) throws Exception {
        List<HTPaymentCostDetail> dataList = new ArrayList<HTPaymentCostDetail>();
        List<String> itemNameList = new ArrayList<String>();
        List<String> relationCodeList = new ArrayList<String>();
        List<String> slNameList = new ArrayList<String>();
        List<String> slDisorderList = new ArrayList<String>();
        try {
            String sqlname = "select name from mode_selectitempagedetail where mainid in ( select id from mode_selectitempage t where t.cubeuuid='B89F75E7D6707CCCE05331353DA877B5') order by id";
            RecordSet rs0 = new RecordSet();
            rs0.execute(sqlname);
            while (rs0.next()) {
                itemNameList.add(Util.null2String(rs0.getString("name")));
            }
            String sqlcode = "select hl from uf_bz_hl order by bz";
            RecordSet rs1 = new RecordSet();
            rs1.execute(sqlcode);
            while (rs1.next()) {
                relationCodeList.add(Util.null2String(rs1.getString("hl")));
            }
            String sqlsl = "select name,disorder from mode_selectitempagedetail where mainid in ( select id from mode_selectitempage t where t.cubeuuid='B89FDE40168B7CABE05331353DA8AED1') order by id";
            RecordSet rs2 = new RecordSet();
            rs2.execute(sqlsl);
            while (rs2.next()) {
                if ("0".equals(rs2.getString("name"))) {
                    slNameList.add("0%");
                } else {
                    slNameList.add(Util.null2String(rs2.getString("name")));
                }
                slDisorderList.add(Util.null2String(rs2.getString("disorder")));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, Integer> indexMap = getIndexMap(rowList);
        for (int rowNum = 0; rowNum < rowList.size(); rowNum++) {
            HTPaymentCostDetail detailObj = new HTPaymentCostDetail();
            XSSFRow xssfRow = rowList.get(rowNum);
            if (xssfRow == null) {
                continue;
            }
            for (int cellNum = 0; cellNum <= xssfRow.getLastCellNum(); cellNum++) {
                XSSFCell xssfCell = xssfRow.getCell(cellNum);
                if (xssfCell == null || cellNum == 4 || cellNum == 5 || cellNum == 9) {
                    continue;
                } else {
                    String cellValue = getValue(xssfCell);
//					cellValue=cellValue.replace(" ", "");
                    cellValue = cellValue.replaceAll("\\z\\n\\t\\r", "");
                    if (indexMap.isEmpty()) {
                        throw new Exception("因没找到对应文件解析EXCEL文件失败");
                    } else {
                        Integer titleRow = indexMap.get("titleRow");
                        if (titleRow == null || titleRow < 0) {
                            throw new Exception("因没找到对应的标题所在的行号，解析EXCEL文件失败");
                        } else if (indexMap.get(COST_DEPT) == null || indexMap.get(COST_DEPT) < 0) {
                            throw new Exception("没有填写相应费用实际承担部门编号，解析EXCEL文件失败");
                        } else if (indexMap.get(BUDGET_ITEM) == null || indexMap.get(BUDGET_ITEM) < 0) {
                            throw new Exception("没有填写相应费用预算编号，解析EXCEL文件失败");
                        } else if (indexMap.get(CURRENCY_KIND) == null || indexMap.get(CURRENCY_KIND) < 0) {
                            throw new Exception("没有填写相应货币类型，解析EXCEL文件失败");
                        } else {
                            if (xssfCell.getRowIndex() == titleRow) {
                                break;
                            } else {
                                if (indexMap.get(this.COST_DEPT) == xssfCell.getColumnIndex()) {
                                    String deptid = "";
                                    String departmentname = "";
                                    RecordSet rs = new RecordSet();
                                    String sql = " select id,departmentname from hrmdepartment l where l.departmentcode = '" + cellValue + "'";
                                    rs.execute(sql);
                                    if (rs.next()) {
                                        deptid = Util.null2String(rs.getString("id"));
                                        departmentname = Util.null2String(rs.getString("departmentname"));
                                    }

                                    if (StringUtils.isEmpty( cellValue)) {
                                         break;
                                    }
                                    if (StringUtils.isEmpty( deptid) || "" == deptid) {
                                        throw new Exception( "费用实际承担部门编号错误！请检查EXCEL文件第" + (rowNum + 1) + "行");
                                    }
                                    detailObj.setAssumeDeptCode(deptid);
                                    detailObj.setAssumeDept(departmentname);
                                } else if (indexMap.get(this.BUDGET_ITEM) == xssfCell.getColumnIndex()) {
                                    setBudgetDetail(cellValue, detailObj);
                                } else if (indexMap.get(this.NOTTAX_MONEY) == xssfCell.getColumnIndex()) {
                                    detailObj.setNotaxMoney(StringUtils.isNotEmpty(cellValue) ? cellValue : "0");
                                } else if (indexMap.get(this.TAX_RATE) == xssfCell.getColumnIndex()) {
                                    detailObj.setTaxRate(StringUtils.isNotEmpty(cellValue) ? cellValue : "0");
                                } else if (indexMap.get(this.CURRENCY) == xssfCell.getColumnIndex()) {
                                    detailObj.setMoneyKind(cellValue);
                                    if (itemNameList.contains(cellValue)) {
                                        detailObj.setMoneyKindCode(itemNameList.indexOf(cellValue));
                                    } else {
                                        detailObj.setMoneyKindCode(0);
                                    }
                                } else if (indexMap.get(this.FOREIGN_CURRENCY_MONEY) == xssfCell.getColumnIndex()) {
                                    detailObj.setForeignCurrencyMoney(StringUtils.isNotEmpty(cellValue) ? cellValue : "0");
                                } else if (indexMap.get(this.REASON) == xssfCell.getColumnIndex()) {
                                    detailObj.setReason(cellValue);
                                } else if (indexMap.get(this.CURRENCY_KIND) == xssfCell.getColumnIndex()) {
                                    if (StringUtils.isEmpty(cellValue) || (!"本币".equals(cellValue) && !"外币".equals(cellValue))) {
                                        throw new Exception("第" + (rowNum + 1) + "行,货币类型为空或错误！");
                                    }
                                    detailObj.setCurrencyKind(cellValue);
                                }
                            }
                        }
                    }
                }
            }
            if (StringUtils.isNotEmpty(detailObj.getAssumeDeptCode()) && null != detailObj.getEstimateProjectCode()) {
                if ("外币".equals(detailObj.getCurrencyKind())) {
                    boolean flag = true;
                    if (StringUtils.isEmpty(detailObj.getMoneyKind())) {
                        throw new Exception("第" + (rowNum + 1) + "行,请填写币种！");
                    }
                    for (int i = 0; i < itemNameList.size(); i++) {
                        if (detailObj.getMoneyKind().equals(itemNameList.get(i))) {
                            BigDecimal b1 = new BigDecimal(detailObj.getForeignCurrencyMoney());
                            BigDecimal b2 = new BigDecimal(relationCodeList.get(i));
                            double money = b1.multiply(b2).doubleValue();
                            DecimalFormat df = new DecimalFormat("#.##");
                            df.setRoundingMode(RoundingMode.HALF_UP);
                            detailObj.setMoney(Double.parseDouble(df.format(money)));
                            detailObj.setTaxMoney("0");
                            detailObj.setTaxRate("0");
                            detailObj.setNotaxMoney("0");
                            detailObj.setExchangeRate(relationCodeList.get(i));
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        throw new Exception("第" + (rowNum + 1) + "行,请填写正确的币种！");
                    }
                } else {
                    if (StringUtils.isEmpty(detailObj.getNotaxMoney())) {
                        throw new Exception("第" + (rowNum + 1) + "行,请填写不含税金额！");
                    } else if (StringUtils.isEmpty(detailObj.getTaxRate()) || (!"0".equals(detailObj.getTaxRate()) &&
                            !"3%".equals(detailObj.getTaxRate()) && !"5%".equals(detailObj.getTaxRate()) &&
                            !"6%".equals(detailObj.getTaxRate()) && !"11%".equals(detailObj.getTaxRate()) &&
                            !"13%".equals(detailObj.getTaxRate()) && !"17%".equals(detailObj.getTaxRate()) &&
                            !"16%".equals(detailObj.getTaxRate()) && !"10%".equals(detailObj.getTaxRate()) &&
                            !"0.03".equals(detailObj.getTaxRate()) && !"0.05".equals(detailObj.getTaxRate()) &&
                            !"0.06".equals(detailObj.getTaxRate()) && !"0.11".equals(detailObj.getTaxRate()) &&
                            !"0.13".equals(detailObj.getTaxRate()) && !"0.17".equals(detailObj.getTaxRate()) &&
                            !"0.16".equals(detailObj.getTaxRate()) && !"0.1".equals(detailObj.getTaxRate()))) {
                        throw new Exception("第" + (rowNum + 1) + "行,汇率为空或汇率错误！");
                    }
                    BigDecimal b1 = new BigDecimal(detailObj.getNotaxMoney());
                    BigDecimal b2 = new BigDecimal(detailObj.getTaxRate().replace("%", ""));
                    BigDecimal b3 = new BigDecimal("100");
                    DecimalFormat df = new DecimalFormat("#.##");
                    double taxMoney = 0;
                    if (b2.doubleValue() > 1) {
                        taxMoney = b1.multiply(b2).divide(b3).doubleValue();
                        if (detailObj.getTaxRate().indexOf("%") == -1) {
                            detailObj.setTaxRate(detailObj.getTaxRate() + "%");
                        }
                    } else {
                        taxMoney = b1.multiply(b2).doubleValue();
                        detailObj.setTaxRate(df.format(b3.multiply(b2).doubleValue()) + "%");
                    }
                    df.setRoundingMode(RoundingMode.HALF_UP);
                    detailObj.setTaxMoney(df.format(taxMoney));
                    BigDecimal b4 = new BigDecimal(detailObj.getTaxMoney());
                    detailObj.setMoney(Double.parseDouble(b4.add(b1).toString()));
                    detailObj.setForeignCurrencyMoney("0");
                    detailObj.setTaxRateCode(Integer.parseInt(slDisorderList.get(slNameList.indexOf(detailObj.getTaxRate()))));
                }
                dataList.add(detailObj);
            }
        }
        return dataList;
    }

    private Map<String, Integer> getIndexMap(List<XSSFRow> rowList) {
        Map<String, Integer> indexMap = new HashMap<String, Integer>();
        for (int rowNum = 0; rowNum < rowList.size(); rowNum++) {
            XSSFRow xssfRow = rowList.get(rowNum);
            if (xssfRow == null) {
                continue;
            }
            Boolean blag = true;
            // 循环列Cell 获取字段相对应的列号。
            for (int cellNum = 0; cellNum <= xssfRow.getLastCellNum(); cellNum++) {
                XSSFCell xssfCell = xssfRow.getCell(cellNum);
                if (xssfCell == null || cellNum == 4 || cellNum == 5 || cellNum == 9) {
                    continue;
                } else {
                    if (!"0".equals(getValue(xssfCell))) {
                        String cellValue = getValue(xssfCell);
                        if (cellValue.equals(this.COST_DEPT)) {
                            if (blag) {
                                indexMap.put("titleRow", xssfCell.getRowIndex());
                                blag = false;
                            }
                            indexMap.put(this.COST_DEPT, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.BUDGET_ITEM)) {
                            indexMap.put(this.BUDGET_ITEM, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.NOTTAX_MONEY)) {
                            indexMap.put(this.NOTTAX_MONEY, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.TAX_RATE)) {
                            indexMap.put(this.TAX_RATE, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.CURRENCY)) {
                            indexMap.put(this.CURRENCY, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.FOREIGN_CURRENCY_MONEY)) {
                            indexMap.put(this.FOREIGN_CURRENCY_MONEY, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.REASON)) {
                            indexMap.put(this.REASON, xssfCell.getColumnIndex());
                        } else if (cellValue.equals(this.CURRENCY_KIND)) {
                            indexMap.put(this.CURRENCY_KIND, xssfCell.getColumnIndex());
                        }
                    }
                }
            }
        }
        return indexMap;

    }

    private String getValue(XSSFCell xssfCell) {
        if (xssfCell.getCellType().getCode() == 4) {
            return String.valueOf(xssfCell.getBooleanCellValue());
        } else if (xssfCell.getCellType().getCode() == 0) {
            DecimalFormat df = new DecimalFormat("#.##");
            return df.format(xssfCell.getNumericCellValue());
        } else {
            return String.valueOf(xssfCell.getStringCellValue());
        }
    }

    public void setBudgetDetail(String budgetCode, HTPaymentCostDetail detailObj) {
        Map<String, String> budgetItem = getDataItemByCode(budgetCode, this.TYPE_HTZXYSKM);
        if (null == budgetItem) {
            budgetItem = getDataItemByCode(budgetCode, this.TYPE_HTYBYSKM);
            if (null == budgetItem) {
                budgetItem = getDataItemByCode(budgetCode, this.TYPE_HTZBYSKM);
                if (null == budgetItem) {
                    budgetItem = getDataItemByCode(budgetCode, this.TYPE_HTQTYSKM);
                    if (null == budgetItem) {
                        budgetItem = getDataItemByCode(budgetCode, this.TYPE_HTZJYSKM);
                    }
                }
            }
        }
        detailObj.setIsOutBuadge( budgetItem.get("cyskz"));
        detailObj.setEstimateProject( budgetItem.get("yskmmc"));
        detailObj.setEstimateProjectCode( budgetItem.get("yskmbm"));
    }

    public Map<String, String> getDataItemByCode(String code, String typeCode) {
        Map<String, String> map = new HashMap<>();
        String sqlMaxid = "select id,sjyskm,yskmmc,yskmbm,cyskz from uf_kmpz where YSKMBM = '" + code + "' and typeCode='" + typeCode + "'";
        RecordSet rs = new RecordSet();
        rs.execute(sqlMaxid);
        if (rs.next()) {
            map.put("id", Util.null2String(rs.getString("id")));
            map.put("sjyskm", Util.null2String(rs.getString("sjyskm")));
            map.put("yskmmc", Util.null2String(rs.getString("yskmmc")));
            map.put("yskmbm", Util.null2String(rs.getString("yskmbm")));
            map.put("cyskz", Util.null2String(rs.getString("cyskz")));
        }
        if (null != map && map.size() > 0) {
            return map;
        } else {
            return null;
        }
    }

    @Override
    public JSONArray readByImageId(int imageId,String ngrid) throws Exception {
        List<PayLhExcelData> source = read2List(imageId);
        RecordSet sqlFindCode = new RecordSet();
        //获取拟稿人工号
        String workCode = "";
        String sql = "SELECT WORKCODE FROM HRMRESOURCE h WHERE id = "+ ngrid;
        sqlFindCode.execute(sql);
        if (sqlFindCode.next()){
            workCode = Util.null2String(sqlFindCode.getString("WORKCODE"));
        }
        JAVATools.SetCmdwritelog(String.format("联合通用付款导入Excel获取 image id: %d, and workCode id: %s", imageId,workCode));
        JSONArray jsa = new JSONArray();
        for (PayLhExcelData d : source) {
            JSONObject jso = new JSONObject();
            jso.put("payForDept", BizUtil.getDidByCode(d.getPayForDept()));
            jso.put("estimateProjectCode",BizUtil.getBudgetObj(d.getEstimateProjectCode(),"1") );
            jso.put("notaxMoney", d.getNotaxMoney());
            jso.put("taxMoney", d.getTaxMoney());
            jso.put("allMoney", d.getAllMoney());
            jso.put("projectCode",StringUtils.isNotBlank(d.getProjectCode()) ? BizUtil.getProjectBrowserByCode(workCode, d.getProjectCode()) : "");
            jsa.add(jso);
        }
        JAVATools.SetCmdwritelog(String.format("联合通用付款导入Excel完成 jsa: %s",jsa.toString()));
        return jsa;
    }

    private List<PayLhExcelData> read2List(int imageFileId) throws Exception {
        JAVATools.SetCmdwritelog(String.format("开始读取 imageFileId: %d",imageFileId));
        InputStream fis = ImageFileManager.getInputStreamById(imageFileId);
        JAVATools.SetCmdwritelog(String.format("获得 fis: %s", IOUtils.toString(fis)));
        ExcelDataListener<PayLhExcelData> listener = new ExcelDataListener<>();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        JAVATools.SetCmdwritelog("开始读取第一个");
        EasyExcel.read(ImageFileManager.getInputStreamById(imageFileId), PayLhExcelData.class, listener).sheet().doRead();
        JAVATools.SetCmdwritelog(String.format("读取完成 List: %s",listener.getList().toString()));
        return listener.getList();
    }
}
