package com.yhy.module.core.service.quota.impl;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yhy.module.core.enums.ErrorCodeConstants.*;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldLabelSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldLabelDO;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogItemMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaRateFieldLabelMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaRateFieldMapper;
import com.yhy.module.core.service.quota.QuotaRateFieldLabelService;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 定额费率字段标签字典 Service 实现
 *
 * @author yhy
 */
@Service
@RequiredArgsConstructor
public class QuotaRateFieldLabelServiceImpl implements QuotaRateFieldLabelService {

    private final QuotaRateFieldLabelMapper fieldLabelMapper;
    private final QuotaRateFieldMapper rateFieldMapper;
    private final QuotaCatalogItemMapper catalogItemMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createFieldLabel(QuotaRateFieldLabelSaveReqVO createReqVO) {
        // 1. 验证模式节点存在
        validateRateModeNode(createReqVO.getCatalogItemId());

        // 2. 验证标签名称唯一性
        QuotaRateFieldLabelDO existLabel = fieldLabelMapper.selectByCatalogItemIdAndName(
                createReqVO.getCatalogItemId(), createReqVO.getLabelName());
        if (existLabel != null) {
            throw exception(QUOTA_RATE_FIELD_LABEL_NAME_DUPLICATE);
        }

        // 3. 设置排序值
        Integer sortOrder = createReqVO.getSortOrder();
        if (sortOrder == null) {
            sortOrder = fieldLabelMapper.selectMaxSortOrder(createReqVO.getCatalogItemId()) + 1;
        }

        // 4. 创建标签
        QuotaRateFieldLabelDO label = BeanUtils.toBean(createReqVO, QuotaRateFieldLabelDO.class);
        label.setSortOrder(sortOrder);
        fieldLabelMapper.insert(label);
        return label.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFieldLabel(QuotaRateFieldLabelSaveReqVO updateReqVO) {
        // 1. 验证存在
        QuotaRateFieldLabelDO existLabel = validateFieldLabelExists(updateReqVO.getId());

        // 2. 验证标签名称唯一性（排除自己）
        QuotaRateFieldLabelDO duplicateLabel = fieldLabelMapper.selectByCatalogItemIdAndName(
                existLabel.getCatalogItemId(), updateReqVO.getLabelName());
        if (duplicateLabel != null && !Objects.equals(duplicateLabel.getId(), updateReqVO.getId())) {
            throw exception(QUOTA_RATE_FIELD_LABEL_NAME_DUPLICATE);
        }

        // 3. 更新
        QuotaRateFieldLabelDO updateObj = BeanUtils.toBean(updateReqVO, QuotaRateFieldLabelDO.class);
        fieldLabelMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFieldLabel(Long id) {
        // 1. 验证存在
        validateFieldLabelExists(id);

        // 2. 验证是否被引用
        Long count = rateFieldMapper.selectCount("field_label_id", id);
        if (count > 0) {
            throw exception(QUOTA_RATE_FIELD_LABEL_IN_USE);
        }

        // 3. 删除
        fieldLabelMapper.deleteById(id);
    }

    @Override
    public QuotaRateFieldLabelDO getFieldLabel(Long id) {
        return fieldLabelMapper.selectById(id);
    }

    @Override
    public List<QuotaRateFieldLabelRespVO> getFieldLabelList(Long catalogItemId) {
        List<QuotaRateFieldLabelDO> labels = fieldLabelMapper.selectListByCatalogItemId(catalogItemId);
        return labels.stream()
                .map(label -> BeanUtils.toBean(label, QuotaRateFieldLabelRespVO.class))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void swapSort(Long labelId1, Long labelId2) {
        // 1. 查询两个标签
        QuotaRateFieldLabelDO label1 = validateFieldLabelExists(labelId1);
        QuotaRateFieldLabelDO label2 = validateFieldLabelExists(labelId2);

        // 2. 验证同一模式节点
        if (!Objects.equals(label1.getCatalogItemId(), label2.getCatalogItemId())) {
            throw exception(QUOTA_RATE_FIELD_LABEL_NOT_SAME_MODE);
        }

        // 3. 交换排序值
        Integer temp = label1.getSortOrder();
        fieldLabelMapper.updateSortOrder(labelId1, label2.getSortOrder());
        fieldLabelMapper.updateSortOrder(labelId2, temp);
    }

    @Override
    public QuotaRateFieldLabelDO validateFieldLabelExists(Long id) {
        QuotaRateFieldLabelDO label = fieldLabelMapper.selectById(id);
        if (label == null) {
            throw exception(QUOTA_RATE_FIELD_LABEL_NOT_EXISTS);
        }
        return label;
    }

    // ==================== 私有方法 ====================

    /**
     * 验证模式节点
     */
    private void validateRateModeNode(Long catalogItemId) {
        QuotaCatalogItemDO catalogItem = catalogItemMapper.selectById(catalogItemId);
        if (catalogItem == null) {
            throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
        }

        // 验证是否为 rate_mode 节点
        if (!"rate_mode".equals(catalogItem.getNodeType())) {
            throw exception(QUOTA_RATE_ITEM_CATALOG_NOT_RATE_MODE);
        }
    }
}
