package com.zt.plat.module.base.service.businessdictionarytype;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import com.zt.plat.module.base.controller.admin.businessdictionarytype.vo.*;
import com.zt.plat.module.base.dal.dataobject.businessdictionarytype.BusinessDictionaryTypeDO;
import com.zt.plat.module.base.dal.dataobject.businessdictionarytype.BusinessDictionaryDataDO;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;

import com.zt.plat.module.base.dal.dao.businessdictionarytype.BusinessDictionaryTypeMapper;
import com.zt.plat.module.base.dal.dao.businessdictionarytype.BusinessDictionaryDataMapper;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.diffList;
import static com.zt.plat.module.base.enums.ErrorCodeConstants.*;

/**
 * 业务字典类型 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class BusinessDictionaryTypeServiceImpl implements BusinessDictionaryTypeService {

    @Resource
    private BusinessDictionaryTypeMapper businessDictionaryTypeMapper;
    @Resource
    private BusinessDictionaryDataMapper businessDictionaryDataMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessDictionaryTypeRespVO createBusinessDictionaryType(BusinessDictionaryTypeSaveReqVO createReqVO) {
        // 插入
        BusinessDictionaryTypeDO businessDictionaryType = BeanUtils.toBean(createReqVO, BusinessDictionaryTypeDO.class);
        businessDictionaryTypeMapper.insert(businessDictionaryType);

        // 插入子表
        createBusinessDictionaryDataList(businessDictionaryType.getId(), createReqVO.getBusinessDictionaryDatas());
        // 返回
        return BeanUtils.toBean(businessDictionaryType, BusinessDictionaryTypeRespVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBusinessDictionaryType(BusinessDictionaryTypeSaveReqVO updateReqVO) {
        // 校验存在
        validateBusinessDictionaryTypeExists(updateReqVO.getId());
        // 更新
        BusinessDictionaryTypeDO updateObj = BeanUtils.toBean(updateReqVO, BusinessDictionaryTypeDO.class);
        businessDictionaryTypeMapper.updateById(updateObj);

        // 更新子表
        updateBusinessDictionaryDataList(updateReqVO.getId(), updateReqVO.getBusinessDictionaryDatas());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBusinessDictionaryType(Long id) {
        // 校验存在
        validateBusinessDictionaryTypeExists(id);
        // 删除
        businessDictionaryTypeMapper.deleteById(id);

        // 删除子表
        deleteBusinessDictionaryDataByDictionaryTypeId(id);
    }

    @Override
        @Transactional(rollbackFor = Exception.class)
    public void deleteBusinessDictionaryTypeListByIds(List<Long> ids) {
        // 校验存在
        validateBusinessDictionaryTypeExists(ids);
        // 删除
        businessDictionaryTypeMapper.deleteByIds(ids);
    
    // 删除子表
            deleteBusinessDictionaryDataByDictionaryTypeIds(ids);
    }

    private void validateBusinessDictionaryTypeExists(List<Long> ids) {
        List<BusinessDictionaryTypeDO> list = businessDictionaryTypeMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(BUSINESS_DICTIONARY_TYPE_NOT_EXISTS);
        }
    }

    private void validateBusinessDictionaryTypeExists(Long id) {
        if (businessDictionaryTypeMapper.selectById(id) == null) {
            throw exception(BUSINESS_DICTIONARY_TYPE_NOT_EXISTS);
        }
    }

    @Override
    public BusinessDictionaryTypeDO getBusinessDictionaryType(Long id) {
        return businessDictionaryTypeMapper.selectById(id);
    }

    @Override
    public PageResult<BusinessDictionaryTypeDO> getBusinessDictionaryTypePage(BusinessDictionaryTypePageReqVO pageReqVO) {
        return businessDictionaryTypeMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（业务字典数据） ====================

    @Override
    public List<BusinessDictionaryDataDO> getBusinessDictionaryDataListByDictionaryTypeId(Long dictionaryTypeId) {
        return businessDictionaryDataMapper.selectListByDictionaryTypeId(dictionaryTypeId);
    }

    @Override
    public List<BusinessDictionaryDataDO> getBusinessDictionaryDataListByType(String type) {
        if (StrUtil.isBlank(type)) {
            return Collections.emptyList();
        }
        BusinessDictionaryTypeDO dictionaryType = businessDictionaryTypeMapper.selectByType(type);
        if (dictionaryType == null) {
            return Collections.emptyList();
        }
        // 直接根据类型编码定位字典类型，简化前端查询流程
        return businessDictionaryDataMapper.selectListByDictionaryTypeId(dictionaryType.getId());
    }

    private void createBusinessDictionaryDataList(Long dictionaryTypeId, List<BusinessDictionaryDataDO> list) {
        list.forEach(o -> o.setDictionaryTypeId(dictionaryTypeId).clean());
        businessDictionaryDataMapper.insertBatch(list);
    }

    private void updateBusinessDictionaryDataList(Long dictionaryTypeId, List<BusinessDictionaryDataDO> list) {
	    list.forEach(o -> o.setDictionaryTypeId(dictionaryTypeId).clean());
	    List<BusinessDictionaryDataDO> oldList = businessDictionaryDataMapper.selectListByDictionaryTypeId(dictionaryTypeId);
	    List<List<BusinessDictionaryDataDO>> diffList = diffList(oldList, list, (oldVal, newVal) -> {
            boolean same = ObjectUtil.equal(oldVal.getId(), newVal.getId());
            if (same) {
                newVal.setId(oldVal.getId()).clean(); // 解决更新情况下：updateTime 不更新
            }
            return same;
	    });

	    // 第二步，批量添加、修改、删除
	    if (CollUtil.isNotEmpty(diffList.get(0))) {
	        businessDictionaryDataMapper.insertBatch(diffList.get(0));
	    }
	    if (CollUtil.isNotEmpty(diffList.get(1))) {
	        businessDictionaryDataMapper.updateBatch(diffList.get(1));
	    }
	    if (CollUtil.isNotEmpty(diffList.get(2))) {
	        businessDictionaryDataMapper.deleteByIds(convertList(diffList.get(2), BusinessDictionaryDataDO::getId));
	    }
    }

    private void deleteBusinessDictionaryDataByDictionaryTypeId(Long dictionaryTypeId) {
        businessDictionaryDataMapper.deleteByDictionaryTypeId(dictionaryTypeId);
    }

	private void deleteBusinessDictionaryDataByDictionaryTypeIds(List<Long> dictionaryTypeIds) {
        businessDictionaryDataMapper.deleteByDictionaryTypeIds(dictionaryTypeIds);
	}

}