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

import cn.hutool.core.date.DateUtil;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.puzzle.dto.PuzzleGenerateRequest;
import com.ycwl.basic.puzzle.dto.PuzzleGenerateResponse;
import com.ycwl.basic.puzzle.dto.PuzzleTemplateDTO;
import com.ycwl.basic.puzzle.service.IPuzzleGenerateService;
import com.ycwl.basic.puzzle.service.IPuzzleTemplateService;
import com.ycwl.basic.repository.ScenicRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 拼图生成编排器
 * 负责编排拼图模板的批量生成逻辑
 *
 * 职责:
 * 1. 查询景区的所有启用拼图模板
 * 2. 构建动态数据
 * 3. 逐个生成拼图图片
 * 4. 记录统计信息
 *
 * 设计说明:
 * - 从GeneratePuzzleStage中抽离出来,符合"薄Stage,厚Service"原则
 * - Stage只负责触发异步任务,业务逻辑由此Orchestrator承担
 */
@Slf4j
@Service
public class PuzzleGenerationOrchestrator {

    @Autowired
    private IPuzzleTemplateService puzzleTemplateService;

    @Autowired
    private IPuzzleGenerateService puzzleGenerateService;

    @Autowired
    private ScenicRepository scenicRepository;

    @Autowired
    private SourceMapper sourceMapper;

    /**
     * 异步生成景区所有启用的拼图模板
     *
     * @param scenicId 景区ID
     * @param faceId 人脸ID
     * @param memberId 会员ID
     * @param faceUrl 人脸URL
     */
    public void generateAllTemplatesAsync(Long scenicId, Long faceId, Long memberId, String faceUrl) {
        new Thread(() -> {
            try {
                log.info("开始异步生成景区拼图模板: scenicId={}, faceId={}", scenicId, faceId);

                // 1. 查询该景区所有启用状态的拼图模板
                List<PuzzleTemplateDTO> templateList = puzzleTemplateService.listTemplates(
                        scenicId, null, 1); // 查询启用状态的模板

                if (templateList == null || templateList.isEmpty()) {
                    log.info("景区不存在启用的拼图模板，跳过生成: scenicId={}", scenicId);
                    return;
                }

                log.info("景区存在 {} 个启用的拼图模板，开始逐个生成: scenicId={}", templateList.size(), scenicId);

                // 2. 获取景区信息用于动态数据
                ScenicV2DTO scenicBasic = scenicRepository.getScenicBasic(scenicId);

                // 3. 准备公共动态数据
                Map<String, String> baseDynamicData = buildBaseDynamicData(faceId, faceUrl, scenicBasic);

                // 4. 设置dateStr为图片素材的最大创建时间
                Date maxCreateTime = sourceMapper.getMaxCreateTimeByFaceId(faceId);
                baseDynamicData.put("dateStr", DateUtil.format(
                        maxCreateTime != null ? maxCreateTime : new Date(), "yyyy.MM.dd"));

                // 4. 使用虚拟线程池并行生成所有模板
                java.util.concurrent.atomic.AtomicInteger successCount = new java.util.concurrent.atomic.AtomicInteger(0);
                java.util.concurrent.atomic.AtomicInteger failCount = new java.util.concurrent.atomic.AtomicInteger(0);

                try (java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) {
                    // 为每个模板创建一个异步任务
                    List<java.util.concurrent.CompletableFuture<Void>> futures = templateList.stream()
                            .map(template -> java.util.concurrent.CompletableFuture.runAsync(() -> {
                                try {
                                    generateSingleTemplate(scenicId, faceId, memberId, template, baseDynamicData);
                                    successCount.incrementAndGet();
                                } catch (Exception e) {
                                    log.error("拼图生成失败: scenicId={}, templateCode={}, templateName={}",
                                            scenicId, template.getCode(), template.getName(), e);
                                    failCount.incrementAndGet();
                                }
                            }, executor))
                            .toList();

                    // 等待所有任务完成
                    java.util.concurrent.CompletableFuture.allOf(futures.toArray(new java.util.concurrent.CompletableFuture[0])).join();
                }

                log.info("景区拼图模板批量生成完成: scenicId={}, 总数={}, 成功={}, 失败={}",
                        scenicId, templateList.size(), successCount.get(), failCount.get());

            } catch (Exception e) {
                // 异步任务失败不影响主流程，仅记录日志
                log.error("异步生成拼图模板失败: scenicId={}, faceId={}, e={}", scenicId, faceId, e.getMessage());
            }
        }, "PuzzleTemplateGenerator-" + scenicId + "-" + faceId).start();
    }

    /**
     * 构建基础动态数据
     */
    private Map<String, String> buildBaseDynamicData(Long faceId, String faceUrl, ScenicV2DTO scenicBasic) {
        Map<String, String> baseDynamicData = new HashMap<>();

        if (faceUrl != null) {
            baseDynamicData.put("faceImage", faceUrl);
            baseDynamicData.put("userAvatar", faceUrl);
        }

        baseDynamicData.put("faceId", String.valueOf(faceId));
        baseDynamicData.put("scenicName", scenicBasic.getName());
        baseDynamicData.put("scenicText", scenicBasic.getName());

        return baseDynamicData;
    }

    /**
     * 生成单个拼图模板
     */
    private void generateSingleTemplate(Long scenicId, Long faceId, Long memberId,
                                       PuzzleTemplateDTO template,
                                       Map<String, String> baseDynamicData) {
        log.info("开始生成拼图: scenicId={}, templateCode={}, templateName={}",
                scenicId, template.getCode(), template.getName());

        // 构建生成请求
        PuzzleGenerateRequest generateRequest = new PuzzleGenerateRequest();
        generateRequest.setScenicId(scenicId);
        generateRequest.setUserId(memberId);
        generateRequest.setFaceId(faceId);
        generateRequest.setBusinessType("face_matching");
        generateRequest.setTemplateCode(template.getCode());
        generateRequest.setOutputFormat("JPEG");
        generateRequest.setQuality(80);
        generateRequest.setDynamicData(new HashMap<>(baseDynamicData));
        generateRequest.setRequireRuleMatch(true);

        // 调用拼图生成服务
        PuzzleGenerateResponse response = puzzleGenerateService.generate(generateRequest);

        log.info("拼图生成成功: scenicId={}, templateCode={}, imageUrl={}",
                scenicId, template.getCode(), response.getImageUrl());
    }
}
