export type ModuleType = 
  | 'overview'
  | 'script' 
  | 'assets' 
  | 'storyboard';

export type AssetId = string;
export type StoryboardId = string;
export type EpisodeId = string;
export type ProjectId = string;

export interface GeneralCanvas {
  id: string;
  name: string;
  createdAt: string;  // ISO 8601 format
  updatedAt: string;  // ISO 8601 format
}

// Canvas Metadata Types
export type CanvasType = 'general' | 'asset' | 'storyboard';
export type RelatedEntityType = 'asset' | 'storyboard' | null;

export interface CanvasMetadata {
  id: string;
  projectId: string;
  canvasType: CanvasType;
  relatedEntityType: RelatedEntityType;
  relatedEntityId: string | null;
  name: string;
  description?: string;
  orderIndex: number;
  isPinned: boolean;
  tags: string[];
  nodeCount: number;
  lastAccessedAt?: string;  // ISO 8601 format
  accessCount: number;
  createdAt: string;  // ISO 8601 format
  updatedAt: string;  // ISO 8601 format
  deletedAt?: string;  // ISO 8601 format
}

export interface CreateGeneralCanvasRequest {
  name: string;
  description?: string;
}

export interface UpdateCanvasMetadataRequest {
  name?: string;
  description?: string;
  isPinned?: boolean;
  tags?: string[];
}

// Initialization Progress
export interface InitializationProgress {
  current_step: string;
  percentage: number;
  message: string;
  details?: Record<string, any>;
}

export interface ProjectData {
  id: ProjectId;
  name: string;
  description?: string;
  type: 'video' | 'comic' | 'canvas' | 'script';
  status: string;
  created_at: string;
  updated_at: string;
  resolution?: string;
  ratio?: string;
  styleId?: string;
  styleParams?: Record<string, any>;
  
  // Project-level model overrides (higher priority than system defaults)
  defaultImageModel?: string;
  defaultVideoModel?: string;
  defaultAudioModel?: string;
  defaultLyricsModel?: string;
  defaultLLMModel?: string;
  
  episodes: Episode[];
  assets: Asset[];
  storyboards: Storyboard[];
  generalCanvases: GeneralCanvas[];
  canvasMetadata?: CanvasMetadata[];
  chapters?: any[];
  
  // Initialization tracking
  progress?: InitializationProgress;
  error?: {
    message: string;
    type?: string;
  };
}

export interface Episode {
  id: EpisodeId;
  title: string;
  order: number;
  desc?: string;
  content?: string; // Full chapter content
  status: 'draft' | 'production' | 'completed';
}


// Generation History Types
export type GenerationStatus = 'pending' | 'processing' | 'success' | 'failed';

export interface BaseGenerationRecord {
  id: string; // UUID
  timestamp: number;
  status: GenerationStatus;
  model: string; // e.g., "flux-pro-1.1", "kling-1.5"
  prompt: string;
  resultUrl?: string; // The final image/video URL
  resultUrls?: string[]; // For batch generation
  error?: string;
}

export interface ImageGenerationParams {
  negativePrompt?: string;
  aspectRatio?: string; // e.g., "16:9"
  width?: number;
  height?: number;
  referenceImageUrls?: string[]; // Support multiple reference images (e.g. Midjourney, Vidu)
  styleId?: string;
  loras?: { name: string; strength: number }[]; // For SD/Flux
  modelConfig?: Record<string, any>; // Flexible bag for model-specific args (e.g. MJ parameters)
}

export interface ImageGenerationRecord extends BaseGenerationRecord {
  type: 'image';
  params: ImageGenerationParams;
}

export interface VideoGenerationParams {
  negativePrompt?: string;
  duration?: number; // seconds
  aspectRatio?: string;
  
  // Control Images/Videos
  imageUrls?: string[]; // Unified image input (e.g. [first_frame, last_frame])
  referenceImageUrls?: string[]; // For models that take general ref images
  referenceVideoUrls?: string[]; // For video-to-video (Wan 2.6)
  
  // Camera & Motion
  cameraMotion?: {
    type: 'zoom' | 'pan' | 'tilt' | 'roll' | 'static';
    direction?: 'in' | 'out' | 'left' | 'right' | 'up' | 'down' | 'cw' | 'ccw';
    speed?: number;
  };
  
  modelConfig?: Record<string, any>; // Flexible bag for model-specific args (e.g. Kling mode, Runway headers)
}

export interface VideoGenerationRecord extends BaseGenerationRecord {
  type: 'video';
  params: VideoGenerationParams;
}

export type GenerationRecord = ImageGenerationRecord | VideoGenerationRecord;

export interface Storyboard {
  id: StoryboardId;
  episodeId: EpisodeId; // Associated episode
  order: number; // Sequence order of the shot
  shot: string;
  desc: string;
  duration: string;
  type: string;
  sceneId?: AssetId;
  characterIds: AssetId[];
  propIds: AssetId[];
  
  // Production Details
  voiceover?: string;        // Dialogue or narration
  audioDesc?: string;        // Sound effects or background music description
  audioUrl?: string;         // Generated audio URL
  cameraMovement?: string;   // e.g., "Pan Left", "Zoom In"
  cameraAngle?: string;      // e.g., "High Angle", "Eye Level"
  lens?: string;             // e.g., "Wide Angle", "50mm"
  focus?: string;            // e.g., "Shallow Bokeh", "Deep Focus"
  lighting?: string;         // e.g., "Cinematic", "Natural"
  colorStyle?: string;       // e.g., "Cyberpunk", "Warm"
  transition?: string;       // e.g., "Cut", "Dissolve"
  
  // Context (from Agent)
  location?: string;         // Raw location name
  time?: string;            // Time of day
  
  // AI-Generated Prompts
  originalText?: string;     // Original novel text for this shot
  mergeImagePrompt?: string; // Integrated prompt for image generation (characters + scene + action)
  videoPrompt?: string;      // Motion and action prompt for video generation
  
  imageUrls?: string[];
  videoUrls?: string[];
  generations?: GenerationRecord[]; // Full history of generations
}

export type AssetType = 'character' | 'scene' | 'prop' | 'audio' | 'other';

export interface BaseAsset {
  id: AssetId;
  type: AssetType;
  name: string;
  desc: string;
  tags: string[];
  imageUrl?: string;
  imageUrls?: string[];
  videoUrls?: string[];
  audioUrl?: string; // Added for audio assets
  imagePrompt?: string; // AI-generated prompt for image generation
  generations?: GenerationRecord[]; // Full history of generations
}

export interface CharacterAsset extends BaseAsset {
  type: 'character';
  age?: string;
  gender?: string;
  role?: string;
  emotion?: string;
  appearance?: string;
}

export interface SceneAsset extends BaseAsset {
  type: 'scene';
  location?: string;
  environmentType?: string;
  timeOfDay?: string;
  weather?: string;
  atmosphere?: string;
}

export interface PropAsset extends BaseAsset {
  type: 'prop';
  usage?: string;
}

export interface OtherAsset extends BaseAsset {
  type: 'other';
}

export interface AudioAsset extends BaseAsset {
  type: 'audio';
  duration?: number;
}

export type Asset = CharacterAsset | SceneAsset | PropAsset | OtherAsset | AudioAsset;

export interface StyleConfig {
  id: string;
  name: string;
  type?: 'prompt' | 'lora';
  desc: string;
  imageUrl?: string;
  prompt?: string;
  lora?: {
    id: string;
    base_model: string;
    trigger_word?: string;
  };
  color?: string;
}

// --- API Request/Response Types ---

// Common
export interface BaseResponse<T> {
  code: string;
  message: string;
  data: T;
  meta?: {
    request_id?: string;
    timestamp?: string;
    api_version?: string;
    page?: number;
    page_size?: number;
    total?: number;
    total_pages?: number;
  };
}

// Project Management
export interface CreateProjectRequest {
  name: string;
  description?: string;
  type?: 'video' | 'comic' | 'canvas' | 'script';
}

export interface UpdateProjectRequest {
  name?: string;
  description?: string;
  resolution?: string;
  ratio?: string;
  styleId?: string;
  styleParams?: Record<string, any>;
  assets?: any[];
  chapters?: any[];
  generalCanvases?: GeneralCanvas[];
}

export interface ExportProjectRequest {
  project_id: string;
  format?: string;
}

export interface ExportResponse {
  project_id: string;
  video_url: string;
  status: string;
}

// Episode Management
export interface CreateEpisodeRequest {
  title: string;
  order: number;
  desc?: string;
  status?: 'draft' | 'production' | 'completed';
}

export interface UpdateEpisodeRequest {
  title?: string;
  order?: number;
  desc?: string;
  status?: 'draft' | 'production' | 'completed';
}

// Asset Management
export interface CreateAssetRequest {
  name: string;
  desc: string;
  tags: string[];
  type: AssetType;
  imageUrl?: string;
  imageUrls?: string[];
  imagePrompt?: string; // AI-generated prompt
  // Specific fields
  age?: string;
  role?: string;
  emotion?: string;
  appearance?: string;
  location?: string;
  environmentType?: string;
  timeOfDay?: string;
  weather?: string;
  atmosphere?: string;
  usage?: string;
}

export interface UpdateAssetRequest extends Partial<CreateAssetRequest> {
  generations?: GenerationRecord[];
}

// Storyboard Management
export interface CreateStoryboardRequest {
  episodeId: string;
  order: number;
  shot: string;
  desc: string;
  duration: string;
  type: string;
  sceneId?: string;
  characterIds?: string[];
  propIds?: string[];
  voiceover?: string;
  audioDesc?: string;
  audioUrl?: string;
  cameraMovement?: string;
  cameraAngle?: string;
  lens?: string;
  focus?: string;
  lighting?: string;
  colorStyle?: string;
  transition?: string;
  location?: string;
  time?: string;
  originalText?: string; // Original novel text
  mergeImagePrompt?: string; // Integrated image prompt
  videoPrompt?: string; // Video motion prompt
  imageUrls?: string[];
  videoUrls?: string[];
}

export interface UpdateStoryboardRequest extends Partial<CreateStoryboardRequest> {
  generations?: GenerationRecord[];
}

// Script Analysis
export interface ScriptProcessRequest {
  novel_text: string;
  project_id: string;
  model?: string;
  style_preset?: string;
  max_input_tokens?: number;
  skip_storyboard?: boolean;
  extraParams?: Record<string, any>;
}

export interface ScriptScene {
  scene_id: number;
  location: string;
  time: string;
  action: string;
  dialogue: string;
  camera_movement?: string;
  characters: string[];
}

export interface ScriptResponse {
  project_id: string;
  title: string;
  summary: string;
  chapters: Chapter[];
  characters: CharacterProfile[];
  scenes: SceneProfile[];
  props: PropProfile[];
  // Legacy
  scriptScenes?: ScriptScene[];
  characterList?: string[];
}

// Novel Summary
export interface NovelSummaryRequest {
  novel_text: string;
  language?: string;
  global_summary?: string;
  project_id?: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface NovelSummaryResponse {
  summary: string;
  title: string;
}

// Character Extraction
export interface CharacterExtractionRequest {
  novel_text: string;
  language?: string;
  global_summary?: string;
  known_characters?: Record<string, any>[];
  project_id?: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface CharacterProfile {
  name: string;
  desc?: string;
  age?: string;
  gender?: string;
  role?: string;
  emotion?: string;
  appearance?: string;
  tags?: string[];
  imagePrompt?: string; // AI-generated prompt for character image
}

export interface CharacterExtractionResponse {
  characters: CharacterProfile[];
}

// Scene Extraction
export interface SceneProfile {
  name: string;
  desc: string;
  location?: string;
  environmentType?: string;
  timeOfDay?: string;
  weather?: string;
  atmosphere?: string;
  tags?: string[];
  imagePrompt?: string; // AI-generated prompt for scene image
}

export interface SceneExtractionRequest {
  novel_text: string;
  language?: string;
  global_summary?: string;
  known_scenes?: Record<string, any>[];
  project_id?: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface SceneExtractionResponse {
  scenes: SceneProfile[];
}

// Prop Extraction
export interface PropProfile {
  name: string;
  desc: string;
  usage?: string;
  tags?: string[];
  imagePrompt?: string; // AI-generated prompt for prop image
}

export interface PropExtractionRequest {
  novel_text: string;
  language?: string;
  global_summary?: string;
  known_props?: Record<string, any>[];
  project_id?: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface PropExtractionResponse {
  props: PropProfile[];
}

// Chapter Split
export interface ChapterSplitRequest {
  novel_text: string;
  regex_pattern?: string;
}

export interface Chapter {
  title: string;
  content: string;
  word_count: number;
  summary?: string;
}

export interface ChapterSplitResponse {
  chapters: Chapter[];
  total_chapters: number;
}

// Prompt Optimization
export interface PromptOptimizationRequest {
  prompt: string;
  target_type?: 'image' | 'video';
  template?: string;
  model?: string;
  language?: string;
  extraParams?: Record<string, any>;
}

export interface PromptOptimizationResponse {
  original_prompt: string;
  optimized_prompt: string;
  target_type: 'image' | 'video';
}

// Style Recommendation
export interface StyleRecommendationRequest {
  novel_text: string;
  available_styles: string[];
  project_id?: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface StyleRecommendationResponse {
  recommended_style: string;
  reasoning: string;
}

// Image Generation
export interface ImageGenerationRequest {
  prompt: string;
  negativePrompt?: string;
  styleId?: string;
  model?: string;
  provider?: string;
  resolution?: string; // 统一使用 resolution 替代 dimension
  aspectRatio?: string;
  n?: number; // 一级参数
  imageInputs?: string[]; // 统一的图片输入
  loraStrength?: number; // 提升为一级参数
  source?: string; // 新增
  sourceId?: string; // 新增
  projectId?: string;
  extraParams?: Record<string, any>;
}

export interface GenerationResponse {
  task_id?: string;
  status?: string;
}

// Storyboard Split
export interface StoryboardSplitRequest {
  novel_text: string;
  projectId?: string;
  model?: string;
  language?: string;
  known_characters?: any[];
  known_scenes?: any[];
  known_props?: any[];
  extraParams?: Record<string, any>;
}

export interface StoryboardSplitItem {
  shot_number: number;
  shot_title: string;
  visual_description: string;
  dialogue?: string;
  duration?: string;
  shot_type?: string;
  camera_movement?: string;
  camera_angle?: string;
  lens?: string;
  focus?: string;
  lighting?: string;
  color_style?: string;
  transition?: string;
  audio_description?: string;
  character_list?: string[];
  location?: string;
  time_of_day?: string;
  original_text?: string; // Original novel text for this shot
  merge_image_prompt?: string; // Integrated prompt for image generation
  video_prompt?: string; // Motion and action prompt for video generation
}

export interface StoryboardSplitResponse {
  storyboards: StoryboardSplitItem[];
}

// Video Generation
export interface VideoGenerationRequest {
  imageInputs?: string[]; // 统一的图片输入
  videoInputs?: string[]; // 统一的视频输入
  audioInputs?: string[]; // 统一的音频输入
  prompt: string;
  negativePrompt?: string;
  shotType?: string;
  enableAudio?: boolean;
  cameraControl?: string;
  duration?: number;
  n?: number; // 提升为一级参数
  model: string;  // 复合 ID 格式: provider/model_key
  projectId?: string;
  source?: string; // 新增
  sourceId?: string; // 新增
  aspectRatio?: string;
  resolution?: string;
  extraParams?: Record<string, any>;
}

// Image Upscale
export interface UpscaleImageRequest {
  image_url: string;
  rate?: number;
  extraParams?: Record<string, any>;
}

export interface UpscaleImageResponse {
  original_url: string;
  upscaled_url: string;
}

// Audio Generation
export interface GenerateAudioRequest {
  text: string;
  voice?: string;
  storyboard_id: string;
  project_id: string;
  model?: string;
  extraParams?: Record<string, any>;
}

export interface AudioResponse {
  audio_url: string;
  task_id?: string;
}

// Task Status
export interface GenerationResult {
  url?: string;
  content?: string;
  orig_prompt?: string;
  actual_prompt?: string;
  usage?: Record<string, any>;
}

export interface OptionsConfig {
  character_roles: { zh: string[], en: string[] };
  character_genders: { zh: string[], en: string[] };
  shot_types: { zh: string[], en: string[] };
  camera_movements: { zh: string[], en: string[] };
  transitions: { zh: string[], en: string[] };
}

export interface TaskStatusResponse {
  id: string; // Task ID
  status: 'pending' | 'processing' | 'success' | 'failed';
  result?: {
    urls?: string[];
    [key: string]: any;
  };
  error?: string;
  meta?: Record<string, any>;
}

// Project List Response
export interface ProjectListResponse {
  data: {
    items: ProjectData[];
    pagination: {
      page: number;
      page_size: number;
      total: number;
      total_pages: number;
    };
  };
  meta?: {
    request_id?: string;
    timestamp?: string;
    api_version?: string;
  };
}

// Single Project Response
export interface ProjectResponse {
  data: ProjectData;
}

// Model Configuration
export interface ModelConfig {
  id: string;
  name: string;
  provider: string;
  provider_name?: string;
  type: 'llm' | 'image' | 'video' | 'audio';
  model_id: string;
  enabled: boolean;
  is_default?: boolean;
  capabilities?: {
    supportsRefImage?: boolean;
    supportsLora?: boolean;
    supportsFirstFrame?: boolean;
    supportsLastFrame?: boolean;
  };
  variants?: Record<string, string>;
  resolutions?: Record<string, string>;
  /** 
   * Duration config - two formats:
   * - Enumerated: { values: number[] }     e.g. { values: [5, 10] }
   * - Range:      { min: number, max: number } e.g. { min: 2, max: 15 }
   */
  durations?: { values?: number[]; min?: number; max?: number };
  /**
   * Count config for generation quantity.
   * Example: { min: 1, max: 4 }.
   */
  counts?: { min?: number; max?: number; values?: number[] };
  /** Voice options for audio models (OpenAI format) */
  voices?: Array<{ id: string; name: string; gender?: string; desc?: string }>;
  args?: any[];
  family?: string;
}

// Models List Response
export interface ModelsListResponse {
  models: ModelConfig[];
}
