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

import cn.hutool.core.collection.CollUtil;
import com.yhy.module.core.dal.dataobject.quota.QuotaAdjustmentSettingDO;
import com.yhy.module.core.dal.dataobject.workbench.WbAdjustmentSettingDO;
import com.yhy.module.core.dal.dataobject.workbench.WbBoqDivisionDO;
import com.yhy.module.core.dal.mysql.quota.QuotaAdjustmentSettingMapper;
import com.yhy.module.core.dal.mysql.workbench.WbAdjustmentSettingMapper;
import com.yhy.module.core.dal.mysql.workbench.WbBoqDivisionMapper;
import com.yhy.module.core.service.workbench.WbAdjustmentSettingService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

/**
 * 工作台定额调整设置 Service 实现类
 *
 * @author yhy
 */
@Service
@Validated
@Slf4j
public class WbAdjustmentSettingServiceImpl implements WbAdjustmentSettingService {

    @Resource
    private WbAdjustmentSettingMapper wbAdjustmentSettingMapper;

    @Resource
    private WbBoqDivisionMapper wbBoqDivisionMapper;

    @Resource
    private QuotaAdjustmentSettingMapper quotaAdjustmentSettingMapper;

    @Override
    public List<WbAdjustmentSettingDO> getListByDivisionId(Long divisionId) {
        return wbAdjustmentSettingMapper.selectListByDivisionId(divisionId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<WbAdjustmentSettingDO> copyFromQuotaAdjustmentSetting(Long divisionId, Long sourceQuotaItemId) {
        // 1. 检查是否已经复制过
        List<WbAdjustmentSettingDO> existingSettings = wbAdjustmentSettingMapper.selectListByDivisionId(divisionId);
        if (CollUtil.isNotEmpty(existingSettings)) {
            log.debug("[copyFromQuotaAdjustmentSetting] 已存在调整设置，divisionId={}", divisionId);
            return existingSettings;
        }

        // 2. 从后台获取定额调整设置
        List<QuotaAdjustmentSettingDO> sourceSettings = quotaAdjustmentSettingMapper.selectListByQuotaItemId(sourceQuotaItemId);
        if (CollUtil.isEmpty(sourceSettings)) {
            log.debug("[copyFromQuotaAdjustmentSetting] 后台无调整设置，sourceQuotaItemId={}", sourceQuotaItemId);
            return new ArrayList<>();
        }

        // 3. 复制到工作台（不复制 adjustmentContent 和 inputValue，新复制的定额调整应该没有初始值）
        List<WbAdjustmentSettingDO> copiedSettings = new ArrayList<>();
        for (QuotaAdjustmentSettingDO source : sourceSettings) {
            WbAdjustmentSettingDO target = new WbAdjustmentSettingDO();
            target.setDivisionId(divisionId);
            target.setSourceAdjustmentSettingId(source.getId());
            target.setName(source.getName());
            target.setQuotaValue(source.getQuotaValue());
            // 不复制 adjustmentContent，新复制的定额调整应该没有初始值
            // target.setAdjustmentContent(source.getAdjustmentContent());
            target.setAdjustmentType(source.getAdjustmentType());
            // 复制 adjustmentRules，但移除 items 中的 inputValue（用户填写的值不应复制）
            target.setAdjustmentRules(copyAdjustmentRulesWithoutInputValue(source.getAdjustmentRules()));
            target.setSortOrder(source.getSortOrder());
            
            // 保存快照
            Map<String, Object> snapshot = new HashMap<>();
            snapshot.put("sourceId", source.getId());
            snapshot.put("sourceName", source.getName());
            snapshot.put("sourceQuotaItemId", sourceQuotaItemId);
            target.setSnapshotJson(snapshot);
            
            wbAdjustmentSettingMapper.insert(target);
            copiedSettings.add(target);
        }

        log.info("[copyFromQuotaAdjustmentSetting] 复制完成，divisionId={}, count={}", divisionId, copiedSettings.size());
        return copiedSettings;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdjustmentRules(Long id, Map<String, Object> adjustmentRules) {
        WbAdjustmentSettingDO setting = wbAdjustmentSettingMapper.selectById(id);
        if (setting == null) {
            log.warn("[updateAdjustmentRules] 调整设置不存在，id={}", id);
            return;
        }
        setting.setAdjustmentRules(adjustmentRules);
        wbAdjustmentSettingMapper.updateById(setting);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyAdjustmentSetting(Long divisionId, Long adjustmentSettingId, boolean enabled) {
        // TODO: 实现应用调整设置逻辑
        // 类似后台的 applyAdjustmentSetting，但操作的是工作台的工料机数据
        log.info("[applyAdjustmentSetting] divisionId={}, adjustmentSettingId={}, enabled={}", 
                divisionId, adjustmentSettingId, enabled);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyDynamicAdjustment(Long divisionId, Long adjustmentSettingId, Map<String, BigDecimal> inputValues) {
        // 1. 获取调整设置
        WbAdjustmentSettingDO setting = wbAdjustmentSettingMapper.selectById(adjustmentSettingId);
        if (setting == null) {
            log.warn("[applyDynamicAdjustment] 调整设置不存在，adjustmentSettingId={}", adjustmentSettingId);
            return;
        }

        // 2. 更新 inputValue 到 adjustmentRules
        Map<String, Object> adjustmentRules = setting.getAdjustmentRules();
        if (adjustmentRules != null && adjustmentRules.get("items") instanceof List) {
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> items = (List<Map<String, Object>>) adjustmentRules.get("items");
            for (Map<String, Object> item : items) {
                String categoryId = item.get("category") != null ? item.get("category").toString() : null;
                if (categoryId != null) {
                    if (inputValues.containsKey(categoryId)) {
                        item.put("inputValue", inputValues.get(categoryId));
                    } else {
                        // 没有输入值则清空（用户清除了值）
                        item.remove("inputValue");
                    }
                }
            }
            setting.setAdjustmentRules(adjustmentRules);
            wbAdjustmentSettingMapper.updateById(setting);
        }

        // TODO: 实现动态调整计算逻辑
        log.info("[applyDynamicAdjustment] divisionId={}, adjustmentSettingId={}, inputValues={}", 
                divisionId, adjustmentSettingId, inputValues);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applyDynamicMerge(Long divisionId, Long adjustmentSettingId, Map<String, BigDecimal> inputValues) {
        // 1. 获取调整设置
        WbAdjustmentSettingDO setting = wbAdjustmentSettingMapper.selectById(adjustmentSettingId);
        if (setting == null) {
            log.warn("[applyDynamicMerge] 调整设置不存在，adjustmentSettingId={}", adjustmentSettingId);
            return;
        }

        // 2. 更新 inputValue 到 adjustmentRules
        Map<String, Object> adjustmentRules = setting.getAdjustmentRules();
        if (adjustmentRules != null && adjustmentRules.get("items") instanceof List) {
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> items = (List<Map<String, Object>>) adjustmentRules.get("items");
            for (Map<String, Object> item : items) {
                String code = item.get("code") != null ? item.get("code").toString() : null;
                if (code != null) {
                    if (inputValues.containsKey(code)) {
                        // 有输入值则更新
                        item.put("inputValue", inputValues.get(code));
                    } else {
                        // 没有输入值则清空（用户清除了值）
                        item.remove("inputValue");
                    }
                }
            }
            setting.setAdjustmentRules(adjustmentRules);
            wbAdjustmentSettingMapper.updateById(setting);
        }

        // TODO: 实现动态合并定额计算逻辑
        log.info("[applyDynamicMerge] divisionId={}, adjustmentSettingId={}, inputValues={}", 
                divisionId, adjustmentSettingId, inputValues);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByDivisionId(Long divisionId) {
        wbAdjustmentSettingMapper.deleteByDivisionId(divisionId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdjustmentSetting(Long id, String adjustmentContent) {
        WbAdjustmentSettingDO setting = wbAdjustmentSettingMapper.selectById(id);
        if (setting == null) {
            log.warn("[updateAdjustmentSetting] 调整设置不存在，id={}", id);
            return;
        }
        setting.setAdjustmentContent(adjustmentContent);
        wbAdjustmentSettingMapper.updateById(setting);
        log.info("[updateAdjustmentSetting] 更新调整设置成功，id={}, adjustmentContent={}", id, adjustmentContent);
    }

    @Override
    public List<Map<String, Object>> getAdjustmentCombinedList(Long divisionId) {
        // 1. 获取分部分项节点，获取关联的定额基价ID
        WbBoqDivisionDO division = wbBoqDivisionMapper.selectById(divisionId);
        if (division == null || !"quota".equals(division.getNodeType())) {
            return new ArrayList<>();
        }

        Long sourceQuotaItemId = division.getSourceQuotaItemId();
        if (sourceQuotaItemId == null) {
            return new ArrayList<>();
        }

        // 2. 确保已复制调整设置
        List<WbAdjustmentSettingDO> settings = copyFromQuotaAdjustmentSetting(divisionId, sourceQuotaItemId);

        // 3. 转换为前端需要的格式
        List<Map<String, Object>> result = new ArrayList<>();
        for (WbAdjustmentSettingDO setting : settings) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", setting.getId());
            item.put("divisionId", setting.getDivisionId());
            item.put("name", setting.getName());
            item.put("quotaValue", setting.getQuotaValue());
            item.put("adjustmentType", setting.getAdjustmentType());
            item.put("adjustmentRules", setting.getAdjustmentRules());
            item.put("adjustmentContent", setting.getAdjustmentContent());
            item.put("sortOrder", setting.getSortOrder());
            result.add(item);
        }

        return result;
    }

    /**
     * 复制 adjustmentRules，但移除 items 中的 inputValue
     * 项目指引复制定额时，用户填写的调整值不应复制，应由用户重新填写
     */
    @SuppressWarnings("unchecked")
    private Map<String, Object> copyAdjustmentRulesWithoutInputValue(Map<String, Object> sourceRules) {
        if (sourceRules == null || sourceRules.isEmpty()) {
            return sourceRules;
        }
        
        // 深拷贝
        Map<String, Object> rules = new HashMap<>(sourceRules);
        
        // 移除 items 中的 inputValue
        if (rules.get("items") instanceof List) {
            List<Map<String, Object>> items = (List<Map<String, Object>>) rules.get("items");
            List<Map<String, Object>> newItems = new ArrayList<>();
            for (Map<String, Object> item : items) {
                Map<String, Object> newItem = new HashMap<>(item);
                newItem.remove("inputValue");
                newItems.add(newItem);
            }
            rules.put("items", newItems);
        }
        
        return rules;
    }
}
