package thyyxxk.webserver.service.dictionary;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.dictionary.OpLevelManagementDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.OpLevelManagement;
import thyyxxk.webserver.entity.zhuyuanyisheng.shoushu.ZdIcd9Cm3;
import thyyxxk.webserver.service.hutoolcache.UserCache;
import thyyxxk.webserver.utils.AssertUtil;
import thyyxxk.webserver.utils.CommonUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author:lihong
 * @Date: 2023/6/8
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OpLevelManagementService {
    private final OpLevelManagementDao dao;
    private final UserCache userCache;

    public ResultVo<IPage<ZdIcd9Cm3>> queryZdIcd9Cm3(ZdIcd9Cm3 param) {
        IPage<ZdIcd9Cm3> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("del_flag", 0);
        queryWrapper.in(CollUtil.isNotEmpty(param.getOpScaleList()), "op_scale", param.getOpScaleList());
        String sqlTemplate = StrUtil.format("(code like '%{}%' or name like '%{}%' or py_code like '%{}%' )", param.getCode(), param.getCode(), param.getCode());
        queryWrapper.apply(StrUtil.isNotBlank(param.getCode()), sqlTemplate);
        dao.queryZdIcd9Cm3Page(page, queryWrapper);
        page.setRecords(page.getRecords());
        page.setTotal(page.getTotal());
        return ResultVoUtil.success(page);
    }


    public ResultVo<String> saveZdIcd9Cm3(ZdIcd9Cm3 saveParam) {
        AssertUtil.isnotBlank(saveParam.getCode(), "手术编码不能为空");
        AssertUtil.isnotBlank(saveParam.getOpScale(), "手术级别不能为空");
        dao.updateZdIcd9Cm3OpScaleByCode(saveParam.getCode(), saveParam.getOpScale());
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "保存成功");
    }

    public ResultVo<IPage<OpLevelManagement>> queryOpLevelManagement(OpLevelManagement param) {
        IPage<OpLevelManagement> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like(StrUtil.isNotBlank(param.getNameDoctor()), "name_doctor", param.getNameDoctor());
        queryWrapper.like(StrUtil.isNotBlank(param.getCodeDoctor()), "code_doctor", param.getCodeDoctor());
        dao.selectDoctorPage(page, queryWrapper);
        page.setRecords(page.getRecords());
        page.setTotal(page.getTotal());
        return ResultVoUtil.success(page);
    }


    public ResultVo<IPage<OpLevelManagement>> queryOprtInfo(OpLevelManagement param) {
        AssertUtil.isnotBlank(param.getCode(), "医生编号不能为空");
        IPage<OpLevelManagement> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("code", param.getCode());
        queryWrapper.like(StrUtil.isNotBlank(param.getCodeOp()), "code_op", param.getCodeOp());
        queryWrapper.like(StrUtil.isNotBlank(param.getCodeOpName()), "code_op_name", param.getCodeOpName());
        dao.selectPage(page, queryWrapper);
        page.setRecords(page.getRecords());
        page.setTotal(page.getTotal());
        return ResultVoUtil.success(page);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> saveOpLevelManagement(OpLevelManagement saveParam) {
        AssertUtil.isnotBlank(saveParam.getCode(), "医生编号不能为空");
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("code", saveParam.getCode());
        dao.delete(queryWrapper);
        Date now = new Date();
        if (CollUtil.isNotEmpty(saveParam.getSaveData())) {
            saveParam.getSaveData().forEach(item -> {
                item.setCode(saveParam.getCode());
                item.setCodeDoctor(saveParam.getCodeDoctor());
                item.setNameDoctor(saveParam.getNameDoctor());
                item.setInputTime(now);
                item.setInputUser(TokenUtil.getInstance().getTokenUserId());
            });
            List<OpLevelManagement> collect = saveParam.getSaveData().stream().distinct().collect(Collectors.toList());
            List<List<OpLevelManagement>> split = CollUtil.split(collect, 50);
            for (List<OpLevelManagement> item : split) {
                dao.batchSaveOpLevelManagement(item);
            }
        }
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "保存成功");
    }


    public ResultVo<String> getEmpCodeRs(String code) {
        return ResultVoUtil.success(userCache.get(code).getCodeRs());
    }

    public ResultVo<String> uploadOpLevelManagement(MultipartFile file) {
        ExcelReader reader = null;
        try {
            reader = ExcelUtil.getReader(file.getInputStream());
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
        List<Map<String, Object>> mapList = reader.readAll();
        Set<String> codeDoctors = mapList.stream().map(item -> {
            return Convert.toStr(item.get("工号"), "").trim();
        }).collect(Collectors.toSet());
        List<OpLevelManagement> empCodes = dao.selectEmpCode(CommonUtil.toInStringSql(CollUtil.newArrayList(codeDoctors)));
        Map<String, OpLevelManagement> codeMap = empCodes.stream().collect(Collectors.toMap(OpLevelManagement::getCodeDoctor, a -> a, (k1, k2) -> k1));
        List<OpLevelManagement> data = new ArrayList<>();
        for (Map<String, Object> item : mapList) {
            OpLevelManagement opLevelManagement = new OpLevelManagement();
            opLevelManagement.setCode(codeMap.get(Convert.toStr(item.get("工号"), "").trim()).getCode());
            opLevelManagement.setCodeDoctor(Convert.toStr(item.get("工号"), "").trim());
            opLevelManagement.setNameDoctor(Convert.toStr(item.get("姓名"), "").trim());
            opLevelManagement.setCodeOp(Convert.toStr(item.get("手术编码"), "").trim());
            opLevelManagement.setCodeOpName(Convert.toStr(item.get("手术名称"), "").trim());
            opLevelManagement.setInputUser(TokenUtil.getInstance().getTokenUserId());
            data.add(opLevelManagement);
        }
        if (CollUtil.isNotEmpty(data)) {
            List<OpLevelManagement> collect = data.stream().filter(item -> StrUtil.isNotBlank(item.getCode()) && StrUtil.isNotBlank(item.getCodeOp())).collect(Collectors.toList());
            if (CollUtil.isEmpty(collect)) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_HTML_ERROR, "导入的数据格式不对或者数据为空!");
            }
            List<List<OpLevelManagement>> splitData = CollUtil.split(collect, 50);
            for (List<OpLevelManagement> item : splitData) {
                dao.batchSaveOpLevelManagement(item);
            }
            //数据去重
            dao.distinctOpLevelManagement();
        }
        return ResultVoUtil.success();
    }
}
