package com.ycwl.basic.face.pipeline.core;

import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.face.pipeline.enums.FaceMatchingScene;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.task.resp.SearchFaceRespVo;
import com.ycwl.basic.pipeline.core.PipelineContext;
import lombok.Getter;
import lombok.Setter;

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

/**
 * 人脸匹配管线上下文
 * 在各个Stage之间传递状态和数据
 */
@Getter
@Setter
public class FaceMatchingContext implements PipelineContext {

    // ==================== 核心字段（构造时必填）====================

    /**
     * 人脸ID（必填）
     */
    private final Long faceId;

    /**
     * 是否新用户
     */
    private final boolean isNew;

    // ==================== 场景标识 ====================

    /**
     * 场景标识
     */
    private FaceMatchingScene scene;

    /**
     * 手动选择的样本ID（自定义匹配场景）
     */
    private List<Long> faceSampleIds;

    // ==================== 中间状态 ====================

    /**
     * 人脸实体
     */
    private FaceEntity face;

    /**
     * 景区配置管理器
     */
    private ScenicConfigManager scenicConfig;

    /**
     * 人脸识别适配器
     */
    private IFaceBodyAdapter faceBodyAdapter;

    /**
     * 人脸搜索结果
     */
    private SearchFaceRespVo searchResult;

    /**
     * 人脸样本列表（自定义匹配场景）
     */
    private List<FaceSampleEntity> faceSamples;

    /**
     * 匹配到的样本ID列表
     */
    private List<Long> sampleListIds;

    /**
     * 源文件关联列表
     */
    private List<MemberSourceEntity> memberSourceList;

    /**
     * 免费源文件ID列表
     */
    private List<Long> freeSourceIds;

    /**
     * 关联扩展的样本ID列表（由 ExpandSampleAssociationStage 设置）
     * 用于标识哪些 sampleId 是通过关联分组扩展得到的，而非直接匹配
     */
    private List<Long> associatedSampleIds;

    /**
     * 人脸选择后置模式配置（自定义匹配场景）
     * 0: 并集, 1: 交集, 2: 直接使用
     */
    private Integer faceSelectPostMode;

    // ==================== 输出结果 ====================

    /**
     * 最终结果
     */
    private SearchFaceRespVo finalResult;

    // ==================== Stage配置 ====================

    /**
     * Stage开关配置表
     * Key: stageId, Value: 是否启用
     */
    private Map<String, Boolean> stageEnabledMap = new HashMap<>();

    // ==================== 构造函数（私有）====================

    private FaceMatchingContext(Builder builder) {
        this.faceId = builder.faceId;
        this.isNew = builder.isNew;
        this.scene = builder.scene;
        this.faceSampleIds = builder.faceSampleIds;
    }

    // ==================== 静态工厂方法 ====================

    /**
     * 获取 Builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * 快速创建自动匹配场景Context
     */
    public static FaceMatchingContext forAutoMatching(Long faceId, boolean isNew) {
        return FaceMatchingContext.builder()
                .faceId(faceId)
                .isNew(isNew)
                .scene(FaceMatchingScene.AUTO_MATCHING)
                .build();
    }

    /**
     * 快速创建自定义匹配场景Context
     */
    public static FaceMatchingContext forCustomMatching(Long faceId, List<Long> faceSampleIds) {
        return FaceMatchingContext.builder()
                .faceId(faceId)
                .isNew(false)
                .faceSampleIds(faceSampleIds)
                .scene(FaceMatchingScene.CUSTOM_MATCHING)
                .build();
    }

    /**
     * 快速创建仅识别场景Context
     */
    public static FaceMatchingContext forRecognitionOnly(Long faceId) {
        return FaceMatchingContext.builder()
                .faceId(faceId)
                .isNew(false)
                .scene(FaceMatchingScene.RECOGNITION_ONLY)
                .build();
    }

    // ==================== 业务方法 ====================

    /**
     * 判断指定Stage是否启用
     *
     * @param stageId        Stage唯一标识
     * @param defaultEnabled 默认值(当配置未指定时使用)
     * @return true-启用, false-禁用
     */
    @Override
    public boolean isStageEnabled(String stageId, boolean defaultEnabled) {
        return stageEnabledMap.getOrDefault(stageId, defaultEnabled);
    }

    /**
     * 判断指定Stage是否启用(默认为false)
     *
     * @param stageId Stage唯一标识
     * @return true-启用, false-禁用
     */
    @Override
    public boolean isStageEnabled(String stageId) {
        return stageEnabledMap.getOrDefault(stageId, false);
    }

    /**
     * 设置指定Stage的启用状态
     *
     * @param stageId Stage唯一标识
     * @param enabled 是否启用
     * @return this(支持链式调用)
     */
    public FaceMatchingContext setStageState(String stageId, boolean enabled) {
        stageEnabledMap.put(stageId, enabled);
        return this;
    }

    /**
     * 启用指定Stage
     *
     * @param stageId Stage唯一标识
     * @return this(支持链式调用)
     */
    public FaceMatchingContext enableStage(String stageId) {
        stageEnabledMap.put(stageId, true);
        return this;
    }

    /**
     * 禁用指定Stage
     *
     * @param stageId Stage唯一标识
     * @return this(支持链式调用)
     */
    public FaceMatchingContext disableStage(String stageId) {
        stageEnabledMap.put(stageId, false);
        return this;
    }

    /**
     * 批量设置Stage启用状态
     *
     * @param stages Stage配置Map(stageId -> enabled)
     * @return this(支持链式调用)
     */
    public FaceMatchingContext setStages(Map<String, Boolean> stages) {
        if (stages != null) {
            stageEnabledMap.putAll(stages);
        }
        return this;
    }

    /**
     * 清空所有Stage配置
     *
     * @return this(支持链式调用)
     */
    public FaceMatchingContext clearStages() {
        stageEnabledMap.clear();
        return this;
    }

    // ==================== Builder ====================

    public static class Builder {
        private Long faceId;
        private boolean isNew = false;
        private FaceMatchingScene scene;
        private List<Long> faceSampleIds;

        public Builder faceId(Long faceId) {
            this.faceId = faceId;
            return this;
        }

        public Builder isNew(boolean isNew) {
            this.isNew = isNew;
            return this;
        }

        public Builder scene(FaceMatchingScene scene) {
            this.scene = scene;
            return this;
        }

        public Builder faceSampleIds(List<Long> faceSampleIds) {
            this.faceSampleIds = faceSampleIds;
            return this;
        }

        public FaceMatchingContext build() {
            // 参数校验
            if (faceId == null) {
                throw new IllegalArgumentException("faceId is required");
            }
            if (scene == null) {
                throw new IllegalArgumentException("scene is required");
            }
            // 自定义匹配场景必须提供faceSampleIds
            if (scene == FaceMatchingScene.CUSTOM_MATCHING && (faceSampleIds == null || faceSampleIds.isEmpty())) {
                throw new IllegalArgumentException("faceSampleIds is required for CUSTOM_MATCHING scene");
            }
            return new FaceMatchingContext(this);
        }
    }
}
