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.QUOTA_CATALOG_ITEM_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_CATALOG_ITEM_SPECIALTY_NOT_FOUND;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_RATE_FIELD_BINDING_OUT_OF_RANGE;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_RATE_FIELD_NOT_EXISTS;
import static com.yhy.module.core.enums.ErrorCodeConstants.QUOTA_RATE_ITEM_NOT_EXISTS;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldRespVO;
import com.yhy.module.core.controller.admin.quota.vo.QuotaRateFieldSaveReqVO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogItemDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaCatalogTreeDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateFieldLabelDO;
import com.yhy.module.core.dal.dataobject.quota.QuotaRateItemDO;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogItemMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaCatalogTreeMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaRateFieldLabelMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaRateFieldMapper;
import com.yhy.module.core.dal.mysql.quota.QuotaRateItemMapper;
import com.yhy.module.core.enums.ErrorCodeConstants;
import com.yhy.module.core.service.quota.QuotaRateFieldService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 定额费率字段绑定 Service 实现
 */
@Service
@RequiredArgsConstructor
public class QuotaRateFieldServiceImpl implements QuotaRateFieldService {

    private final QuotaRateFieldMapper rateFieldMapper;
    private final QuotaCatalogItemMapper catalogItemMapper;
    private final QuotaCatalogTreeMapper catalogTreeMapper;
    private final QuotaRateFieldLabelMapper fieldLabelMapper;
    private final QuotaRateItemMapper rateItemMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveRateField(QuotaRateFieldSaveReqVO saveReqVO) {
        // 1. 验证费率模式节点存在
        QuotaCatalogItemDO catalogItem = catalogItemMapper.selectById(saveReqVO.getCatalogItemId());
        if (catalogItem == null) {
            throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
        }
        
        // 2. 如果提供了 rateItemId，则保存字段值到费率项的 settings.fieldValues
        if (saveReqVO.getRateItemId() != null) {
            // 验证费率项存在
            QuotaRateItemDO rateItem = rateItemMapper.selectById(saveReqVO.getRateItemId());
            if (rateItem == null) {
                throw exception(QUOTA_RATE_ITEM_NOT_EXISTS);
            }
            
            // 获取或创建 settings
            Map<String, Object> settings = rateItem.getSettings();
            if (settings == null) {
                settings = new HashMap<>();
            }
            
            // 获取或创建 fieldValues
            @SuppressWarnings("unchecked")
            Map<String, Object> fieldValues = (Map<String, Object>) settings.get("fieldValues");
            if (fieldValues == null) {
                fieldValues = new HashMap<>();
                settings.put("fieldValues", fieldValues);
            }
            
            // 保存或删除字段值
            String fieldIndexStr = String.valueOf(saveReqVO.getFieldIndex());
            if (saveReqVO.getFieldValue() != null) {
                // 保存字段值
                fieldValues.put(fieldIndexStr, saveReqVO.getFieldValue());
            } else {
                // 删除字段值（当值为 null 时）
                fieldValues.remove(fieldIndexStr);
            }
            
            // 更新费率项
            QuotaRateItemDO updateObj = new QuotaRateItemDO();
            updateObj.setId(saveReqVO.getRateItemId());
            updateObj.setSettings(settings);
            rateItemMapper.updateById(updateObj);
        }
        
        // 3. 保存字段绑定配置（binding_ids, field_label_id）到 yhy_quota_rate_field
        if (saveReqVO.getBindingIds() != null || saveReqVO.getFieldLabelId() != null) {
            // 验证绑定范围
            if (saveReqVO.getBindingIds() != null && saveReqVO.getBindingIds().length > 0) {
                validateBindingRange(saveReqVO.getCatalogItemId(), saveReqVO.getBindingIds());
            }
            
            // 查询是否已存在
            QuotaRateFieldDO existField = rateFieldMapper.selectByCatalogItemIdAndFieldIndex(
                    saveReqVO.getCatalogItemId(), saveReqVO.getFieldIndex());
            
            if (existField != null) {
                // 更新（只更新 binding_ids 和 field_label_id，不更新 field_value）
                QuotaRateFieldDO updateObj = new QuotaRateFieldDO();
                updateObj.setId(existField.getId());
                if (saveReqVO.getBindingIds() != null) {
                    updateObj.setBindingIds(saveReqVO.getBindingIds());
                }
                if (saveReqVO.getFieldLabelId() != null) {
                    updateObj.setFieldLabelId(saveReqVO.getFieldLabelId());
                }
                rateFieldMapper.updateById(updateObj);
                return existField.getId();
            } else {
                // 新增（不保存 field_value）
                QuotaRateFieldDO insertObj = new QuotaRateFieldDO();
                insertObj.setCatalogItemId(saveReqVO.getCatalogItemId());
                insertObj.setFieldIndex(saveReqVO.getFieldIndex());
                insertObj.setBindingIds(saveReqVO.getBindingIds());
                insertObj.setFieldLabelId(saveReqVO.getFieldLabelId());
                rateFieldMapper.insert(insertObj);
                return insertObj.getId();
            }
        }
        
        return null;
    }

    @Override
    public void deleteRateField(Long id) {
        QuotaRateFieldDO field = rateFieldMapper.selectById(id);
        if (field == null) {
            throw exception(QUOTA_RATE_FIELD_NOT_EXISTS);
        }
        rateFieldMapper.deleteById(id);
    }

    @Override
    public void deleteByCatalogItemId(Long catalogItemId) {
        rateFieldMapper.deleteByCatalogItemId(catalogItemId);
    }

    @Override
    public QuotaRateFieldDO getRateField(Long id) {
        return rateFieldMapper.selectById(id);
    }

    @Override
    public List<QuotaRateFieldRespVO> getRateFieldList(Long catalogItemId) {
        List<QuotaRateFieldDO> fields = rateFieldMapper.selectListByCatalogItemId(catalogItemId);
        return fields.stream()
                .map(field -> {
                    QuotaRateFieldRespVO vo = BeanUtils.toBean(field, QuotaRateFieldRespVO.class);
                    // 关联查询标签名称
                    if (field.getFieldLabelId() != null) {
                        QuotaRateFieldLabelDO label = fieldLabelMapper.selectById(field.getFieldLabelId());
                        if (label != null) {
                            vo.setFieldLabelName(label.getLabelName());
                        }
                    }
                    return vo;
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBinding(Long catalogItemId, Integer fieldIndex, Long[] bindingIds) {
        // 1. 验证费率模式节点存在
        QuotaCatalogItemDO catalogItem = catalogItemMapper.selectById(catalogItemId);
        if (catalogItem == null) {
            throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
        }
        
        // 2. 验证绑定范围
        if (bindingIds != null && bindingIds.length > 0) {
            validateBindingRange(catalogItemId, bindingIds);
            
            // 3. 验证节点是否已被其他虚拟字段绑定
            for (Long bindingId : bindingIds) {
                List<QuotaRateFieldDO> existingFields = rateFieldMapper.selectByBindingIdExcludeFieldIndex(
                        catalogItemId, bindingId, fieldIndex);
                if (!existingFields.isEmpty()) {
                    throw exception(ErrorCodeConstants.QUOTA_RATE_FIELD_NODE_ALREADY_BOUND);
                }
            }
        }
        
        // 4. 查询或创建字段
        QuotaRateFieldDO field = rateFieldMapper.selectByCatalogItemIdAndFieldIndex(catalogItemId, fieldIndex);
        if (field == null) {
            field = new QuotaRateFieldDO();
            field.setCatalogItemId(catalogItemId);
            field.setFieldIndex(fieldIndex);
            field.setBindingIds(bindingIds);
            rateFieldMapper.insert(field);
        } else {
            field.setBindingIds(bindingIds);
            rateFieldMapper.updateById(field);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchSaveRateFields(Long catalogItemId, List<QuotaRateFieldSaveReqVO> fields) {
        // 1. 验证费率模式节点存在
        QuotaCatalogItemDO catalogItem = catalogItemMapper.selectById(catalogItemId);
        if (catalogItem == null) {
            throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
        }
        
        // 2. 删除原有字段
        rateFieldMapper.deleteByCatalogItemId(catalogItemId);
        
        // 3. 批量插入新字段
        for (QuotaRateFieldSaveReqVO fieldVO : fields) {
            fieldVO.setCatalogItemId(catalogItemId);
            
            // 验证绑定范围
            if (fieldVO.getBindingIds() != null && fieldVO.getBindingIds().length > 0) {
                validateBindingRange(catalogItemId, fieldVO.getBindingIds());
            }
            
            QuotaRateFieldDO field = BeanUtils.toBean(fieldVO, QuotaRateFieldDO.class);
            rateFieldMapper.insert(field);
        }
    }

    @Override
    public void validateBindingRange(Long catalogItemId, Long[] bindingIds) {
        if (bindingIds == null || bindingIds.length == 0) {
            return;
        }
        
        // 1. 获取模式节点所属的定额专业
        QuotaCatalogItemDO modeNode = catalogItemMapper.selectById(catalogItemId);
        if (modeNode == null) {
            throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
        }
        
        // 向上追溯到定额专业节点
        Long specialtyId = findSpecialtyId(modeNode);
        if (specialtyId == null) {
            throw exception(QUOTA_CATALOG_ITEM_SPECIALTY_NOT_FOUND);
        }
        
        // 2. 验证每个绑定节点是否属于同一定额专业
        // 注意：bindingIds 是定额基价树（yhy_quota_catalog_tree）的ID，不是定额专业树的ID
        for (Long bindingId : bindingIds) {
            // 查询定额基价树节点
            QuotaCatalogTreeDO treeNode = catalogTreeMapper.selectById(bindingId);
            if (treeNode == null) {
                throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
            }
            
            // 获取该子目树节点关联的定额专业节点
            QuotaCatalogItemDO catalogItem = catalogItemMapper.selectById(treeNode.getCatalogItemId());
            if (catalogItem == null) {
                throw exception(QUOTA_CATALOG_ITEM_NOT_EXISTS);
            }
            
            // 验证是否属于同一定额专业
            Long bindingSpecialtyId = findSpecialtyId(catalogItem);
            if (!specialtyId.equals(bindingSpecialtyId)) {
                throw exception(QUOTA_RATE_FIELD_BINDING_OUT_OF_RANGE);
            }
        }
    }

    /**
     * 向上追溯找到定额专业节点ID
     */
    private Long findSpecialtyId(QuotaCatalogItemDO node) {
        QuotaCatalogItemDO current = node;
        while (current != null) {
            if ("specialty".equals(current.getNodeType())) {
                return current.getId();
            }
            if (current.getParentId() == null) {
                break;
            }
            current = catalogItemMapper.selectById(current.getParentId());
        }
        return null;
    }
}
