package com.eitc.patient.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.bean.BeanUtils;
import com.eitc.patient.domain.DiagnosisType;
import com.eitc.patient.domain.DiagnosisTypeTemplate;
import com.eitc.patient.mapper.DiagnosisTypeMapper;
import com.eitc.patient.service.IDiagnosisTypeService;
import com.eitc.patient.service.IDiagnosisTypeTemplateService;
import com.eitc.patient.tree.DiagnosisTypeTree;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * DiagnosisTypeServiceImpl
 *
 * @author mtx
 * @date: 2024/05/17 15:39
 */
@Service
public class DiagnosisTypeServiceImpl extends ServiceImpl<DiagnosisTypeMapper, DiagnosisType> implements IDiagnosisTypeService {

    @Resource
    private IDiagnosisTypeTemplateService diagnosisTypeTemplateService;

    /**
     * 获取面包屑
     *
     * @param parentId id
     * @return 字符串
     * @author mtx
     * @date: 2024/5/31 10:12
     */
    @Override
    public String findCrumb(String parentId) {
        if (!"0".equals(parentId)) {
            // 获取父级
            DiagnosisType service = this.getById(parentId);
            String diagnosisName = service.getDiagnosisName();
            // 循环添加子集面包屑
            String s = findCrumb(service.getParentId());
            if (StringUtils.isNotBlank(s)) {
                return s + " > " + diagnosisName;
            } else {
                return diagnosisName;
            }
        }
        return "";
    }

    /**
     * 根据搜索条件查询所有的诊断分类
     *
     * @param diagnosisType 搜索条件
     * @return 列表
     */
    @Override
    public List<DiagnosisType> getDiagnosisTypes(DiagnosisType diagnosisType) {
        LambdaQueryWrapper<DiagnosisType> eq = Wrappers.<DiagnosisType>lambdaQuery()
                .like(StringUtils.isNotBlank(diagnosisType.getDiagnosisName()), DiagnosisType::getDiagnosisName, diagnosisType.getDiagnosisName()).or()
                .like(StringUtils.isNotBlank(diagnosisType.getDiagnosisNamePinyinFirstLetter()),
                        DiagnosisType::getDiagnosisNamePinyinFirstLetter, diagnosisType.getDiagnosisNamePinyinFirstLetter()).or()
                .like(StringUtils.isNotBlank(diagnosisType.getDiagnosisNamePinyin()),
                        DiagnosisType::getDiagnosisNamePinyin, diagnosisType.getDiagnosisNamePinyin())
                .orderByDesc(DiagnosisType::getCreateDate);

        return this.list(eq);
    }

    /**
     * 封装属性结构
     *
     * @param parentId 父级id
     * @param list     数据
     * @return 封装好的数据
     */
    @Override
    public List<DiagnosisTypeTree> getChildren(String parentId, List<DiagnosisTypeTree> list) {
        return list.stream().filter(t -> Objects.equals(t.getParentId(), parentId)).peek(
                m -> m.setChildrenList(getChildren(m.getId(), list))
        ).collect(Collectors.toList());
    }

    /**
     * 获取树形结构
     *
     * @param searchParam 搜索信息
     * @param visitType   状态
     * @return 返回结果
     * @author mtx
     * @date: 2024/8/21 9:36
     */
    @Override
    public List<DiagnosisTypeTree> findTreeList(String searchParam, String visitType) {
        // 获取分类列表
        List<DiagnosisType> list = this.getDiagnosisTypes(new DiagnosisType());
        // 封装树形结构
        List<DiagnosisTypeTree> treeBeans = new ArrayList<>();
        // 获取数据列表
        LambdaQueryWrapper<DiagnosisTypeTemplate> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(searchParam)) {
            wrapper.and(w -> w.like(DiagnosisTypeTemplate::getTemplateName, searchParam).or()
                    .like(DiagnosisTypeTemplate::getNamePinyinFirstLetter, searchParam).or()
                    .like(DiagnosisTypeTemplate::getNamePinyin, searchParam));
        }
        if (StringUtils.isNotBlank(visitType)) {
            wrapper.eq(DiagnosisTypeTemplate::getVisitType, visitType);
        }
        wrapper.eq(DiagnosisTypeTemplate::getEnableStatus, 1);
        List<DiagnosisTypeTemplate> templates = diagnosisTypeTemplateService.list(wrapper);
        if (CollectionUtils.isNotEmpty(templates)) {
            for (DiagnosisTypeTemplate template : templates) {
                DiagnosisTypeTree diagnosisTypeTree = new DiagnosisTypeTree();
                diagnosisTypeTree.setDiagnosisName(template.getTemplateName());
                diagnosisTypeTree.setTemplateDesc(template.getTemplateDesc());
                diagnosisTypeTree.setDiagnosisNamePinyin(template.getNamePinyin());
                diagnosisTypeTree.setDiagnosisNamePinyinFirstLetter(template.getNamePinyinFirstLetter());
                diagnosisTypeTree.setVisitType(template.getVisitType());
                diagnosisTypeTree.setParentId(template.getDiagnosisTypeId());
                diagnosisTypeTree.setId(template.getId());
                diagnosisTypeTree.setDiagnosisManageId(template.getDiagnosisManageId());

                treeBeans.add(diagnosisTypeTree);
            }
        }

        list.forEach(t -> {
            DiagnosisTypeTree diagnosisTypeTree = new DiagnosisTypeTree();
            BeanUtils.copyProperties(t, diagnosisTypeTree);
            treeBeans.add(diagnosisTypeTree);
        });

        //获取父节点
        return this.getChildren("0", treeBeans);
    }

    /**
     * 检查是否可以添加诊断类型
     * 此方法主要进行两个重要检查：
     * 1. 确保传入的诊断类型ID不为空，因为这是添加新诊断类型的必要条件
     * 2. 检查传入的诊断类型ID是否已经有子类型存在，如果存在子类型，则不允许添加新的诊断类型
     *
     * @param diagnosisTypeId 诊断类型ID，用于检查和添加新的诊断类型
     * @throws IllegalArgumentException 如果诊断类型ID为空或存在子类型，则抛出此异常
     */
    @Override
    public void checkAddDiagnosisType(String diagnosisTypeId) {
        // 检查诊断类型ID是否为空
        if (StringUtils.isBlank(diagnosisTypeId)) {
            throw new IllegalArgumentException("必填项不能为空");
        }

        // 查询是否有子类型存在
        long typeCount = this.count(Wrappers.<DiagnosisType>lambdaQuery().eq(DiagnosisType::getParentId, diagnosisTypeId));

        // 如果存在子类型，则不允许添加模板
        if (typeCount > 0) {
            throw new IllegalArgumentException("存在子类型，不允许添加模板");
        }
    }

}
