package com.ycwl.basic.puzzle.fill;

import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.puzzle.entity.PuzzleFillRuleEntity;
import com.ycwl.basic.puzzle.entity.PuzzleFillRuleItemEntity;
import com.ycwl.basic.puzzle.fill.condition.ConditionContext;
import com.ycwl.basic.puzzle.fill.condition.ConditionEvaluator;
import com.ycwl.basic.puzzle.fill.datasource.DataSourceContext;
import com.ycwl.basic.puzzle.fill.datasource.DataSourceResolver;
import com.ycwl.basic.puzzle.mapper.PuzzleFillRuleItemMapper;
import com.ycwl.basic.puzzle.mapper.PuzzleFillRuleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 拼图元素自动填充引擎
 * 核心业务逻辑:
 * 1. 查询模板的所有规则(按priority DESC)
 * 2. 遍历规则,评估条件是否匹配
 * 3. 匹配成功后,批量填充该规则的所有明细项
 * 4. 匹配第一条后停止(优先级逻辑)
 */
@Slf4j
@Component
public class PuzzleElementFillEngine {

    @Autowired
    private PuzzleFillRuleMapper ruleMapper;

    @Autowired
    private PuzzleFillRuleItemMapper itemMapper;

    @Autowired
    private SourceMapper sourceMapper;

    @Autowired
    private ConditionEvaluator conditionEvaluator;

    @Autowired
    private DataSourceResolver dataSourceResolver;

    /**
     * 执行填充规则
     *
     * @param templateId 模板ID
     * @param faceId 人脸ID
     * @param scenicId 景区ID
     * @return 填充结果（包含是否匹配规则的信息）
     */
    public FillResult execute(Long templateId, Long faceId, Long scenicId) {
        if (faceId == null) {
            log.debug("自动填充被跳过, templateId={}, faceId={}", templateId, faceId);
            return FillResult.noMatch();
        }

        try {
            // 1. 查询模板的所有启用规则(按priority DESC排序)
            List<PuzzleFillRuleEntity> rules = ruleMapper.listByTemplateId(templateId);
            if (rules == null || rules.isEmpty()) {
                log.debug("模板[{}]没有配置自动填充规则", templateId);
                return FillResult.noMatch();
            }

            log.info("模板[{}]共有{}条填充规则,开始执行...", templateId, rules.size());

            // 2. 统计机位数量和获取机位列表(缓存,避免重复查询)
            Integer deviceCount = sourceMapper.countDistinctDevicesByFaceId(faceId);
            List<Long> deviceIds = sourceMapper.getDeviceIdsByFaceId(faceId);
            log.debug("faceId[{}]关联机位数量: {}, 机位列表: {}", faceId, deviceCount, deviceIds);

            // 3. 构建条件评估上下文
            ConditionContext conditionContext = ConditionContext.builder()
                    .faceId(faceId)
                    .deviceCount(deviceCount)
                    .deviceIds(deviceIds)
                    .build();

            // 4. 遍历规则,匹配第一条后停止
            for (PuzzleFillRuleEntity rule : rules) {
                // 评估条件是否匹配
                boolean matched = conditionEvaluator.evaluate(rule, conditionContext);

                if (!matched) {
                    log.debug("规则[{}]条件不匹配,跳过", rule.getRuleName());
                    continue;
                }

                // 条件匹配!查询该规则的所有明细
                log.info("规则[{}]匹配成功,开始执行填充...", rule.getRuleName());
                List<PuzzleFillRuleItemEntity> items = itemMapper.listByRuleId(rule.getId());

                if (items == null || items.isEmpty()) {
                    log.warn("规则[{}]没有配置明细项", rule.getRuleName());
                    continue;
                }

                // 5. 批量填充dynamicData
                DataSourceContext dataSourceContext = DataSourceContext.builder()
                        .faceId(faceId)
                        .scenicId(scenicId)
                        .extra(conditionContext.getExtra())
                        .build();

                Map<String, String> dynamicData = new HashMap<>();
                int successCount = 0;
                for (PuzzleFillRuleItemEntity item : items) {
                    String value = dataSourceResolver.resolve(
                            item.getDataSource(),
                            item.getSourceFilter(),
                            item.getSortStrategy(),
                            item.getFallbackValue(),
                            dataSourceContext
                    );

                    if (value != null && !value.isEmpty()) {
                        dynamicData.put(item.getElementKey(), value);
                        successCount++;
                        log.debug("填充成功: {} -> {}", item.getElementKey(), value);
                    } else {
                        log.debug("填充失败(值为空): {}", item.getElementKey());
                    }
                }

                log.info("规则[{}]执行完成,成功填充{}/{}个元素", rule.getRuleName(), successCount, items.size());

                // 6. 返回匹配成功的结果
                return FillResult.matched(rule.getRuleName(), dynamicData, successCount);
            }

            // 所有规则都不匹配
            log.info("所有规则都不匹配, templateId={}, faceId={}", templateId, faceId);
            return FillResult.noMatch();

        } catch (Exception e) {
            log.error("自动填充引擎执行异常, templateId={}, faceId={}", templateId, faceId, e);
            return FillResult.noMatch();
        }
    }
}
