package com.cool.store.dao.dict;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.cool.store.entity.dict.SysDictColumnDO;
import com.cool.store.entity.dict.SysDictTableDO;
import com.cool.store.mapper.dict.SysDictColumnMapper;
import com.cool.store.request.dict.DictColumnQueryRequest;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.dict.DictColumnSimpleVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * <p>
 * 字典项DAO
 * </p>
 *
 * @author wangff
 * @since 2025/9/26
 */
@Repository
@RequiredArgsConstructor
public class SysDictColumnDAO {
    private final SysDictColumnMapper sysDictColumnMapper;
    private final SysDictTableDAO sysDictTableDAO;


    public List<SysDictColumnDO> getList(DictColumnQueryRequest dto) {
        return sysDictColumnMapper.selectList(dto);
    }

    /**
     * 根据id查询
     *
     * @param id id
     * @return 字典项信息表
     */
    public SysDictColumnDO getById(Long id) {
        return sysDictColumnMapper.selectById(id);
    }

    public List<SysDictColumnDO> getByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return sysDictColumnMapper.selectByIds(ids);
    }

    /**
     * 根据字典表id查询字典项数量
     *
     * @param tableIds 字典表id列表
     * @return <字典表id, 字典项数量>
     */
    public Map<Long, Integer> getColumnNumMapByTableIds(List<Long> tableIds) {
        if (CollectionUtil.isEmpty(tableIds)) {
            return Collections.emptyMap();
        }
        List<Map<String, Object>> mapList = sysDictColumnMapper.selectColumnNumByTableIds(tableIds);
        return CollStreamUtil.toMap(mapList, v -> MapUtils.getLong(v, "dict_table_id"), v -> MapUtils.getInteger(v, "num"));
    }

    /**
     * 过滤存在启用字典项的字典分组id
     * @param groupIds 字典分组id列表
     * @return 字典分组id列表
     */
    public Set<Long> filterEnableColumnByGroupIds(List<Long> groupIds) {
        if (CollectionUtil.isEmpty(groupIds)) {
            return Collections.emptySet();
        }
        List<Map<String, Object>> list = sysDictColumnMapper.filterEnableColumnByGroupIds(groupIds);
        return CollStreamUtil.toSet(list, v -> MapUtils.getLong(v, "dict_group_id"));
    }

    /**
     * 过滤存在启用字典项的字典表id
     * @param tableIds 字典表id列表
     * @return 字典表id列表
     */
    public Set<Long> filterEnableColumnByTableIds(List<Long> tableIds) {
        if (CollectionUtil.isEmpty(tableIds)) {
            return Collections.emptySet();
        }
        List<Map<String, Object>> list = sysDictColumnMapper.filterEnableColumnByTableIds(tableIds);
        return CollStreamUtil.toSet(list, v -> MapUtils.getLong(v, "dict_table_id"));
    }

    /**
     * 根据分组id删除
     * @param groupIds 分组id列表
     */
    public void deleteByGroupIds(List<Long> groupIds) {
        if (CollectionUtil.isEmpty(groupIds)) {
            return;
        }
        sysDictColumnMapper.deleteByGroupIds(groupIds);
    }

    /**
     * 根据字典表id删除
     * @param tableIds 字典表id列表
     */
    public void deleteByTableIds(List<Long> tableIds) {
        if (CollectionUtil.isEmpty(tableIds)) {
            return;
        }
        sysDictColumnMapper.deleteByTableIds(tableIds);
    }

    /**
     * 根据字典列编码查询已启用字典项信息
     * @param columnCode 字典列编码
     * @return 字典项信息
     */
    public SysDictColumnDO getOpenColumnByCode(String columnCode) {
        return sysDictColumnMapper.selectOpenColumnByCode(columnCode);
    }

    /**
     * 根据字典列编码查询已启用字典名
     * @param columnCode 字典列编码
     * @return 字典名
     */
    public String getNameByCode(String columnCode) {
        SysDictColumnDO sysDictColumnDO = sysDictColumnMapper.selectOpenColumnByCode(columnCode);
        if (Objects.nonNull(sysDictColumnDO)) {
            return sysDictColumnDO.getColumnName();
        }
        return "";
    }

    /**
     * 根据字典列编码查询已启用字典项名称映射
     * @param columnCodes 字典列编码列表
     * @return <字典列编码, 字典项名称>
     */
    public Map<String, String> getNameMapByCodes(List<String> columnCodes) {
        if (CollectionUtils.isEmpty(columnCodes)) {
            return Collections.emptyMap();
        }
        List<SysDictColumnDO> list = sysDictColumnMapper.selectOpenColumnByCodes(columnCodes);
        return CollStreamUtil.toMap(list, SysDictColumnDO::getColumnCode, SysDictColumnDO::getColumnName);
    }

    /**
     * 根据字典列编码查询字典项名称映射包含已删除字典项
     * @param columnCodes 字典列编码列表
     * @return <字典列编码, 字典项名称>
     */
    public Map<String, String> getNameMapIncludeDeleted(List<String> columnCodes) {
        if (CollectionUtils.isEmpty(columnCodes)) {
            return Collections.emptyMap();
        }
        List<SysDictColumnDO> list = sysDictColumnMapper.selectColumnByCodesIncludeDeleted(columnCodes);
        return CollStreamUtil.toMap(list, SysDictColumnDO::getColumnCode, SysDictColumnDO::getColumnName);
    }

    /**
     * 根据字典表编码查询启用状态的字典项
     * @param tableCodes 字典表编码列表
     * @return 字典项列表
     */
    public List<DictColumnSimpleVO> getOpenColumnListByTableCode(List<String> tableCodes) {
        List<SysDictTableDO> tableList = sysDictTableDAO.getOpenTableListByTableCodes(tableCodes);
        if (CollectionUtils.isEmpty(tableList)) {
            return Collections.emptyList();
        }
        List<Long> tableIds = CollStreamUtil.toList(tableList, SysDictTableDO::getId);
        List<SysDictColumnDO> columnList = sysDictColumnMapper.selectOpenColumnListByTableIds(tableIds);
        Map<Long, String> tableCodeMap = CollStreamUtil.toMap(tableList, SysDictTableDO::getId, SysDictTableDO::getTableCode);
        return CollStreamUtil.toList(columnList, v -> DictColumnSimpleVO.of(v, tableCodeMap.get(v.getDictTableId())));
    }

    /**
     * 获取字典项关联字典项列表映射
     * @param columnIds 字典项id列表
     * @return 关联字典项分组
     */
    public Map<Long, List<DictColumnSimpleVO>> getRelationColumnMap(List<Long> columnIds) {
        if (CollectionUtils.isEmpty(columnIds)) {
            return Collections.emptyMap();
        }
        List<Map<String, Object>> list = sysDictColumnMapper.getRelationColumnIds(columnIds);
        Set<Long> relationIds = CollStreamUtil.toSet(list, v -> MapUtils.getLong(v, "relation_id"));
        List<SysDictColumnDO> columnList = getByIds(new ArrayList<>(relationIds));
        Map<Long, SysDictColumnDO> columnMap = CollStreamUtil.toMap(columnList, SysDictColumnDO::getId, v -> v);
        return CollStreamUtil.groupBy(list,
                v -> MapUtils.getLong(v, "column_id"),
                Collector.of(
                        ArrayList::new,
                        (acc, row) -> {
                            SysDictColumnDO col = columnMap.get(MapUtils.getLong(row, "relation_id"));
                            if (col != null) {
                                acc.add(DictColumnSimpleVO.of(col, null));
                            }
                        },
                        (left, right) -> {
                            left.addAll(right);
                            return left;
                        }
                ));

    }
}
