package com.yaoai.api.controller;

import com.yaoai.api.dto.ai.EpisodeDTO;
import com.yaoai.api.dto.ai.OutlineDTO;
import com.yaoai.common.exception.BizException;
import com.yaoai.common.exception.ErrorCode;
import com.yaoai.common.response.ApiResponse;
import com.yaoai.domain.entity.Episode;
import com.yaoai.domain.entity.Outline;
import com.yaoai.domain.mapper.StoryboardMapper;
import com.yaoai.pipeline.service.OutlinePipelineService;
import com.yaoai.security.context.TenantContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Tag(name = "AI 大纲 & 分集")
@RestController
@RequestMapping("/projects/{projectId}")
@RequiredArgsConstructor
public class OutlineController {

    private final OutlinePipelineService outlinePipelineService;
    private final StoryboardMapper storyboardMapper;

    @Operation(summary = "生成大纲（传入剧本文本）")
    @PostMapping("/outline/generate")
    public ApiResponse<OutlineDTO> generateOutline(@PathVariable Long projectId,
                                                   @RequestBody Map<String, String> body) {
        String scriptContent = body.get("script");
        if (scriptContent == null || scriptContent.isBlank()) {
            throw new BizException(ErrorCode.INVALID_PARAM, "script 不能为空");
        }
        Long tenantId = TenantContext.get();
        Outline outline = outlinePipelineService.generateOutline(projectId, tenantId, scriptContent);
        return ApiResponse.success(OutlineDTO.from(outline));
    }

    @Operation(summary = "获取项目大纲")
    @GetMapping("/outline")
    public ApiResponse<OutlineDTO> getOutline(@PathVariable Long projectId) {
        Long tenantId = TenantContext.get();
        Outline outline = outlinePipelineService.getOutline(projectId, tenantId);
        if (outline == null) {
            throw new BizException(ErrorCode.NOT_FOUND, "大纲不存在，请先生成");
        }
        return ApiResponse.success(OutlineDTO.from(outline));
    }

    @Operation(summary = "编辑项目大纲")
    @PutMapping("/outline")
    public ApiResponse<OutlineDTO> updateOutline(@PathVariable Long projectId,
                                                 @RequestBody Outline req) {
        Long tenantId = TenantContext.get();
        Outline outline = outlinePipelineService.updateOutline(projectId, tenantId, req);
        return ApiResponse.success(OutlineDTO.from(outline));
    }

    @Operation(summary = "生成分集内容（使用最新大纲）")
    @PostMapping("/episodes/generate")
    public ApiResponse<List<EpisodeDTO>> generateEpisodes(@PathVariable Long projectId) {
        Long tenantId = TenantContext.get();
        Outline outline = outlinePipelineService.getOutline(projectId, tenantId);
        if (outline == null) {
            throw new BizException(ErrorCode.NOT_FOUND, "大纲不存在，请先生成大纲");
        }
        return ApiResponse.success(
                outlinePipelineService.generateEpisodes(outline.getId(), projectId, tenantId)
                        .stream().map(EpisodeDTO::from).collect(Collectors.toList())
        );
    }

    @Operation(summary = "生成分集内容（指定大纲ID）")
    @PostMapping("/outline/{outlineId}/episodes/generate")
    public ApiResponse<List<EpisodeDTO>> generateEpisodesByOutlineId(@PathVariable Long projectId,
                                                          @PathVariable Long outlineId) {
        Long tenantId = TenantContext.get();
        return ApiResponse.success(
                outlinePipelineService.generateEpisodes(outlineId, projectId, tenantId)
                        .stream().map(EpisodeDTO::from).collect(Collectors.toList())
        );
    }

    @Operation(summary = "获取项目分集列表")
    @GetMapping("/episodes")
    public ApiResponse<List<EpisodeDTO>> listEpisodes(@PathVariable Long projectId) {
        Long tenantId = TenantContext.get();
        return ApiResponse.success(
                outlinePipelineService.getEpisodes(projectId, tenantId)
                        .stream()
                        .map(e -> EpisodeDTO.from(e, storyboardMapper.countByEpisode(e.getId(), tenantId)))
                        .collect(Collectors.toList())
        );
    }

    @Operation(summary = "手动新增一集")
    @PostMapping("/episodes")
    public ApiResponse<EpisodeDTO> createEpisode(@PathVariable Long projectId,
                                                 @RequestBody Episode req) {
        Long tenantId = TenantContext.get();
        Episode ep = outlinePipelineService.createEpisode(projectId, tenantId, req);
        return ApiResponse.success(EpisodeDTO.from(ep, 0));
    }

    @Operation(summary = "编辑单集（episodeNumber/title/summary/script）")
    @PutMapping("/episodes/{episodeId}")
    public ApiResponse<EpisodeDTO> updateEpisode(@PathVariable Long projectId,
                                                  @PathVariable Long episodeId,
                                                  @RequestBody Episode req) {
        Long tenantId = TenantContext.get();
        Episode ep = outlinePipelineService.updateEpisode(projectId, tenantId, episodeId, req);
        return ApiResponse.success(EpisodeDTO.from(ep, storyboardMapper.countByEpisode(ep.getId(), tenantId)));
    }
}
