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

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.infoprice.vo.InfoPriceResourcePageReqVO;
import com.yhy.module.core.controller.admin.infoprice.vo.InfoPriceResourceRespVO;
import com.yhy.module.core.controller.admin.infoprice.vo.InfoPriceResourceSaveReqVO;
import com.yhy.module.core.dal.dataobject.infoprice.InfoPriceCategoryTreeDO;
import com.yhy.module.core.dal.dataobject.infoprice.InfoPriceResourceDO;
import com.yhy.module.core.dal.mysql.infoprice.InfoPriceCategoryTreeMapper;
import com.yhy.module.core.dal.mysql.infoprice.InfoPriceResourceMapper;
import com.yhy.module.core.dal.mysql.infoprice.InfoPriceResourcePriceMapper;
import com.yhy.module.core.enums.infoprice.InfoPriceCategoryNodeTypeEnum;
import com.yhy.module.core.service.infoprice.InfoPriceResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;

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

/**
 * 信息价工料机信息 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class InfoPriceResourceServiceImpl implements InfoPriceResourceService {

    @Resource
    private InfoPriceResourceMapper resourceMapper;

    @Resource
    private InfoPriceCategoryTreeMapper categoryTreeMapper;

    @Resource
    private InfoPriceResourcePriceMapper infoPriceResourcePriceMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createResource(InfoPriceResourceSaveReqVO createReqVO) {
        // 1. 校验分类树节点存在且为内容节点
        validateContentNode(createReqVO.getCategoryTreeId());

        // 2. 校验编码唯一性
        validateCodeUnique(createReqVO.getCategoryTreeId(), createReqVO.getCode(), null);

        // 3. 插入
        InfoPriceResourceDO resource = BeanUtils.toBean(createReqVO, InfoPriceResourceDO.class);
        
        // 计算排序
        List<InfoPriceResourceDO> siblings = resourceMapper.selectListByCategoryTreeId(createReqVO.getCategoryTreeId());
        resource.setSortOrder(siblings.size() + 1);

        resourceMapper.insert(resource);
        return resource.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResource(InfoPriceResourceSaveReqVO updateReqVO) {
        // 1. 校验存在
        InfoPriceResourceDO resource = validateResourceExists(updateReqVO.getId());

        // 2. 校验编码唯一性
        validateCodeUnique(resource.getCategoryTreeId(), updateReqVO.getCode(), updateReqVO.getId());

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteResource(Long id) {
        // 1. 校验存在
        validateResourceExists(id);

        // 2. 校验是否有价格历史
        long priceCount = infoPriceResourcePriceMapper.selectCount("resource_id", id);
        if (priceCount > 0) {
            throw exception(INFO_PRICE_RESOURCE_HAS_PRICES);
        }

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

    @Override
    public InfoPriceResourceRespVO getResource(Long id) {
        InfoPriceResourceDO resource = resourceMapper.selectById(id);
        return BeanUtils.toBean(resource, InfoPriceResourceRespVO.class);
    }

    @Override
    public PageResult<InfoPriceResourceRespVO> getResourcePage(InfoPriceResourcePageReqVO pageReqVO) {
        PageResult<InfoPriceResourceDO> pageResult = resourceMapper.selectPage(pageReqVO);
        return BeanUtils.toBean(pageResult, InfoPriceResourceRespVO.class);
    }

    @Override
    public List<InfoPriceResourceRespVO> getResourceList(Long categoryTreeId) {
        List<InfoPriceResourceDO> list = resourceMapper.selectListByCategoryTreeId(categoryTreeId);
        return BeanUtils.toBean(list, InfoPriceResourceRespVO.class);
    }

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

    private InfoPriceResourceDO validateResourceExists(Long id) {
        InfoPriceResourceDO resource = resourceMapper.selectById(id);
        if (resource == null) {
            throw exception(INFO_PRICE_RESOURCE_NOT_EXISTS);
        }
        return resource;
    }

    private void validateContentNode(Long categoryTreeId) {
        InfoPriceCategoryTreeDO node = categoryTreeMapper.selectById(categoryTreeId);
        if (node == null) {
            throw exception(INFO_PRICE_CATEGORY_TREE_NOT_EXISTS);
        }
        if (!InfoPriceCategoryNodeTypeEnum.CONTENT.getType().equals(node.getNodeType())) {
            throw exception(INFO_PRICE_RESOURCE_ONLY_UNDER_CONTENT_NODE);
        }
    }

    private void validateCodeUnique(Long categoryTreeId, String code, Long excludeId) {
        InfoPriceResourceDO existing = resourceMapper.selectByCategoryTreeIdAndCode(categoryTreeId, code);
        if (existing != null && !existing.getId().equals(excludeId)) {
            throw exception(INFO_PRICE_RESOURCE_CODE_DUPLICATE, code);
        }
    }

}
