export type GenSession = {
  id: string;
  createdAt: number;
  prompt: string;
  refImages: string[];
  count: number;
  images: GenImage[];
  inputMode?: ProjectInputMode;
  uploadedImages?: UploadedImage[];
  preFilledSlots?: PreFilledSlot[];
  characterSpec?: CharacterSpec;
  packs?: AssetPack[];
  exports?: ExportManifest[];
};

export type GenImage = {
  id: string;
  url: string;
  prompt: string;
  status: 'pending' | 'selected' | 'rejected';
  meta?: Record<string, unknown>;
};

export type GenerateRequest = {
  prompt: string;
  refImages?: string[];
  count: number;
  style?: string;
};

export type GenerateResponse = {
  sessionId: string;
  images: GenImage[];
  provider: 'mock' | 'gpt';
};

export type ProjectInputMode = 'idea' | 'remix' | 'replicate' | 'extend';

export type UploadedImageRole =
  | 'reference'
  | 'subject'
  | 'view-front'
  | 'view-back'
  | 'view-left'
  | 'view-right'
  | 'view-top'
  | 'view-bottom'
  | 'accessory-isolated'
  | 'accessory-named';

export type UploadedImage = {
  id: string;
  url: string;
  filename: string;
  originalFilename?: string;
  mimeType: string;
  uploadedAt: number;
  role: UploadedImageRole;
  accessoryName?: string;
  needsCleanup: boolean;
};

export type PreFilledSlot = {
  uploadedImageId: string;
  templateId: string;
  role: UploadedImageRole;
  url: string;
};

export type PackKind = 'patent' | 'production' | 'marketing' | 'accessories';

export type AssetStatus = 'draft' | 'selected' | 'needs_regen' | 'approved' | 'exported';

export type CharacterSpec = {
  name: string;
  oneLiner: string;
  targetUser: string;
  speciesShape: string;
  bodyRatio: string;
  faceFeatures: string;
  colorPalette: string[];
  materials: string[];
  accessories: string[];
  signatureElements: string[];
  manufacturingNotes: string[];
  patentFocus: string[];
  marketingAngle: string[];
  negativePrompt: string;
  sourceImageId?: string;
  sourceImageUrl?: string;
  cleanReferenceImageUrl?: string;
  lockedAt: number;
};

export type AssetTemplate = {
  id: string;
  kind: PackKind;
  view: string;
  title: string;
  description: string;
  required: boolean;
  aspectRatio: '1:1' | '3:4' | '4:5' | '9:16' | '16:9' | 'long';
  filenamePart: string;
  promptTemplate: string;
  checklist: string[];
  anchorTemplateId?: string;
};

export type TextTemplate = {
  id: string;
  kind: PackKind | 'video' | 'project';
  title: string;
  description: string;
  required: boolean;
  outputFormat: 'paragraph' | 'bullets' | 'table' | 'script' | 'json';
  filenamePart: string;
  promptTemplate: string;
  checklist: string[];
};

export type ToyAsset = {
  id: string;
  templateId: string;
  kind: PackKind;
  view: string;
  title: string;
  description: string;
  url: string;
  prompt: string;
  status: AssetStatus;
  version: string;
  aspectRatio: AssetTemplate['aspectRatio'];
  required: boolean;
  createdAt: number;
  anchorAssetId?: string;
  anchorImageUrl?: string;
  derivationLevel: 0 | 1 | 2 | 3;
  meta?: Record<string, unknown>;
};

export type AssetPack = {
  id: string;
  kind: PackKind;
  sessionId: string;
  sourceImageId: string;
  sourceImageUrl: string;
  characterSpec: CharacterSpec;
  assets: ToyAsset[];
  manifestId: string;
  createdAt: number;
  version: string;
  status: 'draft' | 'complete';
};

export type ExportManifest = {
  id: string;
  sessionId: string;
  packId: string;
  packKind: PackKind;
  version: string;
  createdAt: number;
  filenameSchema: string;
  templateFreezeVersion: string;
  source: {
    prompt: string;
    sourceImageId: string;
    sourceImageUrl: string;
  };
  characterSpec: CharacterSpec;
  files: Array<{
    assetId: string;
    templateId: string;
    filename: string;
    url: string;
    kind: PackKind;
    view: string;
    title: string;
    required: boolean;
    aspectRatio: AssetTemplate['aspectRatio'];
    prompt: string;
    anchorAssetId?: string;
    anchorImageUrl?: string;
    derivationLevel?: 0 | 1 | 2 | 3;
    checklist: string[];
  }>;
  exportTargets: Array<'zip' | 'pdf' | 'manifest-json'>;
};

export type GeneratePackRequest = {
  sessionId: string;
  imageId: string;
  kind: PackKind;
  background?: boolean;
};

export type GeneratePackResponse = {
  pack: AssetPack;
  manifest: ExportManifest;
  provider: 'mock' | 'gpt';
};

export type GenerateAllPacksRequest = {
  sessionId: string;
  imageId: string;
  background?: boolean;
};

export type GenerateAllPacksResponse = {
  packs: AssetPack[];
  manifests: ExportManifest[];
  provider: 'mock' | 'gpt';
};

export type LockCharacterRequest = {
  sessionId: string;
  imageId: string;
  force?: boolean;
};

export type LockCharacterResponse = {
  characterSpec: CharacterSpec;
  provider: 'mock' | 'gpt';
};

export type CleanupCharacterRequest = {
  sessionId: string;
  imageId: string;
  force?: boolean;
  preserveLevel?: 'normal' | 'strict';
};

export type CleanupCharacterResponse = {
  characterSpec: CharacterSpec;
  cleanReferenceImageUrl: string;
  provider: 'mock' | 'gpt';
};

export type UploadImageResponse = {
  uploadedImage: UploadedImage;
};

export type ProjectFromUploadRequest = {
  uploadedImages: UploadedImage[];
  mode: 'remix' | 'replicate' | 'extend';
  remixPrompt?: string;
  userHint?: string;
  styleId?: string;
  count?: number;
};

export type ProjectFromUploadResponse = {
  sessionId: string;
  images?: GenImage[];
  characterSpec?: CharacterSpec;
  l1AnchorUrl?: string;
  preFilledSlots?: PreFilledSlot[];
  provider: 'mock' | 'gpt';
};

export type LockCharacterFromUploadRequest = {
  sessionId: string;
  subjectImageId: string;
  userHint?: string;
  force?: boolean;
};

export type RegenerateAssetRequest = {
  sessionId: string;
  userRefinement?: string;
  confirmCost?: boolean;
};

export type RegenerateAssetResponse = {
  asset: ToyAsset;
  pack: AssetPack;
  provider: 'mock' | 'gpt';
};

export type VideoGenerationRequest = {
  prompt: string;
  imageUrl?: string;
  references?: Array<{
    type: 'image_url' | 'video_url' | 'audio_url';
    url: string;
    role?: 'reference_image' | 'reference_video' | 'reference_audio';
  }>;
  duration?: number;
  ratio?: '16:9' | '9:16' | '1:1' | '4:3' | '3:4';
  resolution?: '720p' | '1080p';
  generateAudio?: boolean;
  watermark?: boolean;
};

export type VideoGenerationResponse = {
  provider: 'seedance';
  model: string;
  taskId?: string;
  status: 'submitted' | 'processing' | 'succeeded' | 'failed';
  videoUrl?: string;
  raw?: unknown;
};
