/**
 * AI Comic Creator - TypeScript Type Definitions
 * 
 * Based on the specification document (comic-creator-app-instruction.md)
 */

// ============================================================================
// Core Enums and Types
// ============================================================================

export type UserMode = 'casual' | 'professional';

export type WorkflowStep =
  | 'story-input'
  | 'generating-script'
  | 'script-review'
  | 'character-setup'
  | 'generating-panels'
  | 'layout'
  | 'speech-bubbles'
  | 'complete';

export type ExportFormat = 'pdf' | 'cbz' | 'png';
export type PageSizeName = 'a4' | 'letter' | 'manga' | 'webtoon' | 'square';
export type ColorProfile = 'rgb' | 'cmyk';

export type ShotType = 
  | 'establishing' 
  | 'wide' 
  | 'medium' 
  | 'close-up' 
  | 'extreme-close-up' 
  | 'over-shoulder' 
  | 'aerial';

export type LayoutType = 'grid' | 'manga' | 'western' | 'action' | 'dialogue' | 'splash';

export type BubbleType = 'normal' | 'thought' | 'shout' | 'whisper' | 'narration' | 'sound-effect';

export type CharacterRole = 'protagonist' | 'antagonist' | 'supporting' | 'extra';

export type Emotion = 'happy' | 'sad' | 'angry' | 'surprised' | 'neutral' | 'determined';

export type TransitionType = 'none' | 'fade' | 'wipe' | 'dissolve' | 'action-lines';

// ============================================================================
// Character Types
// ============================================================================

export interface CharacterPromptTemplate {
  age: string;
  gender: string;
  hairColor: string;
  hairStyle: string;
  skinTone: string;
  eyeColor: string;
  bodyType: string;
  outfit: string;
  accessories: string;
  distinguishingFeatures: string;
}

export interface ColorPalette {
  hair: string;
  eyes: string;
  skin: string;
  outfit: string;
}

export interface Character {
  id: string;
  name: string;
  role: CharacterRole;
  description: string;
  promptTemplate: CharacterPromptTemplate;
  referenceImageUrl: string;
  characterSheetUrls: string[];
  seed: number;
  colorPalette: ColorPalette;
  appearanceCount: number;
  firstAppearancePanel?: string;
}

// ============================================================================
// Dialogue Types
// ============================================================================

export interface Dialogue {
  speakerId: string;
  text: string;
  bubbleType: Exclude<BubbleType, 'narration' | 'sound-effect'>;
  emotion: Emotion;
}

// ============================================================================
// Panel Types
// ============================================================================

export interface Panel {
  panelId: string;
  panelNumber: number;
  shotType: ShotType;
  description: string;
  charactersPresent: string[];
  dialogue: Dialogue[];
  caption?: string;
  soundEffects: string[];
  transitionFromPrevious: TransitionType;
}

export interface PanelImage {
  url: string;
  width: number;
  height: number;
  seed: number;
  prompt: string;
}

export interface Position {
  x: number;
  y: number;
}

export interface Size {
  width: number;
  height: number;
}

export interface LayoutCell {
  x: number;
  y: number;
  w: number;
  h: number;
  type: 'panel' | 'gutter';
}

// ============================================================================
// Page Types
// ============================================================================

export interface Page {
  pageNumber: number;
  layoutType: LayoutType;
  panels: Panel[];
}

export interface PageLayout {
  pageNumber: number;
  patternId: string;
  pattern: LayoutPattern;
  panels: Array<{ panelId: string; panelNumber: number; layoutCell: LayoutCell }>;
  width: number;
  height: number;
}

export interface PageSize {
  name: string;
  width: number;
  height: number;
  dpi: number;
  unit: string;
}

// ============================================================================
// Script Types
// ============================================================================

export interface ComicScript {
  title: string;
  synopsis: string;
  characters: Character[];
  pages: Page[];
}

// ============================================================================
// Speech Bubble Types
// ============================================================================

export interface BubbleStyle {
  backgroundColor: string;
  borderColor: string;
  borderWidth: number;
  borderRadius: number;
  fontFamily: string;
  fontSize: number;
  textColor: string;
  padding: number;
}

export interface SpeechBubble {
  id: string;
  panelId: string;
  type: BubbleType;
  text: string;
  position: Position;
  size: Size;
  tailDirection: 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
  tailTarget: Position;
  style: BubbleStyle;
  speakerId: string;
}

// ============================================================================
// Store State Types
// ============================================================================

export interface WorkflowState {
  currentStep: WorkflowStep;
  completedSteps: WorkflowStep[];
  isGenerating: boolean;
  generationProgress: number;
  error: string | null;
}

export interface ComicProject {
  projectId: string;
  projectName: string;
  createdAt: string;
  lastModified: string;
}

export interface ComicStore {
  // ─── Project ───
  project: ComicProject;
  
  // ─── User Mode ───
  userMode: UserMode;
  
  // ─── Story ───
  storyIdea: string;
  storyGenre: string;
  targetAudience: string;
  artStyle: string;
  
  // ─── Script (generated by DeepSeek) ───
  script: ComicScript | null;
  
  // ─── Characters (with consistency data) ───
  characters: Character[];
  
  // ─── Generated Assets ───
  panelImages: Record<string, PanelImage>;
  characterRefImages: Record<string, string>;
  
  // ─── Layout ───
  pageLayouts: PageLayout[];
  
  // ─── Speech Bubbles ───
  speechBubbles: Record<string, SpeechBubble[]>;
  
  // ─── Export Settings ───
  exportFormat: ExportFormat;
  pageSize: PageSizeName;
  colorProfile: ColorProfile;
  
  // ─── Workflow ───
  workflow: WorkflowState;
  
  // ─── Actions ───
  setUserMode: (mode: UserMode) => void;
  setStoryIdea: (idea: string) => void;
  setStoryGenre: (genre: string) => void;
  setTargetAudience: (audience: string) => void;
  setArtStyle: (style: string) => void;
  setScript: (script: ComicScript | null) => void;
  setCharacters: (characters: Character[]) => void;
  setPanelImage: (panelId: string, image: PanelImage) => void;
  setCharacterRefImage: (characterId: string, url: string) => void;
  setPageLayouts: (layouts: PageLayout[]) => void;
  setSpeechBubbles: (panelId: string, bubbles: SpeechBubble[]) => void;
  setExportFormat: (format: ExportFormat) => void;
  setPageSize: (size: PageSizeName) => void;
  setWorkflowStep: (step: WorkflowStep) => void;
  setWorkflowError: (error: string | null) => void;
  setGenerationProgress: (progress: number) => void;
  resetProject: () => void;
}

// ============================================================================
// Layout Pattern Types
// ============================================================================

export interface LayoutPattern {
  id: string;
  name: string;
  description: string;
  genre: string[];
  maxPanels: number;
  cells: LayoutCell[];
}

// ============================================================================
// Art Style Types
// ============================================================================

export type ArtStyleKey = 'manga' | 'western-comic' | 'pixel-art' | 'watercolor' | 'noir' | 'chibi' | 'sketch' | 'cyberpunk';

export interface ArtStyle {
  key: ArtStyleKey;
  name: string;
  keywords: string;
}

// ============================================================================
// Community Types
// ============================================================================

export interface PublishMetadata {
  title: string;
  description: string;
  tags: string[];
  visibility: 'public' | 'unlisted';
}

export interface PublishedComic {
  id: string;
  projectId: string;
  title: string;
  author: string;
  coverImage: string;
  genre: string;
  likes: number;
  comments: number;
  createdAt: string;
  metadata: PublishMetadata;
}

// ============================================================================
// API Types
// ============================================================================

export interface DeepSeekConfig {
  apiKey: string;
  baseURL: string;
}

export interface FalAiConfig {
  credentials: string;
}

export interface GenerateScriptOptions {
  storyIdea: string;
  genre: string;
  artStyle: string;
  numPages: number;
  audience: string;
}

export interface GeneratePanelOptions {
  panel: Panel;
  characters: Character[];
  artStyle: string;
  referenceImages?: string[];
}

// ============================================================================
// Error Types
// ============================================================================

export interface ComicError extends Error {
  code: string;
  recoverable: boolean;
}

export function createComicError(
  message: string,
  code: string,
  recoverable: boolean = false
): ComicError {
  const error = new Error(message) as ComicError;
  error.name = 'ComicError';
  error.code = code;
  error.recoverable = recoverable;
  return error;
}

export function createRateLimitError(message: string = 'Rate limit exceeded'): ComicError {
  return createComicError(message, 'RATE_LIMIT', true);
}

export function createContentPolicyError(message: string = 'Content violates policy'): ComicError {
  return createComicError(message, 'CONTENT_POLICY', false);
}

export function createGenerationError(message: string = 'Generation failed'): ComicError {
  return createComicError(message, 'GENERATION_FAILED', true);
}
