package com.artfess.cqxy.processManagermant.manager.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.artfess.base.context.BaseContext;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.BeanUtils;
import com.artfess.cqxy.processManagermant.dao.ProgressManageDefiniteDao;
import com.artfess.cqxy.processManagermant.manager.ProgressManageDefiniteManager;
import com.artfess.cqxy.processManagermant.manager.ProgressManageManager;
import com.artfess.cqxy.processManagermant.model.ProgressManage;
import com.artfess.cqxy.processManagermant.model.ProgressManageDefinite;
import com.artfess.cqxy.projectManagement.enums.ProjectStatusEnum;
import com.artfess.cqxy.search.enums.FunctionEnum;
import com.artfess.cqxy.search.manager.GlobalRetrievalManager;
import com.artfess.cqxy.search.model.GlobalRetrieval;
import com.artfess.cqxy.universal.manager.AccessoryManager;
import com.artfess.cqxy.universal.model.Accessory;
import com.artfess.cqxy.utils.BizUtils;
import com.artfess.poi.util.ExcelUtil;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.artfess.sysConfig.persistence.param.DictModel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 过程管理 - 进度管理 - 本次拨款明细(BizProgressManageDefinite)表服务实现类
 *
 * @author 黎沐华
 * @since 2022-03-04 16:49:48
 */
@Service
public class ProgressManageDefiniteManagerImpl extends BaseManagerImpl<ProgressManageDefiniteDao, ProgressManageDefinite> implements ProgressManageDefiniteManager {

    @Autowired
    private AccessoryManager accessoryManager;

    @Autowired
    private ProgressManageManager pmm;

    @Autowired
    private SysDictionaryManager sdm;

    @Autowired
    private BaseContext baseContext;

    @Autowired
    private GlobalRetrievalManager grm;


    @Override
    public boolean saveOrUpdate(ProgressManageDefinite entity) {
        boolean save = StringUtils.isEmpty(entity.getId());
        boolean savedMain = super.saveOrUpdate(entity);
        // 处理父表中的拨付总额, 返回项目ID以供后续使用
        String projectId = handleAmountTotal(entity);
        // 处理附件信息
        List<Accessory> flag = entity.getAccessoryInfo();//处理空指针
        List<Accessory> accessoryList = null == flag ? new ArrayList<>() : flag;
        for (Accessory ele : accessoryList) {
            ele.setSourceId(entity.getId());
            ele.setProjectId(projectId);
            ele.setDirectory(ProjectStatusEnum.eleven.getCode());
            ele.setGroup("ProgressManageDefinite");
            ele.setNode(ProjectStatusEnum.eleven.getCode());
            ele.setCreateBy(baseContext.getCurrentUserId());
            ele.setCreateName(baseContext.getCurrentUserName());
            ele.setCreateTime(LocalDateTime.now());
        }
        // 先清空该ID下的所有附件信息再添加
        accessoryManager.removeBySourceId(entity.getId());
        // 如果没有附件则返回true，不进入添加
        boolean saveAcc = accessoryList.size() == 0 || accessoryManager.saveAccess(accessoryList);
        // 同步到检索表
        GlobalRetrieval globalRetrieval= grm.getByBizId(entity.getId());
        handleRetrieval(save || BeanUtils.isEmpty(globalRetrieval) ?new GlobalRetrieval():globalRetrieval,entity);

        return savedMain && saveAcc;
    }

    private void handleRetrieval(GlobalRetrieval globalRetrieval, ProgressManageDefinite entity){
        globalRetrieval.setArchivesType(1);
        globalRetrieval.setBizDataId(entity.getId());
        globalRetrieval.setProjectId("");
        globalRetrieval.setFunctionCode(FunctionEnum.twentyOne.getCode());
        globalRetrieval.setFunctionName(FunctionEnum.twentyOne.getName());
        globalRetrieval.setBizTableName(FunctionEnum.twentyOne.getTableName());
        globalRetrieval.setDetailsRoteUrl(FunctionEnum.twentyOne.getTableRoteUrl());
        globalRetrieval.setTableRoteUrl(FunctionEnum.twentyOne.getTableRoteUrl());
        globalRetrieval.setTableApiUrl(FunctionEnum.twentyOne.getTableApiUrl());
        globalRetrieval.setDetailsApiUrl(FunctionEnum.twentyOne.getDetailsApiUrl());
        globalRetrieval.setFunctionPath(FunctionEnum.twentyOne.getFunctionPath());
        globalRetrieval.setSearchTitle(entity.getPayeeNum()+"_"+entity.getRemarks()+"_"+entity.getPayeeUnit()+"_"+entity.getBankOfDeposit());
        grm.saveOrUpdate(globalRetrieval);
    }

    @Override
    public boolean deleteByIds(List<String> ids) {
        // 同步删除检索表中的信息
        for(String ele:ids){
            grm.remove(1,ele);
        }
        return removeByIds(ids);
    }

    @Override
    public ProgressManageDefinite getById(String id) {
        ProgressManageDefinite result = baseMapper.getById(id);
        result.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(id));
        return result;
    }

    @Override
    public PageList<ProgressManageDefinite> queryAllByPage(QueryFilter<ProgressManageDefinite> queryFilter) {
        BizUtils.handleFilter(queryFilter, "bpmd", false);
        IPage<ProgressManageDefinite> result =
                baseMapper.queryAllByPage(
                        convert2IPage(queryFilter.getPageBean()),
                        convert2Wrapper(queryFilter, currentModelClass()));
        // 附件信息处理
        List<ProgressManageDefinite> records = result.getRecords();
        for (ProgressManageDefinite ele : records) {
            ele.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(ele.getId()));
        }

        return new PageList<>(result);
    }

    @Override
    public void importExcelData(MultipartFile file, String progressManageId) {
        Assert.notNull(progressManageId, "进度管理ID不能为空");
        List<DictModel> purposeType = sdm.queryDictListItemsByCode("jdgl-bkmx-zflx");

        List<ProgressManageDefinite> data = readExcelData(file);
        for (ProgressManageDefinite ele : data) {
            ele.setProgressManageId(progressManageId);

            baseMapper.insert(ele);
            handleAmountTotal(ele);
            // 同步到检索表
            handleRetrieval(new GlobalRetrieval(),ele);
        }
    }

    @Override
    public List<ProgressManageDefinite> readExcelData(MultipartFile file) {
        try(InputStream inputStream = file.getInputStream();) {
            List<ProgressManageDefinite> data = ExcelImportUtil.importExcel(inputStream,ProgressManageDefinite.class,new ImportParams());
        } catch (Exception e) {
            e.printStackTrace();
        }

        List<ProgressManageDefinite> result = new ArrayList<>();
        try {
            //1、获取文件输入流
            InputStream inputStream = file.getInputStream();
            //2、获取Excel工作簿对象
            Workbook workbook = WorkbookFactory.create(inputStream);
            //3、得到Excel工作表对象
            Sheet sheetAt = workbook.getSheetAt(0);
            //4、循环读取表格数据
            for (Row row : sheetAt) {
                //首行（表头）不读取
                if (row.getRowNum() == 0) {
                    continue;
                }
                //读取当前行中单元格数据并赋值到对象，索引从0开始
                ProgressManageDefinite data = new ProgressManageDefinite();
                //处理单元格数据可能为空 getCell将会抛出空指针的问题
//                data.setPurpose(BizUtils.getDicCodeByValue_Int(purposeType,null == row.getCell(0) ? row.createCell(0).getStringCellValue() : row.getCell(0).getStringCellValue()));
                data.setPayeeUnit(null == row.getCell(1) ? row.createCell(1).getStringCellValue() : row.getCell(1).getStringCellValue());
                data.setBankOfDeposit(null == row.getCell(2) ? row.createCell(2).getStringCellValue() : row.getCell(2).getStringCellValue());
                data.setPayeeNum(null == row.getCell(3) ? row.createCell(3).getStringCellValue() : row.getCell(3).getStringCellValue());
                data.setPayeeAmount(BigDecimal.valueOf(null == row.getCell(4) ? row.createCell(4).getNumericCellValue() : row.getCell(4).getNumericCellValue()));
                data.setRemarks(null == row.getCell(8) ? row.createCell(8).getStringCellValue() : row.getCell(8).getStringCellValue());
                result.add(data);
            }
            //5、关闭流
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public void exportDataToExcel(QueryFilter<ProgressManageDefinite> queryFilter, HttpServletResponse response) throws IOException {
        // 获取字典
        List<DictModel> purposeType = sdm.queryDictListItemsByCode("jdgl-bkmx-zflx");

        String fileName = "过程管理-进度管理-本次拨款明细-导出结果";

        // 获取数据
        BizUtils.handleFilter(queryFilter, "bpmd", false);
        List<ProgressManageDefinite> data = baseMapper.queryAllByPage(
                        convert2IPage(new PageBean(0, -1, false)),
                        convert2Wrapper(queryFilter, currentModelClass())).
                getRecords();

        if(null==data||data.size()==0){
            throw new RuntimeException("没有要导出的的数据！");
        }

        // 翻译字典
        for(ProgressManageDefinite ele : data){
            ele.setPurpose(BizUtils.getDicValueByCode(purposeType, ele.getPurpose()));
        }

        // EasyPoi 导出参数、样式、表格格式设置
        ExportParams exportParams = BizUtils.getExportParams(fileName);
        fileName += ".xlsx";

        // 导出下载excel文件
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ProgressManageDefinite.class, data);
        ExcelUtil.downloadExcel(workbook, fileName, response);
    }

    // 处理父表中的拨付总额
    private String handleAmountTotal(ProgressManageDefinite entity) {
        ProgressManage progressManage = pmm.getOne(new QueryWrapper<ProgressManage>().eq("ID_", entity.getProgressManageId()).eq("IS_DELE_", "0"));
        List<ProgressManageDefinite> definites = baseMapper.selectList(new QueryWrapper<ProgressManageDefinite>().eq("PROGRESS_MANAGE_ID_", entity.getProgressManageId()).eq("IS_DELE_", "0"));
        BigDecimal payeeAmountTotal = new BigDecimal("0");
        for (ProgressManageDefinite ele : definites) {
            payeeAmountTotal.add(ele.getPayeeAmount());
        }
        progressManage.setPayeeAmountTotal(payeeAmountTotal);
        progressManage.setAmountTotalWords(BizUtils.changeMoney(payeeAmountTotal.doubleValue()));
        pmm.saveOrUpdate(progressManage);
        return progressManage.getProjectId();
    }
}

