package com.sckw.system.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Maps;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.base.BaseModel;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.result.PageDataResult;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.system.model.SysDict;
import com.sckw.system.model.SysDictType;
import com.sckw.system.model.vo.req.SysDictReqVo;
import com.sckw.system.model.vo.res.SysDictResp;
import com.sckw.system.repository.SysDictRepository;
import com.sckw.system.repository.SysDictTypeRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 字典业务服务层(中间层) - MyBatis-Plus 版本
 * 在 SysDictService 基础上添加业务逻辑
 * @author system
 * @date 2024
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictFlexBusinessService {

    private final SysDictRepository sysDictRepository;
    private final SysDictTypeRepository sysDictTypeRepository;

    /**
     * 新增字典
     */
    public Boolean insert(SysDictReqVo.SysDictInfo entity) {
        log.info("新增字典,请求参数：{}", JSON.toJSONString(entity));
        
        // 业务校验：检查是否存在相同的字典项
        SysDict existDict = sysDictRepository.selectUniqueDict(
            entity.getDictId(),
            entity.getLabel(),
            entity.getType(),
            entity.getParentId()
        );
        if (existDict != null) {
           // return Boolean.FALSE;
            if (StringUtils.equals(entity.getLabel(), existDict.getLabel())){
                log.error("字典名称已存在，请勿重复添加");
                throw new BusinessException("字典名称已存在，请勿重复添加");
            }
            if (StringUtils.equals(entity.getValue(), existDict.getValue())) {
                log.error("字典项值已存在，请勿重复添加");
                throw new BusinessException("字典项值已存在，请勿重复添加");
            }

        }
        
        // 设置创建信息
        Long userId = LoginUserHolder.getUserId();
        long id = new IdWorker(1L).nextId();
        SysDict sysDict = getSysDict(entity, id, userId);
        Boolean result = sysDictRepository.save(sysDict);
        
        // 删除以"dictInfo:"开头的缓存
        if (result) {
            log.info("新增字典成功删除以\"dictInfo:\"开头的缓存");
            RedissonUtils.deleteBactch("dictInfo:*");
        }
        
        return result;
    }

    @NotNull
    private static SysDict getSysDict(SysDictReqVo.SysDictInfo entity, long id, Long userId) {
        SysDict sysDict = new SysDict();
        sysDict.setId(id);
        sysDict.setDictId(entity.getDictId());
        sysDict.setValue(entity.getValue());
        sysDict.setLabel(entity.getLabel());
        sysDict.setType(entity.getType());
        sysDict.setDescription(entity.getDescription());
        sysDict.setSort(entity.getSort());
        sysDict.setParentId(entity.getParentId());
        sysDict.setRemark(entity.getRemark());
        sysDict.setStatus(0);
        sysDict.setCreateBy(userId);
        sysDict.setUpdateBy(userId);
        sysDict.setCreateTime(new Date());
        sysDict.setUpdateTime(new Date());
        sysDict.setDelFlag(0);
        return sysDict;
    }


    /**
     * 逻辑删除
     */
    public int logicDeleteById(Long id) {
        log.info("逻辑删除字典，ID：{}", id);
        return sysDictRepository.logicDeleteById(id);
    }

    /**
     * 更新字典
     */
    public Boolean update(SysDictReqVo.SysDictInfo entity) {
        log.info("更新字典，ID：{}", entity.getId());
        
        // 业务校验：检查是否存在相同的字典项（排除自己）
        SysDict existDict = sysDictRepository.selectById(entity.getId());
        if (Objects.isNull(existDict)) {
            log.error("字典项不存在");
            return Boolean.FALSE;
        }

        // 设置更新信息
        Long userId = LoginUserHolder.getUserId();
        SysDict sysDict = new SysDict();
        sysDict.setDictId(entity.getDictId());
        sysDict.setValue(entity.getValue());
        sysDict.setLabel(entity.getLabel());
        sysDict.setType(entity.getType());
        sysDict.setDescription(entity.getDescription());
        sysDict.setParentId(StringUtils.isBlank(entity.getParentId()) ? "0" : entity.getParentId());
        sysDict.setId(existDict.getId());
        sysDict.setSort(entity.getSort());
        sysDict.setRemark(entity.getRemark());
        sysDict.setUpdateBy(userId);
        sysDict.setUpdateTime(new Date());

        Boolean update = sysDictRepository.update(sysDict);
        // 删除以"dictInfo:"开头的缓存
        if (update) {
            log.info("更新字典成功删除以\"dictInfo:\"开头的缓存");
            RedissonUtils.deleteBactch("dictInfo:*");
        }
        return update;
    }







    /**
     * 分页查询字典
     */
    public PageDataResult<SysDictResp> selectPage(SysDictReqVo reqVo) {
        log.info("分页查询字典,请求参数：{}", JSON.toJSONString(reqVo));
        int pageNum = reqVo.getPageNum();
        int pageSize = reqVo.getPageSize();

        IPage<SysDict> page = sysDictRepository.selectPage(pageNum, pageSize, reqVo.getType(), reqVo.getParentId(), reqVo.getLabel());
        
        List<SysDict> records = page.getRecords();
        if (records == null || records.isEmpty()) {
            return PageDataResult.empty(reqVo.getPageNum(), reqVo.getPageSize());
        }

        //根据商品类型查询商品类型名称
        Set<String> types = records.stream()
                .map(SysDict::getType)
                .collect(Collectors.toSet());
        //查询商品类型名称
        List<SysDictType> typeDicts = sysDictTypeRepository.queryByTypes(types);
        Map<String, SysDictType> typeAndDictMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(typeDicts)){
            typeAndDictMap = typeDicts.stream()
                    .collect(Collectors.toMap(SysDictType::getType, Function.identity(), (k1, k2) -> k1));
        }

        Set<String> parentIds = records.stream()
                .map(SysDict::getParentId)
                .collect(Collectors.toSet());
        //查询父字典
        List<SysDict> parentDicts = sysDictRepository.queryByIds(parentIds);
        Map<Long, SysDict> idAndParentDictMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(parentDicts)){
            idAndParentDictMap = parentDicts.stream()
                    .collect(Collectors.toMap(BaseModel::getId, Function.identity(), (k1, k2) -> k1));
        }

        List<SysDictResp> sysDictResps = convertToRespList(records,idAndParentDictMap,typeAndDictMap);
        return PageDataResult.of(page, sysDictResps);
    }

    /**
     * 统计字典数量
     */
    public long count(String type) {
        log.info("统计字典数量，type：{}", type);
        return sysDictRepository.count(type);
    }

    /**
     * 查询上级字典下拉列表（支持输入搜索）
     * 用于字典项选择父级字典
     * @return 字典响应列表
     */
    public List<SysDictResp> searchParentDictForSelect(SysDictReqVo reqVo) {
        log.info("查询上级字典下拉列表，请求参数：{}", JSON.toJSONString(reqVo));
        List<SysDict> list = sysDictRepository.searchParentDictForSelect(reqVo.getKeyword());
        return convertToRespList(list,new HashMap<>(),new HashMap<>());
    }

    /**
     * 快捷更改字典状态（启用/停用）
     * @param id 字典ID
     * @param status 状态（0正常/1锁定）
     * @return 影响行数
     */
    public Boolean updateStatus(Long id, Integer status) {
        log.info("快捷更改字典状态，ID：{}, 新状态：{}", id, status);
        
        // 业务校验
        if (id == null) {
            log.error("字典ID不能为空");
            return Boolean.FALSE;
        }
        if (status == null || (status != 0 && status != 1)) {
            log.error("状态值无效，只能为0（正常）或1（锁定）");
            return Boolean.FALSE;
        }
        
        // 检查字典是否存在
        SysDict existDict = sysDictRepository.selectById(id);
        if (Objects.isNull(existDict)) {
            log.error("字典项不存在，ID：{}", id);
            return Boolean.FALSE;
        }
        
        // 更新状态
        Boolean update = sysDictRepository.updateStatus(id, status);
        if (update) {
            log.info("更新字典状态成功,删除缓存，字典id：{}", id);
            RedissonUtils.deleteBactch("dictInfo:*");
        }
        return update;
    }

    /**
     * 将实体转换为响应对象
     */
    private SysDictResp convertToResp(SysDict entity,Map<Long, SysDict> idAndParentDictMap,Map<String, SysDictType> typeAndDictMap) {
        if (entity == null) {
            return null;
        }
        SysDictResp resp = new SysDictResp();
        BeanUtils.copyProperties(entity, resp);
        resp.setStatusName(Objects.equals(entity.getStatus(), 0) ? " 正常" : "锁定");
        SysDictType sysDictType = typeAndDictMap.getOrDefault(entity.getType(), new SysDictType());
        resp.setTypeName(sysDictType.getName());
        // 设置父级字典名称
        Long parentId = Optional.ofNullable(entity.getParentId()).filter(StringUtils::isNotBlank).map(Long::parseLong).orElse(null);
        SysDict parentDict = idAndParentDictMap.getOrDefault(parentId, new SysDict());
        resp.setParentName(parentDict.getLabel());
        return resp;
    }

    /**
     * 将实体列表转换为响应对象列表
     */
    private List<SysDictResp> convertToRespList(List<SysDict> entities,Map<Long, SysDict> idAndParentDictMap,Map<String, SysDictType> typeAndDictMap ) {
        if (entities == null || entities.isEmpty()) {
            return List.of();
        }
        return entities.stream()
                .map(x->convertToResp(x,idAndParentDictMap,typeAndDictMap))
                .collect(Collectors.toList());
    }
}
