package com.eitc.patient.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eitc.common.utils.poi.ExcelUtil;
import com.eitc.patient.constant.PatientConstant;
import com.eitc.patient.domain.DiagnosisTypeTemplate;
import com.eitc.patient.enums.DiagnosisTypeTemplateReviewStatusEnum;
import com.eitc.patient.excel.DiagnosisTypeTemplateExcel;
import com.eitc.patient.mapper.DiagnosisTypeTemplateMapper;
import com.eitc.patient.service.IDiagnosisTypeTemplateService;
import com.eitc.patient.utils.PatientUtil;
import com.eitc.patient.vo.DiagnosisTypeTemplateSaveVO;
import com.eitc.patient.vo.DiagnosisTypeTemplateVO;
import com.eitc.system.service.ISysDictDataService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * DiagnosisTypeTemplateServiceImpl
 *
 * @author mtx
 * @date: 2024/05/17 15:39
 */
@Service
public class DiagnosisTypeTemplateServiceImpl extends ServiceImpl<DiagnosisTypeTemplateMapper, DiagnosisTypeTemplate> implements IDiagnosisTypeTemplateService {

    @Resource
    private ISysDictDataService sysDictDataService;


    /**
     * 获取模板选项的json串
     *
     * @param templateExample 要获取json串的示例
     * @return json串
     * @author mtx
     * @date: 2024/5/20 14:50
     */
    @Override
    public String findTemplateOptionJson(String templateExample) {
        JSONObject templateOption = new JSONObject();
        if (StringUtils.isNotBlank(templateExample)) {
            Matcher matcher = PatientConstant.COMPILE.matcher(templateExample);
            int num = 1;
            // 牙{发黑、有洞、龋洞} {1、2、3、6} 个月  将{}里的内容存到json串里
            // 将《牙{发黑、有洞、龋洞} {1、2、3、6} 个月》转换成 {"patient_diagnosisTypeTemplate_1":["发黑","有洞","龋洞"],"patient_diagnosisTypeTemplate_2":["1","2","3","6"]}
            while (matcher.find()) {
                String group = matcher.group(1);
                String[] split = group.split("、");
                templateOption.put(PatientConstant.DIAGNOSIS_TYPE_TEMPLATE_KEY_PREFIX + num, split);
                num++;
            }
        }
        return templateOption.toJSONString();
    }

    /**
     * 获取模板数据中{}中的数据
     *
     * @param templateExample 要获取json串的示例
     * @return json串
     * @author mtx
     * @date: 2024/5/20 14:50
     */
    @Override
    public String findTemplateInfo(String templateExample) {
        if (StringUtils.isEmpty(templateExample)) {
            return "";
        }
        // 将《牙{发黑、有洞、龋洞} {1、2、3、6} 个月》转换成 牙patient_diagnosisTypeTemplate_1 patient_diagnosisTypeTemplate_2 个月
        Matcher matcher = PatientConstant.COMPILE.matcher(templateExample);
        int num = 1;
        while (matcher.find()) {
            String oldStr = templateExample;
            String target = matcher.group(0);
            String replacement = PatientConstant.DIAGNOSIS_TYPE_TEMPLATE_KEY_PREFIX + num;

            templateExample = Pattern.compile(target, Pattern.LITERAL).matcher(oldStr).replaceFirst(Matcher.quoteReplacement(replacement));
            num++;
        }
        return templateExample;
    }

    /**
     * 导入诊断分类模板
     *
     * @param file            文件
     * @param diagnosisTypeId 诊断分类id
     * @return AjaxResult
     * @author mtx
     * @date: 2024/5/20 15:27
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<DiagnosisTypeTemplateExcel> importTemplate(MultipartFile file, String diagnosisTypeId) throws IOException {
        boolean b = true;
        List<DiagnosisTypeTemplate> diagnosisTypeTemplateList = new ArrayList<>();
        List<DiagnosisTypeTemplateExcel> list;

        // 1.解析excel
        ExcelUtil<DiagnosisTypeTemplateExcel> util = new ExcelUtil<>(DiagnosisTypeTemplateExcel.class);
        list = util.importExcel(file.getInputStream());
        // 2.如果解析数据为空则返回错误信息
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("上传数据为空，请填写");
        }
        AtomicInteger num = new AtomicInteger(1);
        // 3.校验数据是否正确
        for (DiagnosisTypeTemplateExcel excel : list) {
            if (StringUtils.isEmpty(excel.getTemplateName())) {
                excel.setMsg("模板名称不能为空");
                b = false;
                continue;
            }

            String typeTemplateName = sysDictDataService.selectDictLabel(PatientConstant.DICT_KEY_DIAGNOSIS_TYPE_TEMPLATE_NAME, excel.getTemplateName());
            if (StringUtils.isEmpty(typeTemplateName)) {
                excel.setMsg("模板名称错误");
                b = false;
                continue;
            }

            if (StringUtils.isEmpty(excel.getTemplateExample())) {
                excel.setMsg("模板示例不能为空");
                b = false;
            }
        }
        for (String s : PatientUtil.diagnosisTypeTemplateKeyList()) {
            Optional<DiagnosisTypeTemplateExcel> first = list.stream().filter(li -> s.equals(li.getTemplateName())).findFirst();
            if (first.isPresent()) {
                DiagnosisTypeTemplateExcel excel = first.get();
                DiagnosisTypeTemplate diagnosisTypeTemplate = new DiagnosisTypeTemplate();
                // 牙{发黑、有洞、龋洞} {1、2、3、6} 个月
                diagnosisTypeTemplate.setTemplateName(excel.getTemplateName());
                String templateExample = excel.getTemplateExample();
                if (StringUtils.isNotEmpty(templateExample)) {
                    diagnosisTypeTemplate.setTemplateExample(templateExample);
                    diagnosisTypeTemplate.setTemplateOption(this.findTemplateOptionJson(templateExample));
                    diagnosisTypeTemplate.setTemplateInfo(this.findTemplateInfo(templateExample));
                }
                diagnosisTypeTemplate.setReviewStatus(DiagnosisTypeTemplateReviewStatusEnum.ALREADY_AUDITING.getCode());
                diagnosisTypeTemplate.setDiagnosisTypeId(diagnosisTypeId);
                diagnosisTypeTemplate.setOrderNum(num.getAndIncrement());
                diagnosisTypeTemplateList.add(diagnosisTypeTemplate);
            } else {
                throw new RuntimeException("模板错误");
            }
        }

        if (b && CollectionUtils.isNotEmpty(diagnosisTypeTemplateList)) {
            // 4.删除历史数据
            this.remove(Wrappers.<DiagnosisTypeTemplate>lambdaQuery().eq(DiagnosisTypeTemplate::getDiagnosisTypeId, diagnosisTypeId));
            // 5.保存数据并返回
            this.saveBatch(diagnosisTypeTemplateList);
        }

        return b ? Collections.emptyList() : list;
    }

    /**
     * 新增或修改诊断模板
     *
     * @param entry 参数
     * @return 返回值
     * @author mtx
     * @date: 2024/6/7 14:06
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean add(DiagnosisTypeTemplateSaveVO entry) {
        String diagnosisTypeId = entry.getDiagnosisTypeId();
        List<DiagnosisTypeTemplateVO> diagnosisTypeTemplateList = entry.getDiagnosisTypeTemplateList();
        AtomicInteger num = new AtomicInteger(1);
        // 封装诊断模板数据
        List<DiagnosisTypeTemplate> collect = diagnosisTypeTemplateList.stream().map(typeTemplateVO -> {
            // 封装模板数据
            DiagnosisTypeTemplate diagnosisTypeTemplate = new DiagnosisTypeTemplate();
            String templateExample = typeTemplateVO.getTemplateExample();
            if (StringUtils.isNotBlank(templateExample)) {
                diagnosisTypeTemplate.setTemplateOption(this.findTemplateOptionJson(templateExample));
                diagnosisTypeTemplate.setTemplateInfo(this.findTemplateInfo(templateExample));
                diagnosisTypeTemplate.setTemplateExample(templateExample);
            }
            diagnosisTypeTemplate.setReviewStatus(DiagnosisTypeTemplateReviewStatusEnum.ALREADY_AUDITING.getCode());
            diagnosisTypeTemplate.setTemplateName(typeTemplateVO.getTemplateName());
            diagnosisTypeTemplate.setDiagnosisTypeId(diagnosisTypeId);
            diagnosisTypeTemplate.setOrderNum(num.getAndIncrement());
            return diagnosisTypeTemplate;
        }).collect(Collectors.toList());

        return this.saveBatch(collect);
    }

}
