package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.dto.dict.CreateDictDTO;
import com.lesingle.creation.dto.dict.UpdateDictDTO;
import com.lesingle.creation.entity.Dict;
import com.lesingle.creation.entity.DictItem;
import com.lesingle.creation.mapper.DictMapper;
import com.lesingle.creation.mapper.DictItemMapper;
import com.lesingle.creation.service.DictService;
import com.lesingle.creation.vo.dict.DictDetailVO;
import com.lesingle.creation.vo.dict.DictItemVO;
import com.lesingle.creation.vo.dict.DictListVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {

    private final DictMapper dictMapper;
    private final DictItemMapper dictItemMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DictDetailVO create(CreateDictDTO dto, Long tenantId, Long operatorId) {
        log.info("开始创建字典，字典编码：{}", dto.getCode());

        // 检查字典编码是否已存在
        Dict existingDict = dictMapper.selectByCode(tenantId, dto.getCode());
        if (existingDict != null) {
            throw new BusinessException("字典编码已存在");
        }

        // 创建字典
        Dict dict = new Dict();
        dict.setTenantId(tenantId);
        dict.setName(dto.getName());
        dict.setCode(dto.getCode());
        dict.setDescription(dto.getDescription());
        dict.setValidState(1);
        dict.setCreateBy(String.valueOf(operatorId));

        dictMapper.insert(dict);
        log.info("字典创建成功，字典 ID: {}", dict.getId());

        // 如果提供了字典项，创建字典项
        if (!CollectionUtils.isEmpty(dto.getItems())) {
            List<DictItem> dictItems = dto.getItems().stream()
                    .map(itemDTO -> {
                        DictItem item = new DictItem();
                        item.setDictId(dict.getId());
                        item.setLabel(itemDTO.getLabel());
                        item.setValue(itemDTO.getValue());
                        item.setSort(itemDTO.getSort() != null ? itemDTO.getSort() : 0);
                        item.setValidState(1);
                        return item;
                    })
                    .collect(Collectors.toList());
            dictItemMapper.insertBatch(dictItems);
            log.info("字典项创建成功，字典项数量：{}", dto.getItems().size());
        }

        return convertToDetailVO(dict);
    }

    @Override
    public Page<DictListVO> pageList(Long tenantId, int page, int pageSize) {
        log.info("分页查询字典列表，租户 ID: {}, 页码：{}, 每页大小：{}", tenantId, page, pageSize);

        Page<Dict> dictPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dict> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Dict::getTenantId, tenantId)
                .eq(Dict::getValidState, 1)
                .orderByDesc(Dict::getCreateTime);

        Page<Dict> resultPage = dictMapper.selectPage(dictPage, wrapper);

        // 转换为 VO
        List<DictListVO> voList = resultPage.getRecords().stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList());

        Page<DictListVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(voList);

        return voPage;
    }

    @Override
    public DictDetailVO getByCode(String code, Long tenantId) {
        log.info("根据编码查询字典，编码：{}, 租户 ID: {}", code, tenantId);

        Dict dict = dictMapper.selectByCode(tenantId, code);
        if (dict == null) {
            throw new BusinessException("字典不存在");
        }

        return convertToDetailVO(dict);
    }

    @Override
    public DictDetailVO detail(Long id, Long tenantId) {
        log.info("查询字典详情，字典 ID: {}", id);

        Dict dict = dictMapper.selectById(id);
        if (dict == null) {
            throw new BusinessException("字典不存在");
        }

        return convertToDetailVO(dict);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DictDetailVO update(Long id, UpdateDictDTO dto, Long tenantId) {
        log.info("更新字典，字典 ID: {}", id);

        Dict existingDict = dictMapper.selectById(id);
        if (existingDict == null) {
            throw new BusinessException("字典不存在");
        }

        // 如果更新了 code，检查是否冲突
        if (StringUtils.hasText(dto.getCode())) {
            Dict conflictDict = dictMapper.selectByCodeExclude(tenantId, dto.getCode(), id);
            if (conflictDict != null) {
                throw new BusinessException("字典编码已存在");
            }
        }

        // 更新字典信息
        Dict dict = new Dict();
        dict.setId(id);
        dict.setName(dto.getName());
        dict.setCode(dto.getCode());
        dict.setDescription(dto.getDescription());

        dictMapper.updateById(dict);
        log.info("字典更新成功，字典 ID: {}", id);

        // 如果提供了字典项，更新字典项
        if (dto.getItems() != null) {
            // 先删除现有字典项
            LambdaQueryWrapper<DictItem> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DictItem::getDictId, id);
            dictItemMapper.delete(wrapper);
            log.info("已删除字典原有字典项");

            // 创建新的字典项
            if (!dto.getItems().isEmpty()) {
                List<DictItem> dictItems = dto.getItems().stream()
                        .map(itemDTO -> {
                            DictItem item = new DictItem();
                            item.setDictId(id);
                            if (itemDTO.getId() != null) {
                                item.setId(itemDTO.getId());
                            }
                            item.setLabel(itemDTO.getLabel());
                            item.setValue(itemDTO.getValue());
                            item.setSort(itemDTO.getSort() != null ? itemDTO.getSort() : 0);
                            item.setValidState(1);
                            return item;
                        })
                        .collect(Collectors.toList());
                dictItemMapper.insertBatch(dictItems);
                log.info("字典新字典项创建成功，字典项数量：{}", dto.getItems().size());
            }
        }

        return convertToDetailVO(dictMapper.selectById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, Long tenantId) {
        log.info("删除字典，字典 ID: {}", id);

        Dict dict = dictMapper.selectById(id);
        if (dict == null) {
            throw new BusinessException("字典不存在");
        }

        // 删除字典项
        LambdaQueryWrapper<DictItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DictItem::getDictId, id);
        dictItemMapper.delete(wrapper);
        log.info("字典项删除成功");

        // 删除字典（逻辑删除）
        dictMapper.deleteById(id);
        log.info("字典删除成功，字典 ID: {}", id);
    }

    /**
     * 转换为详情 VO
     */
    private DictDetailVO convertToDetailVO(Dict dict) {
        DictDetailVO vo = new DictDetailVO();
        vo.setId(dict.getId());
        vo.setTenantId(dict.getTenantId());
        vo.setName(dict.getName());
        vo.setCode(dict.getCode());
        vo.setDescription(dict.getDescription());
        vo.setValidState(dict.getValidState());
        vo.setCreateBy(dict.getCreateBy());
        vo.setCreateTime(dict.getCreateTime());
        vo.setUpdateBy(dict.getUpdateBy());
        vo.setUpdateTime(dict.getUpdateTime());

        // 获取字典项
        List<DictItem> items = dictItemMapper.selectByDictId(dict.getId());
        if (!CollectionUtils.isEmpty(items)) {
            List<DictItemVO> itemVOs = items.stream()
                    .sorted(Comparator.comparingInt(DictItem::getSort))
                    .map(this::convertItemToVO)
                    .collect(Collectors.toList());
            vo.setItems(itemVOs);
        }

        return vo;
    }

    /**
     * 转换为列表 VO
     */
    private DictListVO convertToListVO(Dict dict) {
        DictListVO vo = new DictListVO();
        vo.setId(dict.getId());
        vo.setTenantId(dict.getTenantId());
        vo.setName(dict.getName());
        vo.setCode(dict.getCode());
        vo.setDescription(dict.getDescription());
        vo.setValidState(dict.getValidState());
        vo.setCreateTime(dict.getCreateTime());
        return vo;
    }

    /**
     * 转换为字典项 VO
     */
    private DictItemVO convertItemToVO(DictItem item) {
        DictItemVO vo = new DictItemVO();
        vo.setId(item.getId());
        vo.setDictId(item.getDictId());
        vo.setLabel(item.getLabel());
        vo.setValue(item.getValue());
        vo.setSort(item.getSort());
        vo.setValidState(item.getValidState());
        return vo;
    }
}
