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 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.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.common.util.excel.ExcelStyleUtil;
import com.kcim.common.util.excel.entity.DiseaseTypeMapImportEntity;
import com.kcim.dao.model.DiseaseType;
import com.kcim.dao.model.DiseaseTypeDiagMap;
import com.kcim.dao.model.Item;
import com.kcim.dao.repository.DiseaseTypeDiagMapRepository;
import com.kcim.dao.repository.DiseaseTypeRepository;
import com.kcim.service.DiseaseTypeDiagMapService;
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.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-11-07 19:13
 **/
@Service("DiseaseTypeDiagMapService")
@Slf4j
@AllArgsConstructor
public class DiseaseTypeDiagMapServiceImpl implements DiseaseTypeDiagMapService {
    DiseaseTypeDiagMapRepository repository;

    DiseaseTypeRepository diseaseTypeRepository;
    /**
     * 获取诊断与病种对照列表
     * @param current 当前页
     * @param pageSize 页容量
     * @param name 诊断名称
     * @param type 显示未对照 0 全部 1未对照
     * @return 列表
     */
    @Override
    public Object getDiseaseTypeMapList(Integer current, Integer pageSize, String name, Integer type) {
        Page<DiseaseTypeDiagMap> page = repository.getPage(current, pageSize, name, type);
        List<DiseaseTypeDiagMap> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
        }
        List<DiseaseType> list = diseaseTypeRepository.getList();
        if(CollectionUtils.isEmpty(list)){
            throw new CostException("当前院区未添加病种字典，添先添加病种字典再进行对照");
        }
        Map<String,String> map = list.stream().collect(Collectors.toMap(DiseaseType::getCode, DiseaseType::getName, (a, b) -> b));
        records.forEach(record -> record.setDiseaseTypeCodeName(map.get(record.getDiseaseTypeCode())));
        return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current);
    }

    /**
     * 新增诊断
     * @param request 入参
     */
    @Override
    public void addDiseaseTypeMap(DiseaseTypeDiagMap request) {
        List<DiseaseTypeDiagMap> byCode = repository.getByDiagCode(request.getDiagCode());
        if(!CollectionUtils.isEmpty(byCode)){
            throw new CostException("当前诊断代码已存在，请修改后再保存");
        }
        request.setHospId(UserContext.getCurrentLoginHospId());
        request.setCreateTime(new Date());
        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        repository.save(request);
    }

    /**
     * 删除诊断
     * @param id 主键
     */
    @Override
    public void deleteDiseaseTypeMap(Integer id) {
        repository.deleteDiseaseTypeMap(id);
    }

    /**
     * 编辑诊断
     * @param request 入参
     */
    @Override
    public void editDiseaseTypeMap(DiseaseTypeDiagMap request) {
        Integer id = request.getId();
        if(id ==null){
            throw new CostException("编辑诊断时，主键必填");
        }
        DiseaseTypeDiagMap diagMap = repository.getById(id);
        DiseaseTypeDiagMap oneByCode = repository.getOneByDiagCode(request.getDiagCode());

        if(Objects.nonNull(diagMap)){
            if(Objects.isNull(oneByCode)||oneByCode.getId().equals(id)){
                BeanUtil.convertObj(request,diagMap);
                diagMap.setUpdateTime(new Date());
                diagMap.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
                repository.updateById(diagMap);
            }else {
                throw new CostException("当前诊断代码已存在，请修改后再保存");
            }
        }

    }

    /**
     * 导出诊断模版
     * @param response 出参
     * @return 出参
     */
    @SneakyThrows
    @Override
    public Object exportDiseaseTypeMap(HttpServletResponse response) {
        try {
            //配置excel 文件信息
            ExportParams params = new ExportParams();

            params.setTitle("说明：1、为了保证成功导入，请勿修改模板格式\n" +
                    "      2、国家编码为国标2.0的ICD码");
            //设置导出样式
            params.setStyle(ExcelStyleUtil.class);
            //设置sheetName
            params.setSheetName("诊断项目");
//            FileOutputStream outputStream = new FileOutputStream("E:\\诊断项目模版.xlsx");
            Workbook workbook = ExcelExportUtil.exportExcel(params, DiseaseTypeMapImportEntity.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 file excel
     */
    @Override
    public void importDiseaseTypeMap(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<DiseaseTypeMapImportEntity> handler = val ->{
                if(StringUtils.isEmpty(val.getCode())){
                    return new ExcelVerifyHandlerResult(false,"诊断代码不能为空");
                }
                if(StringUtils.isEmpty(val.getName())){
                    return new ExcelVerifyHandlerResult(false,"诊断名称不能为空");
                }
                return new ExcelVerifyHandlerResult(true);
            };
            params.setVerifyHandler(handler);
            // 标题占用多少行
            params.setTitleRows(1);
            // 头部属性占用多少行
            params.setHeadRows(1);
            List<DiseaseTypeMapImportEntity> diseaseTypeMapImportEntities  = ExcelImportUtil.importExcel(stream, DiseaseTypeMapImportEntity.class,params);
            if(!CollectionUtils.isEmpty(diseaseTypeMapImportEntities)){
                List<DiseaseTypeDiagMap> saveList = new ArrayList<>();
                DiseaseTypeDiagMap diseaseTypeDiagMap =new DiseaseTypeDiagMap();
                diseaseTypeDiagMap.setHospId(UserContext.getHospId());
                diseaseTypeDiagMap.setCreateTime(new Date());
                diseaseTypeDiagMap.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
                for (DiseaseTypeMapImportEntity entity : diseaseTypeMapImportEntities) {
                    DiseaseTypeDiagMap diagMap = BeanUtil.convertObj(diseaseTypeDiagMap, DiseaseTypeDiagMap.class);
                    diagMap.setDiagCode(entity.getCode());
                    diagMap.setDiagName(entity.getName());
                    diagMap.setIcdCode(entity.getIcdCode());
                    saveList.add(diagMap);
                }
                if(!CollectionUtils.isEmpty(saveList)){
                    check();
                    repository.saveBatch(saveList,100);
                }
            }
        } catch (Exception e) {
            throw new CostException(e.getMessage());
        }
    }

    private void check() {
        List<DiseaseTypeDiagMap> list = repository.getList();
        if(!CollectionUtils.isEmpty(list)){
            repository.removeList(list);
        }
    }

    /**
     *对照诊断与病种
     */
    @Override
    public void matchDiseaseTypeMap() {
        //获取病种字典
        List<DiseaseType> list = diseaseTypeRepository.getList();
        if(CollectionUtils.isEmpty(list)){
            throw new CostException("当前院区未添加病种字典，添先添加病种字典再进行对照");
        }
        List<DiseaseTypeDiagMap> diagMaps = repository.getList();
        if(CollectionUtils.isEmpty(diagMaps)){
            throw new CostException("当前院区未添加诊断字典，添先添加诊断再进行对照");
        }
        for (DiseaseType diseaseType : list) {
            String code = diseaseType.getCode();
            String replace = code.replace(".", "");
            if(replace.length()>3){
                String subStr = replace.substring(0, 4);
                diseaseType.setReplaceCode(subStr);
            }else {
                diseaseType.setReplaceCode(replace);
            }

        }


        Map<String,DiseaseType> map = list.stream().collect(Collectors.toMap(DiseaseType::getReplaceCode, type -> type, (a, b) -> b));
        List<DiseaseTypeDiagMap> collect = diagMaps.stream().filter(f -> StringUtils.isEmpty(f.getDiseaseTypeCode())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(collect)){
            for (DiseaseTypeDiagMap diagMap : collect) {
                String diagCode = diagMap.getIcdCode();
                if(!StringUtils.isEmpty(diagCode)){
                    String replace = diagCode.replace(".", "");
                    String subStr = replace.substring(0, 4);
                    DiseaseType diseaseType = map.get(subStr);
                    if(Objects.nonNull(diseaseType)){
                        diagMap.setDiseaseTypeCode(diseaseType.getCode());
                    }
                }
            }
            repository.updateBatchById(collect);
        }

    }
}
