package com.yaoai.api.dto.ai;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yaoai.domain.entity.AiTask;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Data
public class AiTaskDTO {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private static final TypeReference<List<String>> LIST_STRING_TYPE = new TypeReference<>() {};
    private static final TypeReference<Map<String, String>> MAP_STRING_TYPE = new TypeReference<>() {};

    private Long id;
    private Long projectId;
    private Long episodeId;
    private Long storyboardId;
    private String taskType;
    private String status;
    private String resultVideoUrl;
    private String errorMessage;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

    /** 系统拼接后提交给 Seedance 的最终 Prompt（含 @图N） */
    private String prompt;

    /** 结构化字段：仅 task_type=structured_video 时非空 */
    private String characterImageKey;
    /** V16：多角色出镜列表（优先于 characterImageKey） */
    private List<String> characterImageKeys;
    private String sceneImageKey;
    private List<String> propImageKeys;
    private String styleImageKey;
    /** 用户原始结构化输入 */
    private Map<String, String> userPrompt;
    private Integer videoDuration;
    private String videoRatio;
    private Boolean generateAudio;

    public static AiTaskDTO from(AiTask t) {
        AiTaskDTO dto = new AiTaskDTO();
        dto.setId(t.getId());
        dto.setProjectId(t.getProjectId());
        dto.setEpisodeId(t.getEpisodeId());
        dto.setStoryboardId(t.getStoryboardId());
        dto.setTaskType(t.getTaskType());
        dto.setStatus(t.getStatus());
        dto.setResultVideoUrl(t.getResultVideoUrl());
        dto.setErrorMessage(t.getErrorMessage());
        dto.setCreatedAt(t.getCreatedAt());
        dto.setUpdatedAt(t.getUpdatedAt());
        dto.setPrompt(t.getPrompt());

        dto.setCharacterImageKey(t.getCharacterImageKey());
        dto.setSceneImageKey(t.getSceneImageKey());
        dto.setStyleImageKey(t.getStyleImageKey());
        dto.setVideoDuration(t.getVideoDuration());
        dto.setVideoRatio(t.getVideoRatio());
        dto.setGenerateAudio(t.getGenerateAudio());

        dto.setPropImageKeys(parseList(t.getPropImageKeys(), "propImageKeys", t.getId()));
        dto.setCharacterImageKeys(parseList(t.getCharacterImageKeys(), "characterImageKeys", t.getId()));
        dto.setUserPrompt(parseMap(t.getUserPrompt(), "userPrompt", t.getId()));

        return dto;
    }

    private static List<String> parseList(String json, String fieldName, Long taskId) {
        if (json == null || json.isBlank()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(json, LIST_STRING_TYPE);
        } catch (Exception e) {
            log.warn("Failed to parse {} for task {}: {}", fieldName, taskId, e.getMessage());
            return null;
        }
    }

    private static Map<String, String> parseMap(String json, String fieldName, Long taskId) {
        if (json == null || json.isBlank()) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(json, MAP_STRING_TYPE);
        } catch (Exception e) {
            log.warn("Failed to parse {} for task {}: {}", fieldName, taskId, e.getMessage());
            return null;
        }
    }
}
