package com.kcim.service.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 cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.BeanUtil;
import com.kcim.common.util.ComputeDateUtils;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.common.util.excel.ExcelStyleUtil;
import com.kcim.common.util.excel.entity.EmpCostImportEntity;
import com.kcim.dao.model.CostIncomeFile;
import com.kcim.dao.model.ImportEmpCost;
import com.kcim.dao.repository.ImportEmpCostRepository;
import com.kcim.service.CostIncomeFileService;
import com.kcim.service.EmpCostImportService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 人事成本数据导入实现类
 * @author: Wang.YS
 * @create: 2023-10-18 19:26
 **/
@Service("EmpCostImportService")
@AllArgsConstructor
@Slf4j
public class EmpCostImportServiceImpl implements EmpCostImportService {

    ImportEmpCostRepository repository;

    CostIncomeGroupServiceImpl costIncomeGroupService;

    CostIncomeFileService costIncomeFileService;


    /**
     * 月度信息采集-人事成本数据导入-获取导入列表
     *
     * @param current     当前页
     * @param pageSize    页容量
     * @param computeDate 核算年月
     * @param filter      过滤条件 工号/姓名
     * @return 导入列表
     */
    @Override
    public Object getEmpCostList(Integer current, Integer pageSize, String computeDate, String filter) {
        Page<ImportEmpCost> page = repository.getPage(current, pageSize, computeDate, filter);
        List<ImportEmpCost> records = page.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current);
        }
        return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
    }

    /**
     * 月度信息采集-人事成本数据导入-获取导出模版
     *
     * @param response 出参
     * @return 出参
     */
    @SneakyThrows
    @Override
    public Object exportEmpCostList(HttpServletResponse response) throws RuntimeException {
        try {
            //配置excel 文件信息
            ExportParams params = new ExportParams();

            params.setTitle("说明：1、为了保证成功导入，请勿修改模板格式\n" +
                    "      2、工号、姓名、总工时、总成本必填");
            //设置导出样式
            params.setStyle(ExcelStyleUtil.class);
            //设置sheetName
            params.setSheetName("sheet1");
//            params.setHeaderColor();
//            params.setFreezeCol(2);
//                FileOutputStream outputStream = new FileOutputStream("E:\\人事成本导入模版.xlsx");

            Workbook workbook = ExcelExportUtil.exportExcel(params, EmpCostImportEntity.class,new ArrayList<>());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel");
            String fileName ="人事成本导入模版";
            response.setHeader("Content-Disposition",  URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
//                workbook.write(outputStream);
//                outputStream.close();
            workbook.close();
            log.info("接收到文件：{}",fileName);
        } catch (FileNotFoundException e) {
            throw new CostException(e.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return response.getOutputStream();
    }

    /**
     * 月度信息采集-人事成本数据导入-导入数据
     *
     * @param computeDate 核算年月
     * @param file        文件
     */
    @Override
    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
    public void importEmpCostList(String computeDate, MultipartFile file) {
        try {
            if (ObjectUtils.isEmpty(file) || file.getSize() == 0){
                throw new CostException("未获取到导入的excel文件内容");
            }
            log.info("接收到文件：{}",file.getOriginalFilename());
            // 参数1：文件流
            InputStream stream = file.getInputStream();
            // 参数2：导入类型
            ImportParams params = new ImportParams();
            //校验Excel 去掉空行
            params.setNeedVerify(true);
            IExcelVerifyHandler<EmpCostImportEntity> handler = val ->{
                if(StringUtils.isEmpty(val.getEmpCode())){
                    return new ExcelVerifyHandlerResult(false,"工号不能为空");
                }
                if(StringUtils.isEmpty(val.getEmpName())){
                    return new ExcelVerifyHandlerResult(false,"姓名不能为空");
                }
                if(StringUtils.isEmpty(val.getHour())){
                    return new ExcelVerifyHandlerResult(false,"总工时不能为空");
                }
                if(StringUtils.isEmpty(val.getCost())){
                    return new ExcelVerifyHandlerResult(false,"总成本不能为空");
                }
                return new ExcelVerifyHandlerResult(true);
            };
            params.setVerifyHandler(handler);
            // 标题占用多少行
            params.setTitleRows(1);
            // 头部属性占用多少行
            params.setHeadRows(1);
            List<EmpCostImportEntity> incomeImportEntities  = ExcelImportUtil.importExcel(stream, EmpCostImportEntity.class,params);
            if(!CollectionUtils.isEmpty(incomeImportEntities)){
                List<ImportEmpCost> saveList = new ArrayList<>();
                ImportEmpCost importEmpCost = new ImportEmpCost();
                importEmpCost.setHospId(UserContext.getHospId());
                importEmpCost.setComputeDate(computeDate);
                importEmpCost.setCreateTime(new Date());
                importEmpCost.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
                for (EmpCostImportEntity entity : incomeImportEntities) {
                    ImportEmpCost cost = BeanUtil.convertObj(importEmpCost, ImportEmpCost.class);
                    cost.setEmpCode(entity.getEmpCode());
                    cost.setEmpName(entity.getEmpName());
                    cost.setHour(entity.getHour());
                    cost.setSalary(entity.getSalary());
                    cost.setVariableCompensation(entity.getVariableCompensation());
                    cost.setCost(entity.getCost());
                    saveList.add(cost);
                }
                // 文件上传
                String uploadFile = costIncomeGroupService.uploadFile(file);
                // 上传记录保存
                if (StrUtil.isBlank(uploadFile)) {
                    throw new CostException(500, "文件上传异常");
                }
                CostIncomeFile costIncomeFile = costIncomeFileService.saveFile(saveList.size(), file, UserContext.getHospId(), new ArrayList<>(), uploadFile, NumberConstant.FOUR, ComputeDateUtils.getComputeYear(computeDate), ComputeDateUtils.getComputeMonth(computeDate));
                Long id = costIncomeFile.getId();

                if(!CollectionUtils.isEmpty(saveList)){
//                    check(computeDate);
                    saveList.forEach(f->f.setFileId(id));
                    repository.saveBatch(saveList,50);
                }
            }
        } catch (Exception e) {

            throw new CostException(e.getMessage());
        }
    }

    @Override
    public void removeEmpCost(String computeDate) {
        check(computeDate);
        //
    }

    /**
     * @param computeDate
     * @param fileId
     */
    @Override
    public void removeEmpCostByFileId(String computeDate, Long fileId) {
        repository.removeEmpCostByFileId(computeDate,fileId);
    }

    /**
     * @param computeDate
     * @param fileId
     */
    @Override
    public void reducingEmpCostByFileId(String computeDate, Long fileId) {
        repository.reducingEmpCostByFileId(computeDate,fileId);

    }

    private void check(String computeDate) {
        List<ImportEmpCost> byComputeDate = repository.getByComputeDate(computeDate);
        if(!CollectionUtils.isEmpty(byComputeDate)){
            for (ImportEmpCost importEmpCost : byComputeDate) {
                importEmpCost.setDeleteTime(new Date());
                importEmpCost.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId()));
            }
            repository.updateBatchById(byComputeDate);
            List<Integer> collect = byComputeDate.stream().map(ImportEmpCost::getId).collect(Collectors.toList());
            repository.removeBatchByIds(collect);

        }
    }
}
