package com.openhis.web.document.appservice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.constant.CacheConstants;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysDictData;
import com.core.common.core.redis.RedisCache;
import com.core.common.utils.bean.BeanUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.document.domain.DocStatisticsDefinition;
import com.openhis.document.mapper.DocStatisticsDefinitionMapper;
import com.openhis.document.service.IDocStatisticsDefinitionService;
import com.openhis.web.document.appservice.IDocStatisticsDefinitionAppService;
import com.openhis.web.document.dto.DocStatisticsDefinitionDto;
import com.openhis.web.document.dto.OptionDto;
import com.openhis.web.document.mapper.DocStatisticsDefinitionAppMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文档模板 业务实现类
 */
@Slf4j
@Service
public class DocStatisticsDefinitionAppServiceImpl implements IDocStatisticsDefinitionAppService {

    @Resource
    private IDocStatisticsDefinitionService iDocStatisticsDefinitionService;
    @Resource
    private DocStatisticsDefinitionMapper docStatisticsDefinitionMapper;
    @Resource
    private DocStatisticsDefinitionAppMapper docStatisticsDefinitionAppMapper;
    @Autowired
    private RedisCache redisCache;
    @Override
    public R<?> createOrEdit(DocStatisticsDefinitionDto docStatisticsDefinitionDto) {
        if (docStatisticsDefinitionDto == null) {
            return R.fail("新增/编辑文档统计定义，参数不能为空");
        }
        if (docStatisticsDefinitionDto.getName() == null || docStatisticsDefinitionDto.getName().trim().length() == 0) {
            return R.fail("新增/编辑文档统计定义，名称不能为空");
        }
        if (docStatisticsDefinitionDto.getTypeEnum() == null) {
            return R.fail("新增/编辑文档统计定义，类型不能为空");
        }
        if (docStatisticsDefinitionDto.getCode() == null) {
            return R.fail("新增/编辑文档统计定义，代码不能为空");
        }
        DocStatisticsDefinition docStatisticsDefinition = new DocStatisticsDefinition();
        BeanUtils.copyProperties(docStatisticsDefinitionDto, docStatisticsDefinition);
        // 新增时校验代码唯一性
        if (!docStatisticsDefinitionDto.getCode().isEmpty() && docStatisticsDefinitionDto.getId() == null) {
            LambdaQueryWrapper<DocStatisticsDefinition> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DocStatisticsDefinition::getCode, docStatisticsDefinitionDto.getCode());
            docStatisticsDefinition = iDocStatisticsDefinitionService.getOne(queryWrapper);
            if (docStatisticsDefinition != null) {
                return R.fail("文档统计定义代码已存在，请更换代码");
            }
        }
        // 区分新增/编辑逻辑
        return docStatisticsDefinitionDto.getId() == null ? add(docStatisticsDefinitionDto) : update(docStatisticsDefinitionDto);
    }

    @Override

    public R<?> add(DocStatisticsDefinitionDto docStatisticsDefinitionDto) {
        String checkResult = initCheck(docStatisticsDefinitionDto);
        DocStatisticsDefinition docStatisticsDefinition = new DocStatisticsDefinition();
        if (checkResult != null) {
            return R.fail(checkResult);
        }
        if (!docStatisticsDefinitionDto.getCode().isEmpty()) {
            LambdaQueryWrapper<DocStatisticsDefinition> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DocStatisticsDefinition::getCode, docStatisticsDefinitionDto.getCode());
            Long count = iDocStatisticsDefinitionService.count(queryWrapper);
            if (count > 0) {
                return R.fail("文档统计定义代码已存在，请更换代码");
            }
        }
        // 赋值新增字段
        docStatisticsDefinition.setName(docStatisticsDefinitionDto.getName());
        docStatisticsDefinition.setCode(docStatisticsDefinitionDto.getCode());
        docStatisticsDefinition.setTypeEnum(docStatisticsDefinitionDto.getTypeEnum());
        docStatisticsDefinition.setRequired(docStatisticsDefinitionDto.getRequired());
        docStatisticsDefinition.setRemark(docStatisticsDefinitionDto.getRemark());
        docStatisticsDefinition.setIsStatistics(docStatisticsDefinitionDto.getIsStatistics());
        docStatisticsDefinition.setDisplayOrder(docStatisticsDefinitionDto.getDisplayOrder());
        docStatisticsDefinition.setUnit(docStatisticsDefinitionDto.getUnit());
        docStatisticsDefinition.setDictType(docStatisticsDefinitionDto.getDictType());
        docStatisticsDefinition.setDictName(docStatisticsDefinitionDto.getDictName());
        boolean saveResult = iDocStatisticsDefinitionService.save(docStatisticsDefinition);
        if (saveResult) {
            return R.ok("文档统计定义新增成功");
        } else {
            return R.fail("文档统计定义新增失败");
        }
    }

    @Override

    public R<?> update(DocStatisticsDefinitionDto docStatisticsDefinitionDto) {
        String checkResult = initCheck(docStatisticsDefinitionDto);
        if (checkResult != null) {
            return R.fail(checkResult);
        }
        // 校验待更新数据是否存在
        DocStatisticsDefinition existingData = iDocStatisticsDefinitionService.getById(docStatisticsDefinitionDto.getId());
        if (existingData == null) {
            return R.fail("更新文档统计定义失败，目标数据不存在");
        }
        // 赋值更新字段
        existingData.setName(docStatisticsDefinitionDto.getName());
        existingData.setCode(docStatisticsDefinitionDto.getCode());
        existingData.setTypeEnum(docStatisticsDefinitionDto.getTypeEnum());
        existingData.setRequired(docStatisticsDefinitionDto.getRequired());
        existingData.setRemark(docStatisticsDefinitionDto.getRemark());
        existingData.setIsStatistics(docStatisticsDefinitionDto.getIsStatistics());
        existingData.setDisplayOrder(docStatisticsDefinitionDto.getDisplayOrder());
        existingData.setUnit(docStatisticsDefinitionDto.getUnit());
        existingData.setDictType(docStatisticsDefinitionDto.getDictType());
        existingData.setDictName(docStatisticsDefinitionDto.getDictName());
        boolean updateResult = iDocStatisticsDefinitionService.updateById(existingData);
        if (updateResult) {
            // 同步更新选项列表
            return R.ok("文档统计定义更新成功");
        } else {
            return R.fail("文档统计定义更新失败");
        }
    }

    private String initCheck(DocStatisticsDefinitionDto docStatisticsDefinitionDto) {
        if (docStatisticsDefinitionDto == null) {
            return "新增/编辑文档统计定义，参数不能为空";
        }
        if (docStatisticsDefinitionDto.getName() == null || docStatisticsDefinitionDto.getName().trim().length() == 0) {
            return "新增/编辑文档统计定义，名称不能为空";
        }
        if (docStatisticsDefinitionDto.getTypeEnum() == null) {
            return "新增/编辑文档统计定义，类型不能为空";
        }
        if (docStatisticsDefinitionDto.getCode() == null) {
            return "新增/编辑文档统计定义，代码不能为空";
        }

        return null;
    }

    /**
     * 分页查询列表-不包含options（分页）
     *
     * @param pageNo    页码
     * @param pageSize  每页条数
     * @param searchKey 搜索关键词
     * @param request   请求对象
     * @return 分页结果
     */
    @Override
    public R<?> getPageList(Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request) {
//        Map<String, Object>  keyMap =  redisCache.getAllDictDataWithKeys(CacheConstants.SYS_DICT_KEY);
        // 构建查询条件（支持多字段搜索）
        QueryWrapper<DocStatisticsDefinition> queryWrapper = HisQueryUtils.buildQueryWrapper(
                null, searchKey, new HashSet<>(Arrays.asList("name", "code")), request);
        // 按记录时间倒序（最新记录在前）
        queryWrapper.lambda().orderByDesc(DocStatisticsDefinition::getDisplayOrder);
        Page<DocStatisticsDefinitionDto> recordPage = HisPageUtils.selectPage(
                docStatisticsDefinitionMapper, queryWrapper, pageNo, pageSize, DocStatisticsDefinitionDto.class);
        // 转换为分页结果
        return R.ok(recordPage, "文档统计定义列表获取成功");
    }

    /**
     * 获取文档统计定义列表（不分页,不包含options）
     *
     * @param isStatistics 是否统计
     * @return 文档统计定义列表
     */
    @Override
    public List<DocStatisticsDefinitionDto> getList(Integer isStatistics) {
        Map<String, Object>  keyMap =  redisCache.getAllDictDataWithKeys(CacheConstants.SYS_DICT_KEY);
        LambdaQueryWrapper<DocStatisticsDefinition> queryWrapper = new LambdaQueryWrapper<>();
        if (isStatistics != null) {
            queryWrapper.eq(DocStatisticsDefinition::getIsStatistics, isStatistics);
        }
        List<DocStatisticsDefinition> dataList = iDocStatisticsDefinitionService.list(queryWrapper);
        List<DocStatisticsDefinitionDto> resultList = new ArrayList<>();
        for (DocStatisticsDefinition data : dataList) {
            DocStatisticsDefinitionDto dto = new DocStatisticsDefinitionDto();
            BeanUtils.copyProperties(data, dto);
            resultList.add(dto);
        }
        return resultList;
    }
    @Override
    public List<DocStatisticsDefinitionDto> getListWithOptionList(Integer isStatistics) {
        //从redis中获取所有字典数据
        Map<String, Object>  keyMap =  redisCache.getAllDictDataWithKeys(CacheConstants.SYS_DICT_KEY);
        LambdaQueryWrapper<DocStatisticsDefinition> queryWrapper = new LambdaQueryWrapper<>();
        if (isStatistics != null) {
            queryWrapper.eq(DocStatisticsDefinition::getIsStatistics, isStatistics);
        }
        List<DocStatisticsDefinition> dataList = iDocStatisticsDefinitionService.list(queryWrapper);
        List<DocStatisticsDefinitionDto> resultList = new ArrayList<>();
        for (DocStatisticsDefinition data : dataList) {
            DocStatisticsDefinitionDto dto = new DocStatisticsDefinitionDto();
            BeanUtils.copyProperties(data, dto);
            if(keyMap.containsKey(CacheConstants.SYS_DICT_KEY+data.getDictType()))
            {
                List<SysDictData> dictData = (List<SysDictData>) keyMap.get(CacheConstants.SYS_DICT_KEY+data.getDictType());
                dto.setOptionList(dictData);
            }
            resultList.add(dto);
        }
        return resultList;
    }
    /**
     * 获取文档统计定义选项列表并按指定格式返回
     *
     * @return 封装了处理结果的响应对象
     */
    @Override
    public R<?> getOptionList() {
        // 1. 从数据库查询所有选项数据
        List<OptionDto> optionDtoList = docStatisticsDefinitionAppMapper.getOptionList(null, null, null);

        // 2. 处理空数据场景
        if (optionDtoList == null || optionDtoList.isEmpty()) {
            return R.ok(new ArrayList<>(), "文档统计定义选项列表获取成功，查询结果为空");
        }

        // 3. 按code字段分组
        Map<String, List<OptionDto>> groupCodeMap = optionDtoList.stream()
                .collect(Collectors.groupingBy(OptionDto::getCode));

        // 4. 准备最终返回的结果列表
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5. 遍历每个code分组
        for (Map.Entry<String, List<OptionDto>> entry : groupCodeMap.entrySet()) {
            String code = entry.getKey();
            List<OptionDto> optionDtos = entry.getValue();

            Map<String, Object> resultMap = new HashMap<>();

            // 设置名称和code
            if (!optionDtos.isEmpty()) {
                resultMap.put("name", optionDtos.get(0).getName());
            }
            resultMap.put("code", code);

            // 动态生成列表键名
            String listKey = code + "List";

            // 检查分组中是否存在任何optionId为null的元素
            boolean hasNullOptionId = optionDtos.stream()
                    .anyMatch(dto -> dto.getOptionId() == null);

            // 如果存在null的optionId，返回空集合；否则正常处理
            List<Map<String, Object>> optionList;
            if (hasNullOptionId) {
                optionList = new ArrayList<>(); // 返回空集合
            } else {
                // 正常转换有效元素
                optionList = optionDtos.stream()
                        .map(dto -> {
                            Map<String, Object> optionMap = new HashMap<>();
                            optionMap.put("id", dto.getOptionId().toString());
                            optionMap.put("option", dto.getOption());
                            return optionMap;
                        })
                        .collect(Collectors.toList());
            }

            // 添加列表到结果中（即使是空集合）
            resultMap.put(listKey, optionList);
            resultList.add(resultMap);
        }

        return R.ok(resultList, "文档统计定义选项列表获取成功");
    }


    @Override
    public R<?> deleteDocStatisticsDefinition(Long id) {
        if (id == null) {
            return R.fail("删除文档统计定义，参数ID不能为空");
        }
        boolean deleteResult = iDocStatisticsDefinitionService.removeById(id);
        if (deleteResult) {
            return R.ok("文档统计定义删除成功");
        } else {
            return R.fail("文档统计定义删除失败");
        }
    }



}