package com.yunyan.business.document.y23.budget;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.yunyan.business.document.EasyExcelFinalListener;
import com.yunyan.business.document.utils.ReadExcelUtil;
import com.yunyan.business.document.y23.budget.pojo.budgetY23.*;
import com.yunyan.common.exception.ServiceException;
import com.yunyan.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * 决算表的读取
 */
@Slf4j
public class ReadBudT5T8ExcelY23Utils {

    /**
     * 读取 决算excel的数据
     * @return
     */

    public static BudgetDataVo getSheetInfos(MultipartFile file, String fileName) throws IOException {
        return getSheetInfos(file, fileName, null);
    }

    /**
     * 读取 excel数据
     * 只需传一种方式， 当传文件时，直接读取文件
     * @param file 文件实体
     * @param fileName 文件路径名
     * @return
     * @throws IOException
     */
    public static BudgetDataVo getSheetInfos(MultipartFile file, String fileName, Integer lastYearFlag) throws IOException {
        // step1. 读取excel内容
        EasyExcelFinalListener easyExcelFinalListener = new EasyExcelFinalListener();
        ExcelReaderBuilder read = new ExcelReaderBuilder();
        //        ExcelReaderBuilder read = EasyExcelFactory.read(file.getInputStream(), easyExcelListener);
        if(null != file) {
            read = EasyExcelFactory.read(file.getInputStream(), easyExcelFinalListener).registerConverter(new CellStringNumberConverter());
        } else if(StringUtils.isNotBlank(fileName)) {
            read = EasyExcelFactory.read(fileName, easyExcelFinalListener).registerConverter(new CellStringNumberConverter());
        } else {
            throw new ServiceException("文件读取异常");
        }

        ExcelReader excelReader = read.build();
        // step2. 获取各个sheet页信息
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
        // step3. 获取各个Shhet页表格内容存于map
        Map<Integer, List<LinkedHashMap<Integer, String>>> sheetInfos = new HashMap<>(sheets.size());
        for (ReadSheet sheet : sheets) {
            Integer sheetNo = sheet.getSheetNo();
            String sheetName =  sheet.getSheetName();
            excelReader.read(sheet);
            if(null != lastYearFlag && lastYearFlag == 1 ) {
                if(sheetNo.equals(0) || sheetNo.equals(10)) {
                    sheetInfos.put(sheetNo, easyExcelFinalListener.getListMap());
                }
            } else {
                sheetInfos.put(sheetNo, easyExcelFinalListener.getListMap());
            }

        }

        BudgetDataVo vo = new BudgetDataVo();

        ReadBudT5T8ExcelY23Utils readFinalExcelY22Utils = new ReadBudT5T8ExcelY23Utils();
        readFinalExcelY22Utils.saveExcelInfo(sheetInfos, vo);

//        log.debug("sheetInfo [{}]", sheetInfos);
        return vo;
    }

    /**
     * 读取 excel数据
     * 只需传一种方式， 当传文件时，直接读取文件
     * @param file 文件实体
     * @param fileName 文件路径名
     * @param sheetNo2 读取的第几个sheet, 默认0
     * @param type 类型: 5-预算表5, 8-预算表8
     * @return
     * @throws IOException
     */
    public static BudgetDataVo getSheetT5OrT8Infos(MultipartFile file, String fileName, Integer sheetNo2, Integer type) throws IOException {
        // step1. 读取excel内容
        EasyExcelFinalListener easyExcelFinalListener = new EasyExcelFinalListener();
        ExcelReaderBuilder read = new ExcelReaderBuilder();
        if(null != file) {
            read = EasyExcelFactory.read(file.getInputStream(), easyExcelFinalListener).registerConverter(new CellStringNumberConverter());
        } else if(StringUtils.isNotBlank(fileName)) {
            read = EasyExcelFactory.read(fileName, easyExcelFinalListener).registerConverter(new CellStringNumberConverter());
        } else {
            throw new ServiceException("文件读取异常");
        }

        ExcelReader excelReader = read.build();
        // step2. 获取各个sheet页信息
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
        // step3. 获取各个Shhet页表格内容存于map
        Map<Integer, List<LinkedHashMap<Integer, String>>> sheetInfos = new HashMap<>(sheets.size());
        for (ReadSheet sheet : sheets) {
            Integer sheetNo = sheet.getSheetNo();
            String sheetName =  sheet.getSheetName();
            excelReader.read(sheet);
            sheetInfos.put(sheetNo, easyExcelFinalListener.getListMap());
        }

        BudgetDataVo vo = new BudgetDataVo();

        ReadBudT5T8ExcelY23Utils readBudT5T8ExcelY23Utils = new ReadBudT5T8ExcelY23Utils();
        if(5 == type) {
            List<LinkedHashMap<Integer, String>> maps = sheetInfos.get(sheetNo2);
            readBudT5T8ExcelY23Utils.setT5Report(maps, vo);
        } else if(8 == type) {
            List<LinkedHashMap<Integer, String>> maps = sheetInfos.get(sheetNo2);
            readBudT5T8ExcelY23Utils.setT8Report(maps, vo);
        } else {
            return null;
        }

        return vo;
    }

    /**
     * 需来回切换 序号,  读取各个sheet表格的数据
     * @param sheetInfos
     */
    public void saveExcelInfo(Map<Integer, List<LinkedHashMap<Integer, String>>> sheetInfos, BudgetDataVo vo) {
        for (Integer sheetNo : sheetInfos.keySet()) {
            List<LinkedHashMap<Integer, String>> maps = sheetInfos.get(sheetNo);
            // 不同sheet页数据处理方式不同
            switch (sheetNo) {
                case 4:
                    //表5 一般公共预算支出情况表
                    setT5Report(maps, vo);
                    break;
                case 7:
                    //表8 政府性基金预算支出情况表
                    setT8Report(maps, vo);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 读取  (表5)
     * @param maps
     * @param vo
     */
    private void setT5Report(List<LinkedHashMap<Integer, String>> maps, BudgetDataVo vo ) {

        BudgetP3p5Vo p2p5Vo = new BudgetP3p5Vo();
        if(Objects.isNull(vo.getExplainVo())) {
            vo.setExplainVo(new BudgetExplainP3Vo());
        }
        vo.getExplainVo().setP3p5Vo(p2p5Vo);

        //所属单位 list
        List<BudgetP3p5SubDeptVo> subDeptList = new ArrayList<>();
        p2p5Vo.setSubDeptList(subDeptList);
        //子级单位
        BudgetP3p5SubDeptVo subDeptVo = new BudgetP3p5SubDeptVo();

        //主管部门的查询 标记
        boolean deptFlag = false;

        //子级单位的 查询 标记
        boolean deptSubFlag = false;
        //** 的标记
        boolean starFlag = false;


        for (LinkedHashMap<Integer, String> map : maps) {

            //科目编码1
            String f0aCode1 =  map.getOrDefault(0, "");
            //科目编码2
            String f1bCode2 =  map.getOrDefault(1, "");
            //科目编码3
            String f2cCode3 =  map.getOrDefault(2, "");
            //单位编码
            String f3dDeptCode =  map.getOrDefault(3, "").replace(".0", "");
            //单位名称(功能分类科目名称)
            String f4eItemName =  map.getOrDefault(4, "");

            //2023年的预算表 没有合计行
            if(starFlag && !deptSubFlag && StringUtils.isNotBlank(f3dDeptCode) && StringUtils.isNotBlank(f4eItemName)) {
                deptSubFlag = true;
                starFlag = false;
            }

            if(deptSubFlag && StringUtils.isNotBlank(f1bCode2) && StringUtils.isNotBlank(f3dDeptCode) && StringUtils.isNotBlank(f4eItemName) ) {
                //子级单位的结束
                deptSubFlag = false;
            }

            if(deptSubFlag) {
                //子级单位的读取
                //合计
                String total = ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 5, "0");

                //查询 子级单位的
                if(StringUtils.isNotBlank(f3dDeptCode) && StringUtils.isNotBlank(f4eItemName) ) {
                    //先存上次的子级单位
                    /*if(null != subDeptVo) {
                        subDeptList.add(subDeptVo);
                    }*/

                    //新记录
                    subDeptVo = new BudgetP3p5SubDeptVo();
                    subDeptVo.setDeptName(f4eItemName);
                    subDeptVo.setDeptCode(f3dDeptCode);
                    subDeptVo.setTotal(total);
                    subDeptVo.setList(new ArrayList<>());
                    //存子级单位
                    subDeptList.add(subDeptVo);
                }

                if(StringUtils.isNotBlank(f1bCode2) && StringUtils.isBlank(f3dDeptCode) && null != subDeptVo ) {
                    //子级单位的科目项
                    BudgetP3p5SubDeptItemVo subDeptItemVo = new BudgetP3p5SubDeptItemVo();
                    //有时格式错误会出现 小数点(第一列 都是 数值转文本,  3个编码的单位后加的 是 单文本, 引起错误) subDeptItemVo.setCode(f0a + f1b + f2c);
                    subDeptItemVo.setCode( f0aCode1.replace(".0", "") + f1bCode2.replace(".0", "") + f2cCode3.replace(".0", ""));
                    subDeptItemVo.setName(f4eItemName);
                    subDeptItemVo.setTotal(total);
                    subDeptVo.getList().add(subDeptItemVo);

                    //todo map 中记录 再相加
                }
            }


            /*if(deptFlag) {
                // 废弃, 读取 主管部门的, 不这样读取
                //合计 基本 项目 的总计
                String total = ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 5, "0");
                String base = ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 6, "0");
                String project = ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 9, "0");

                p2p5Vo.setDeptName(f4e);
                p2p5Vo.setDeptCode(f3d);
                p2p5Vo.setTotal(total);
                p2p5Vo.setBase(base);
                p2p5Vo.setProject(project);

                //查询 子级单位
                deptFlag = false;
                deptSubFlag = true;
            }*/

            if(starFlag && !deptSubFlag && map.containsValue("合计") && map.getOrDefault(4, "").equals("合计")) {
                deptSubFlag = true;
                starFlag = false;
            }

            //** 的标记
            if(map.containsValue("**") && map.getOrDefault(4, "").equals("**") && map.getOrDefault(3, "").equals("**") && map.getOrDefault(5, "").replace(".0", "").equals("1")) {
                starFlag = true;
            }

        }


        log.debug("结束");

    }

    /**
     * 读取 表8
     * @param maps
     * @param vo
     */
    private void setT8Report(List<LinkedHashMap<Integer, String>> maps, BudgetDataVo vo ) {

        if(Objects.isNull(vo.getExplainVo())) {
            vo.setExplainVo(new BudgetExplainP3Vo());
        }

        BudgetP3p8Vo tvo = new BudgetP3p8Vo();
        List<BudgetP3p8ItemVo> tvoList = new ArrayList<>();
        //tvo.setList(tvoList);

        // 是否读取项目的List
        boolean isListFlag = false;
        //标题行
        boolean isListHeadFlag = false;

        //p8部分 所属单位 list
        List<BudgetP3p8DeptVo> deptList = new ArrayList<>();
        tvo.setDeptList(deptList);

        //子级单位
        BudgetP3p8DeptVo subDeptVo = new BudgetP3p8DeptVo();

        //子级单位的 查询 标记
        boolean deptSubFlag = false;

        //** 的标记
        boolean starFlag = false;


        for (LinkedHashMap<Integer, String> map : maps) {
            //科目编码1
            String f0a =  map.getOrDefault(0, "");
            //科目编码2
            String f1b =  map.getOrDefault(1, "");
            //科目编码3
            String f2c =  map.getOrDefault(2, "");
            //单位编码
            String f3d =  map.getOrDefault(3, "");
            //单位名称(功能分类科目名称)
            String f4e =  map.getOrDefault(4, "");

            //2023年的预算表 没有合计行
            /*if(starFlag && !isListFlag && StringUtils.isNotBlank(f3d) && StringUtils.isNotBlank(f4e)) {
                isListFlag = true;
                starFlag = false;
            }
*/
            if(isListFlag && StringUtils.isNotBlank(f1b) && StringUtils.isNotBlank(f3d) && StringUtils.isNotBlank(f4e) ) {
                //子级单位的结束
                isListFlag = false;
                break;
            }

            if(isListFlag) {
                //子级单位的读取
                //合计
                String total = ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 5, "0");

                //查询 子级单位的
                if(StringUtils.isNotBlank(f3d) && StringUtils.isNotBlank(f4e) ) {
                    //先存上次的子级单位
                    /*if(null != subDeptVo) {
                        subDeptList.add(subDeptVo);
                    }*/

                    //新记录
                    subDeptVo = new BudgetP3p8DeptVo();
                    subDeptVo.setDeptName(f4e);
                    subDeptVo.setDeptCode(f3d);
                    subDeptVo.setTotal(total);
                    subDeptVo.setList(new ArrayList<>());
                    //存子级单位
                    deptList.add(subDeptVo);
                }

                if(StringUtils.isNotBlank(f1b) && StringUtils.isBlank(f3d) && null != subDeptVo ) {
                    //子级单位的科目项
                    BudgetP3p8DeptItemVo subDeptItemVo = new BudgetP3p8DeptItemVo();
                    subDeptItemVo.setCode(f0a + f1b + f2c);
                    subDeptItemVo.setName(f4e);
                    subDeptItemVo.setTotal(total);
                    subDeptVo.getList().add(subDeptItemVo);

                    //todo map 中记录 再相加
                }
            }



            if(isListFlag) {
                /*BudgetP2p8ItemVo itemVo = new BudgetP2p8ItemVo();
                itemVo.setCode(String.format("%s%s%s", map.getOrDefault(0, ""), map.getOrDefault(1, ""), map.getOrDefault(2, "")));
                itemVo.setDeptCode(map.getOrDefault(3, ""));
                itemVo.setTotal(ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 5, "0"));
                itemVo.setBase(ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 6, "0"));
                itemVo.setProject(ReadExcelUtil.getMapNumFormatInThousandsYuan(map, 7, "0"));
                tvoList.add(itemVo);*/
                //continue;
            }

            //标题行
            //if( isListHeadFlag && map.containsValue("**") && map.containsKey(0) &&  "**".equals(map.get(0)) ) {
            /*if( isListHeadFlag  ) {
                isListFlag = true;
                isListHeadFlag = false;
            }*/

            //合计行
            if(!isListFlag && map.containsValue("合计") && map.containsKey(4) &&  "合计".equals(map.getOrDefault(4, "")) ) {
                isListHeadFlag = false;
                isListFlag = true;
            }

            //** 的标记
            /*if(map.containsValue("**") && map.getOrDefault(4, "").equals("**") && map.getOrDefault(3, "").equals("**") && map.getOrDefault(5, "").equals("1")) {
                starFlag = true;
            }*/

        }

        vo.getExplainVo().setP3p8Vo(tvo);

    }

}
