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

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
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.query.QueryOP;
import com.artfess.base.util.BeanUtils;
import com.artfess.cqxy.projectApproval.dao.DecisionAnnualPlanDao;
import com.artfess.cqxy.projectApproval.manager.DecisionAnnualPlanManager;
import com.artfess.cqxy.projectApproval.model.DecisionAnnualPlan;
import com.artfess.cqxy.projectManagement.enums.ProjectStatusEnum;
import com.artfess.cqxy.projectManagement.manager.ProjectManagementManager;
import com.artfess.cqxy.projectManagement.model.ProjectManagement;
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.statistics.vo.StatisticsVo;
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.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 年度计划表(DecisionAnnualPlan)表服务实现类
 *
 * @author 黎沐华
 * @since 2022-03-31 16:37:18
 */
@Service
public class DecisionAnnualPlanManagerImpl extends BaseManagerImpl<DecisionAnnualPlanDao, DecisionAnnualPlan> implements DecisionAnnualPlanManager {

    @Autowired
    private AccessoryManager accessoryManager;

    @Autowired
    private SysDictionaryManager sdm;

    @Autowired
    ProjectManagementManager pmm;

    @Autowired
    private BaseContext baseContext;

    @Autowired
    private GlobalRetrievalManager grm;

    @Override
    public boolean saveOrUpdate(DecisionAnnualPlan entity) {
        boolean save = StringUtils.isEmpty(entity.getId());
        boolean savedMain = super.saveOrUpdate(entity);
        // 处理附件信息
        List<Accessory> flag = entity.getAccessoryInfo();//处理空指针
        List<Accessory> accessoryList = null == flag ? new ArrayList<>() : flag;
        for (Accessory ele : accessoryList) {
            ele.setSourceId(entity.getId());
            ele.setProjectId(entity.getProjectId());
            ele.setDirectory(ProjectStatusEnum.one.getCode());
//            ele.setGroup("DecisionAnnualPlan");
            Integer year = entity.getYear();
            ele.setGroup("DecisionAnnualPlan"+ year);
            ele.setNode(ProjectStatusEnum.one.getCode());
            ele.setCreateBy(baseContext.getCurrentUserId());
            ele.setCreateName(baseContext.getCurrentUserName());
            ele.setCreateTime(LocalDateTime.now());
        }
        // 先清空该ID下的所有附件信息再添加，否则当修改时删除附件就不知道删掉哪一个了，传已经删除的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, DecisionAnnualPlan entity){
        ProjectManagement projectManagement = pmm.getById(entity.getProjectId());
        globalRetrieval.setProjectId(entity.getProjectId());
        if(null != projectManagement){
            globalRetrieval.setProjectName(projectManagement.getProjectName());
            globalRetrieval.setPersonCharge(projectManagement.getProjectManager());
        }
        globalRetrieval.setArchivesType(1);
        globalRetrieval.setBizDataId(entity.getId());
        globalRetrieval.setFunctionCode(FunctionEnum.two.getCode());
        globalRetrieval.setFunctionName(FunctionEnum.two.getName());
        globalRetrieval.setBizTableName(FunctionEnum.two.getTableName());
        globalRetrieval.setDetailsRoteUrl(FunctionEnum.two.getTableRoteUrl());
        globalRetrieval.setTableRoteUrl(FunctionEnum.two.getTableRoteUrl());
        globalRetrieval.setTableApiUrl(FunctionEnum.two.getTableApiUrl());
        globalRetrieval.setDetailsApiUrl(FunctionEnum.two.getDetailsApiUrl());
        globalRetrieval.setFunctionPath(FunctionEnum.two.getFunctionPath());
        globalRetrieval.setSearchTitle(entity.getResponsibleUnit()+"_"+entity.getConstructionAddress()+"_"+entity.getRemarks());
        grm.saveOrUpdate(globalRetrieval);
    }

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

    @Override
    public DecisionAnnualPlan getById(String id) {
        DecisionAnnualPlan result = baseMapper.getById(id);
        Integer year = result.getYear();
        String group = "DecisionAnnualPlan"+ year;
//        result.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(id));
        result.setAccessoryInfo(accessoryManager.getAccessoryByGroup(group));
        return result;
    }

    @Override
    public PageList<DecisionAnnualPlan> queryAllByPage(QueryFilter<DecisionAnnualPlan> queryFilter) {
//        BizUtils.handleFilter(queryFilter, "bdap", "pm");
        queryFilter.addFilter( "bdap.IS_DELE_", "0", QueryOP.EQUAL);
        IPage<DecisionAnnualPlan> result = baseMapper.queryAllByPage(
                convert2IPage(queryFilter.getPageBean()),
                convert2Wrapper(queryFilter, currentModelClass()));
        // 附件信息处理
        List<DecisionAnnualPlan> records = result.getRecords();
        for (DecisionAnnualPlan ele : records) {
            Integer year = ele.getYear();
            String group = "DecisionAnnualPlan"+ year;
            ele.setAccessoryInfo(accessoryManager.getAccessoryByGroup(group));
//            ele.setAccessoryInfo(accessoryManager.getAccessoryBySourceId(ele.getId()));

        }
        return new PageList<>(result);
    }

    @Override
    public void updateProjectIdByProiectId(String oldProjectIds, String newProjectId) {
        UpdateWrapper<DecisionAnnualPlan> wrapper = new UpdateWrapper<DecisionAnnualPlan>()
                .set(StringUtils.isNotBlank(newProjectId), "PROJECT_ID_", newProjectId)
                .in("PROJECT_ID_", Arrays.asList(oldProjectIds.split(",")));
        this.update(wrapper);
    }

    @Override
    public List<Map<String, String>> queryInvestment(StatisticsVo statisticsVo) {

        return this.baseMapper.queryInvestment(statisticsVo);
    }

    @Override
    public void importExcelData(MultipartFile file, String projectId) {
//        Assert.notNull(projectId, "项目ID不能为空");
        // 获取字典
        List<DictModel> projectType = sdm.queryDictListItemsByCode("xmgl-xmlx");
        List<DictModel> buildType = sdm.queryDictListItemsByCode("ndjh-jslx");
        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开始
                DecisionAnnualPlan data = new DecisionAnnualPlan();
                //处理单元格数据可能为空 getCell将会抛出空指针的问题
                // 计划年份
                // 如果项目名称为空，就不进行导入
                if(null == row.getCell(1) || StringUtils.isBlank(BizUtils.getCellValue(row.getCell(1)))){
                    continue;
                }
                data.setYear(null == row.getCell(0) ? LocalDate.now().getYear() : Integer.valueOf(BizUtils.getCellValue(row.getCell(0))));
                // 项目名称
                data.setProjectName(null == row.getCell(1) ? "" : BizUtils.getCellValue(row.getCell(1)));
                // 建设类型
                data.setProjectType(null == row.getCell(2)? "" : (BizUtils.getDicCodeByValue_String(buildType,  BizUtils.getCellValue(row.getCell(2)))));
                //项目类型
                data.setProjectCode(null == row.getCell(3)? null : (BizUtils.getDicCodeByValue_Int(projectType, BizUtils.getCellValue(row.getCell(3)))));
                // 责任单位
                data.setResponsibleUnit(null == row.getCell(4) ? "" : BizUtils.getCellValue(row.getCell(4)));
                // 建设地址
                data.setConstructionAddress(null == row.getCell(5) ? "" : BizUtils.getCellValue(row.getCell(5)));
                // 建设规模及内容
                data.setConstructionScaleContent(null == row.getCell(6) ? "" : BizUtils.getCellValue(row.getCell(6)));
                // 计划总投资
                data.setTotalInvestment(null == row.getCell(7) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(7))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(7))));
                // 开工时间 ------
//                data.setCommencementTime(null == row.getCell(6) ? row.createCell(6).getDateCellValue() : row.getCell(6).getDateCellValue());
                try {
                    data.setCommencementTime(null == row.getCell(8) ? null : (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(8))))? null :
                            new SimpleDateFormat("yyyy-MM-dd").parse(BizUtils.getCellValue(row.getCell(8))));
                } catch (ParseException e) {
                    data.setCompletionTime(null == row.getCell(8) ? null : row.getCell(8).getDateCellValue());
                    e.printStackTrace();
                }
                // 完工时间
//                data.setCompletionTime(null == row.getCell(7) ? row.createCell(7).getDateCellValue() : row.getCell(7).getDateCellValue());
                try {
                    data.setCompletionTime(null == row.getCell(9) ? null : (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(9))))? null :
                            new SimpleDateFormat("yyyy-MM-dd").parse(BizUtils.getCellValue(row.getCell(9))));
                } catch (ParseException e) {
                    data.setCompletionTime(null == row.getCell(9) ? null : row.getCell(9).getDateCellValue());
                    e.printStackTrace();
                }
                //  计划年度总投资
                data.setTotalAnnualInvestment(null == row.getCell(10) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(10))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(10))));
                // 本年度建设任务
                data.setAnnualTasks(null == row.getCell(11) ? null : BizUtils.getCellValue(row.getCell(11)));
                // 1~12月投
                data.setInvestment1(null == row.getCell(12) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(12))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(12))));
                data.setInvestment2(null == row.getCell(13) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(13))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(13))));
                data.setInvestment3(null == row.getCell(14) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(14))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(14))));
                data.setInvestment4(null == row.getCell(15) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(15))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(15))));
                data.setInvestment5(null == row.getCell(16) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(16))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(16))));
                data.setInvestment6(null == row.getCell(17) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(17))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(17))));
                data.setInvestment7(null == row.getCell(18) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(18))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(18))));
                data.setInvestment8(null == row.getCell(19) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(19))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(19))));
                data.setInvestment9(null == row.getCell(20) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(20))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(20))));
                data.setInvestment10(null == row.getCell(21) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(21))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(21))));
                data.setInvestment11(null == row.getCell(22) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(22))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(22))));
                data.setInvestment12(null == row.getCell(23) ? null :
                        (StringUtils.isBlank(BizUtils.getCellValue(row.getCell(23))))? null : new BigDecimal(BizUtils.getCellValue(row.getCell(23))));
                // 备注
                data.setRemarks(null == row.getCell(24) ? "" : BizUtils.getCellValue(row.getCell(24)));
//                data.setProjectId(projectId);
//                data.setProjectName(pmm.get(projectId).getProjectName());
                baseMapper.insert(data);
                // 同步到检索表
                handleRetrieval(new GlobalRetrieval(), data);
            }
            //5、关闭流
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportDatatoExcel(QueryFilter<DecisionAnnualPlan> queryFilter, HttpServletResponse response) throws IOException {
        String fileName = "年度计划-导出结果";
        // 获取字典
        List<DictModel> buildType = sdm.queryDictListItemsByCode("ndjh-jslx");

        // 获取数据
//        BizUtils.handleFilter(queryFilter, "bdap", "pm");
        queryFilter.addFilter( "bdap.IS_DELE_", "0", QueryOP.EQUAL);
        PageBean queryFilterPageBean = queryFilter.getPageBean();
        queryFilterPageBean.setPageSize(-1);
        List<DecisionAnnualPlan> data = queryAllByPage(queryFilter).getRows();
        if(null==data||data.size()==0){
            throw new RuntimeException("没有要导出的的数据！");
        }

        // 翻译字典
        for(DecisionAnnualPlan ele : data){
            ele.setProjectType(BizUtils.getDicValueByCode(buildType, ele.getProjectType()));
        }

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

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

}

