package org.dromara.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.idev.excel.FastExcel;
import cn.idev.excel.annotation.ExcelIgnore;
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.read.builder.ExcelReaderBuilder;
import cn.idev.excel.read.listener.ReadListener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.mapper.SysDictDataMapper;
import org.dromara.system.service.ISysDictDataService;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.SysDiseaseLabelBo;
import org.dromara.system.domain.vo.SysDiseaseLabelVo;
import org.dromara.system.domain.SysDiseaseLabel;
import org.dromara.system.mapper.SysDiseaseLabelMapper;
import org.dromara.system.service.ISysDiseaseLabelService;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * 疾病/部位标签Service业务层处理
 *
 * @author Lion Li
 * @date 2025-06-26
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysDiseaseLabelServiceImpl implements ISysDiseaseLabelService {

    private final SysDiseaseLabelMapper baseMapper;
    private final ISysDictDataService dictDataService;

    /**
     * 查询疾病/部位标签
     *
     * @param labelId 主键
     * @return 疾病/部位标签
     */
    @Override
    public SysDiseaseLabelVo queryById(Long labelId) {
        return baseMapper.selectVoById(labelId);
    }

    /**
     * 分页查询疾病/部位标签列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 疾病/部位标签分页列表
     */
    @Override
    public TableDataInfo<SysDiseaseLabelVo> queryPageList(SysDiseaseLabelBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysDiseaseLabel> lqw = buildQueryWrapper(bo);
        Page<SysDiseaseLabelVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (CollUtil.isNotEmpty(result.getRecords())) {
            Map<String, SysDictDataVo> labelMap = dictDataService.selectMapByType("disease_label").getData();
            result.getRecords().forEach(v -> {
                SysDictDataVo dataVo = labelMap.get(v.getCategory());
                if (ObjUtil.isNotNull(dataVo)) {
                    v.setCategoryName(dataVo.getDictLabel());
                }
            });
        }

        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的疾病/部位标签列表
     *
     * @param bo 查询条件
     * @return 疾病/部位标签列表
     */
    @Override
    public List<SysDiseaseLabelVo> queryList(SysDiseaseLabelBo bo) {
        LambdaQueryWrapper<SysDiseaseLabel> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<SysDiseaseLabel> buildQueryWrapper(SysDiseaseLabelBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysDiseaseLabel> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(SysDiseaseLabel::getLabelId);
//        lqw.like(StringUtils.isNotBlank(bo.getLabelName()), SysDiseaseLabel::getLabelName, bo.getLabelName());
//        lqw.eq(StringUtils.isNotBlank(bo.getLabelCode()), SysDiseaseLabel::getLabelCode, bo.getLabelCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCategory()), SysDiseaseLabel::getCategory, bo.getCategory());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDiseaseLabel::getStatus, bo.getStatus());
        lqw.and(StringUtils.isNotBlank(bo.getLabelCode()), (wrapper) -> {
            wrapper.like(SysDiseaseLabel::getLabelCode, bo.getLabelCode())
                .or()
                .like(SysDiseaseLabel::getLabelName, bo.getLabelCode());
        });
        return lqw;
    }

    /**
     * 新增疾病/部位标签
     *
     * @param bo 疾病/部位标签
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(SysDiseaseLabelBo bo) {
        SysDiseaseLabel add = MapstructUtils.convert(bo, SysDiseaseLabel.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setLabelId(add.getLabelId());
        }
        return flag;
    }

    /**
     * 修改疾病/部位标签
     *
     * @param bo 疾病/部位标签
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(SysDiseaseLabelBo bo) {
        SysDiseaseLabel update = MapstructUtils.convert(bo, SysDiseaseLabel.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SysDiseaseLabel entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除疾病/部位标签信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public R<?> importExcel(MultipartFile file) throws Exception {
        if (ObjUtil.isNull(file)) {
            return R.fail("请选择文件!");
        }

        List<Map<Integer, String>> excelList = FastExcel.read(file.getInputStream())
            .headRowNumber(3)
            .sheet().doReadSync();

        log.info("开始导入数据");
        if (CollUtil.isEmpty(excelList)) {
            return R.fail("读取数据为空!");
        }
        log.info("size:" + excelList.size());

        Map<String, String> labelMap = MapUtil.newHashMap(excelList.size());
        dictDataService.selectMapByType("disease_label").getData().forEach((k, v) -> {
            labelMap.put(v.getDictLabel(), k);
        });

        List<SysDiseaseLabel> labelList = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        excelList.forEach(v -> {
            if (MapUtil.isEmpty(v) || v.size() != 3) {
                builder.append(labelList.size() + 4).append("、");
                return;
            }
            SysDiseaseLabel label = new SysDiseaseLabel();
            label.setLabelCode(v.get(0));
            label.setLabelName(v.get(1));
            label.setCategory(labelMap.get(v.get(2)));
            if (StrUtil.isBlank(label.getCategory()) || StrUtil.isBlank(label.getLabelCode())
                || StrUtil.isBlank(label.getLabelName())) {
                builder.append(labelList.size() + 4).append("、");
                return;
            }
            labelList.add(label);
        });

        if (builder.length() == 0) {
            baseMapper.insertBatch(labelList);
        } else {
            return R.fail("以下行数据不完整：" + builder);
        }

        return R.ok("导入成功！");
    }
}
