package org.dromara.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
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.SysDept;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.*;
import org.dromara.web.domain.bo.NutritionEducationBo;
import org.dromara.web.domain.vo.ConsultantResultTemplateVo;
import org.dromara.web.domain.vo.NutritionEducationTemplateVo;
import org.dromara.web.domain.vo.NutritionEducationVo;
import org.dromara.web.mapper.NutritionEducationMapper;
import org.dromara.web.mapper.NutritionEducationTemplateMapper;
import org.dromara.web.service.INutritionEducationService;
import org.springframework.stereotype.Service;


import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 营养宣教Service业务层处理
 *
 * @author Lion Li
 * @date 2025-07-18
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class NutritionEducationServiceImpl implements INutritionEducationService {

    private final NutritionEducationMapper baseMapper;

    private final SysDeptMapper deptMapper;

    private final SysUserMapper userMapper;

    private final NutritionEducationTemplateMapper templateMapper;

    /**
     * 查询营养宣教
     *
     * @param id 主键
     * @return 营养宣教
     */
    @Override
    public NutritionEducationVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询营养宣教列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 营养宣教分页列表
     */
    @Override
    public TableDataInfo<NutritionEducationVo> queryPageList(NutritionEducationBo bo, PageQuery pageQuery) {

        LambdaQueryWrapper<NutritionEducation> lqw = buildQueryWrapper(bo);
        Page<NutritionEducationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<NutritionEducationVo> records = result.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            Set<Long> deptList = CollUtil.newHashSet();
            Set<Long> userList = CollUtil.newHashSet();
            records.forEach(v -> {
                deptList.add(v.getDeptId());
                userList.add(v.getCreateBy());
            });
            Map<Long, String> deptMap = deptMapper.selectList(Wrappers.lambdaQuery(SysDept.class)
                .select(SysDept::getDeptId, SysDept::getDeptName)
                .in(SysDept::getDeptId, deptList)).stream().collect(Collectors.toMap(k1 -> k1.getDeptId(), k2 -> k2.getDeptName(), (k1, k2) -> k1));
            Map<Long, String> userMap = userMapper.selectList(Wrappers.lambdaQuery(SysUser.class)
                .select(SysUser::getUserId, SysUser::getUserName)
                .in(SysUser::getUserId, userList)).stream().collect(Collectors.toMap(k1 -> k1.getUserId(), k2 -> k2.getUserName(), (k1, k2) -> k1));
            records.forEach(v -> {
                v.setDeptName(deptMap.get(v.getDeptId()));
                v.setCreateByUser(userMap.get(v.getCreateBy()));
            });
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的营养宣教列表
     *
     * @param bo 查询条件
     * @return 营养宣教列表
     */
    @Override
    public List<NutritionEducationVo> queryList(NutritionEducationBo bo) {
        LambdaQueryWrapper<NutritionEducation> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<NutritionEducation> buildQueryWrapper(NutritionEducationBo bo) {
        Map<String, Object> params = bo.getParams();
        List<Date> dateRange = bo.getDateRange();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<SysUser> userList = userMapper.selectList(Wrappers.lambdaQuery(SysUser.class).select(SysUser::getUserId, SysUser::getUserName));
        Map<String, Long> userMap = userList.stream().collect(Collectors.toMap(k1 -> String.valueOf(k1.getUserName()), k2 -> k2.getUserId(), (k1, k2) -> k1));
        LambdaQueryWrapper<NutritionEducation> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(NutritionEducation::getId);
        lqw.eq(StringUtils.isNotBlank(bo.getType()), NutritionEducation::getType, bo.getType());
        lqw.eq(bo.getPatientId() != null, NutritionEducation::getPatientId, bo.getPatientId());
        lqw.eq(StringUtils.isNotBlank(bo.getOutpatientNo()), NutritionEducation::getOutpatientNo, bo.getOutpatientNo());

        if (StringUtils.isNotBlank(bo.getSearchValue())) {
            lqw.and(wrapper -> wrapper.like(NutritionEducation::getCreateBy, userMap.get(bo.getSearchValue())).or().like(NutritionEducation::getOutpatientNo, bo.getSearchValue()));
        }
        if (dateRange != null && dateRange.size() == 2) {
            String startTime = sdf.format(dateRange.get(0)) + " 00:00:00";  // 开始时间
            String endTime = sdf.format(dateRange.get(1)) + " 23:59:59";    // 结束时间
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                lqw.between(NutritionEducation::getCreateTime, startTime, endTime);

            }
        }
        return lqw;
    }

    /**
     * 新增营养宣教
     *
     * @param bo 营养宣教
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(NutritionEducationBo bo) {
        bo.setContent(URLDecoder.decode(new String(Base64.getDecoder().decode(bo.getContentStr()), StandardCharsets.UTF_8)));
        NutritionEducation add = MapstructUtils.convert(bo, NutritionEducation.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改营养宣教
     *
     * @param bo 营养宣教
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(NutritionEducationBo bo) {
        bo.setContent(URLDecoder.decode(new String(Base64.getDecoder().decode(bo.getContentStr()), StandardCharsets.UTF_8)));
        NutritionEducation update = MapstructUtils.convert(bo, NutritionEducation.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(NutritionEducation 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 Map<String, Object> queryTemplateList() {
        Map<String, Object> resultMap = new HashMap<>();

        List<SysDept> deptList = deptMapper.selectList(Wrappers.lambdaQuery(SysDept.class).select(SysDept::getDeptId, SysDept::getDeptName));
        Map<String, String> deptNameMap = deptList.stream().collect(Collectors.toMap(k1 -> String.valueOf(k1.getDeptId()), k2 -> String.valueOf(k2.getDeptName()), (k1, k2) -> k1));
        List<Map<String, Object>> result = new ArrayList<>();

        // 1. 处理 "基础/公共模板" 部分
        Map<String, Object> publicTemplate = new HashMap<>();
        publicTemplate.put("label", "基础/公共模板");


        // 查询所有非个人的公共模板（deptId不为null的模板）
        List<NutritionEducationTemplateVo> publicTemplates = templateMapper.selectVoList(new LambdaQueryWrapper<NutritionEducationTemplate>().isNotNull(NutritionEducationTemplate::getDeptId).orderByAsc(NutritionEducationTemplate::getDeptId)  // 按部门ID排序
        );

        // 使用LinkedHashMap保持插入顺序
        Map<String, List<Map<String, Object>>> deptMap = new LinkedHashMap<>();

        // 按部门名称分组模板
        for (NutritionEducationTemplateVo template : publicTemplates) {
            String deptName = deptNameMap.get(template.getDeptId()); // 部门名称如"骨伤科"
            deptMap.computeIfAbsent(deptName, k -> new ArrayList<>()).add(createTemplateNode(template));
        }

        // 构建部门分类结构
        List<Map<String, Object>> publicChildren = deptMap.entrySet().stream().map(entry -> {
            Map<String, Object> deptNode = new HashMap<>();
            deptNode.put("label", entry.getKey()); // 部门名称
            deptNode.put("children", entry.getValue()); // 该部门下的模板列表
            return deptNode;
        }).collect(Collectors.toList());

        publicTemplate.put("children", publicChildren);
        result.add(publicTemplate);

        // 2. 处理 "个人模板" 部分
        Map<String, Object> personalTemplate = new HashMap<>();
        personalTemplate.put("label", "个人模板");

        // 查询个人模板（假设个人模板的deptId为null）
        List<NutritionEducationTemplateVo> personalTemplates = templateMapper.selectVoList(new LambdaQueryWrapper<NutritionEducationTemplate>().isNull(NutritionEducationTemplate::getDeptId));

        if (!personalTemplates.isEmpty()) {
            List<Map<String, Object>> personalChildren = personalTemplates.stream().map(this::createTemplateNode).collect(Collectors.toList());
            personalTemplate.put("children", personalChildren);
        }

        result.add(personalTemplate);
        resultMap.put("data", result);
        return resultMap;
    }

    // 创建模板节点的辅助方法
    private Map<String, Object> createTemplateNode(NutritionEducationTemplateVo template) {
        Map<String, Object> node = new HashMap<>();
        node.put("id", template.getId());
        node.put("label", template.getTemplateName());
        node.put("template", template.getContent());
        node.put("description", template.getDescription());
        // 可以添加其他需要的字段
        return node;
    }
}
