export type JobStatus =
  | "created"
  | "ingesting"
  | "ai_processing"
  | "pending_qc"
  | "approved_english"
  | "approved_source"  // For non-English source videos
  | "rejected"
  | "qc_feedback"
  | "translating"
  | "tts_generating"
  | "tts_failed"  // legacy: keep for back-compat
  | "rendering_video"  // Accessible video rendering in progress
  | "render_failed"  // legacy: keep for back-compat
  | "rendering_qc"  // Re-rendering accessible video during QC review
  | "processing_failed"  // unified failure; see job.failure for step details
  | "pending_final_review"
  | "completed";

export type UserRole = "client" | "reviewer" | "linguist" | "production" | "project_manager" | "admin";
export type AuthProvider = "local" | "microsoft";

export interface User {
  id: string;
  email: string;
  full_name: string;
  role: UserRole;
  auth_provider: AuthProvider;
  is_active: boolean;
  created_at: string;
  pm_client_ids?: string[];
  languages?: string[];  // BCP-47 codes the user is competent in (R-8)
}

export interface Source {
  filename: string;
  original_filename?: string;
  client_name?: string;
  video_gcs?: string;
  gcs_uri: string;
  duration_s?: number;
  language: string;  // Final source language (from detection or explicit)
  language_hint?: string;  // User-provided hint for non-English videos
  detected_language?: string;  // AI-detected language from Gemini
}

export type TTSProvider = "gemini" | "google" | "elevenlabs";
export type TTSModel = "flash" | "pro";
export type TTSStylePreset = "neutral" | "calm" | "energetic" | "professional" | "warm" | "documentary" | "custom";

export type TranslationMode = "traditional";

export interface TTSPreferences {
  provider: TTSProvider;
  default_voice: string;
  voices_per_language: Record<string, string>;
  model: TTSModel;
  speed: number;
  style_preset: TTSStylePreset;
  custom_style_prompt?: string;
  // ElevenLabs-specific settings
  stability?: number;
  similarity_boost?: number;
}

export interface RequestedOutputs {
  captions_vtt: boolean;
  audio_description_vtt: boolean;
  audio_description_mp3: boolean;
  accessible_video_mp4: boolean;  // Rendered video with embedded audio descriptions
  accessible_video_method?: AccessibleVideoMethod;  // User-selected method for accessible video
  sdh_vtt?: boolean;  // SDH captions with speaker labels, sound effects, music notation
  descriptive_transcript?: boolean;  // WCAG-compliant combined speech+description transcript
  languages: string[];
  transcreation: string[];
  tts_preferences?: TTSPreferences;
  translation_mode?: TranslationMode;
}

export interface VoiceInfo {
  id: string;
  name: string;
  description?: string;
  preview_url?: string;
  labels?: Record<string, string>;
  category?: string;
}

export interface ProviderVoicesResponse {
  provider: string;
  voices: VoiceInfo[];
  default: string;
  available?: boolean;
  error?: string;
}

export interface LanguagesResponse {
  languages: Record<string, string>;
  preview_samples: Record<string, string>;
}

export interface TTSOptionItem {
  value: string;
  label: string;
}

export interface SpeedRange {
  min: number;
  max: number;
  default: number;
  step: number;
}

export interface FloatRange {
  min: number;
  max: number;
  default: number;
  step: number;
}

export interface ProviderOptionsResponse {
  provider: string;
  // Gemini-specific
  models?: TTSOptionItem[];
  style_presets?: TTSOptionItem[];
  speed_range?: SpeedRange;
  // ElevenLabs-specific
  stability_range?: FloatRange;
  similarity_boost_range?: FloatRange;
}

export type AccessibleVideoMethod = "overlay" | "pause_insert";

export interface LangOutput {
  captions_vtt_gcs?: string;
  ad_vtt_gcs?: string;
  ad_mp3_gcs?: string;
  // Accessible video outputs
  accessible_video_gcs?: string;
  accessible_video_method?: AccessibleVideoMethod;
  retimed_captions_vtt_gcs?: string;  // Re-timed captions for pause-insert method
  ad_cues_gcs_prefix?: string;  // Path prefix for per-cue MP3 segments
  origin?: "translate" | "transcreate" | "gemini_translate" | "video_native";
  qa_notes?: string;
}

export interface ReviewHistoryItem {
  at: string;
  status: string;
  by?: string;
  notes?: string;
}

export interface Review {
  notes?: string;
  reviewer_id?: string;
  history: ReviewHistoryItem[];
}

export interface AISection {
  ingestion_json?: Record<string, unknown>;
  confidence?: number;
}

export type AccessibleVideoProgressStatus = "pending" | "rendering" | "completed" | "failed";

export interface AccessibleVideoProgressItem {
  status: AccessibleVideoProgressStatus;
  method?: AccessibleVideoMethod;
  error_message?: string;
  started_at?: string;
  completed_at?: string;
}

export interface TTSRewriteItem {
  language: string;
  cue_index: number;
  original_text: string;
  rewritten_text: string;
  timestamp: string;
}

// ── Per-language QC types ─────────────────────────────────────────────────────

export type LanguageQCStatus =
  | 'pending'
  | 'in_progress'
  | 'pending_review'
  | 'in_review'
  | 'approved'
  | 'rejected';

export interface LanguageQCEvent {
  at: string;
  actor_user_id: string;
  actor_email: string;
  action:
    | 'assign' | 'reassign'
    | 'reviewer_assigned' | 'reviewer_reassigned'
    | 'start_work' | 'submit_for_review' | 'open_review'
    | 'approve' | 'reject' | 'reopen'
    | 'comment_added';
  notes?: string;
  previous_assignee_id?: string;
}

export interface LanguageQCComment {
  id: string;
  author_id: string;
  author_name: string;
  author_email: string;
  body: string;
  created_at: string;
}

export interface LanguageQCState {
  status: LanguageQCStatus;
  // Linguist slot
  assigned_linguist_id?: string;
  assigned_linguist_email?: string;
  assigned_linguist_name?: string;
  assigned_at?: string;
  assigned_by_user_id?: string;
  submitted_for_review_at?: string;
  linguist_deadline?: string;
  // Reviewer slot
  assigned_reviewer_id?: string;
  assigned_reviewer_email?: string;
  assigned_reviewer_name?: string;
  assigned_reviewer_at?: string;
  review_started_at?: string;
  reviewer_deadline?: string;
  // Reviewer progress
  total_cues?: number;
  reviewed_cues?: number;
  // Outcome
  reviewed_at?: string;
  reviewed_by_user_id?: string;
  reviewed_by_email?: string;
  notes?: string;
  reject_category?: string;
  history: LanguageQCEvent[];
  comments: LanguageQCComment[];
}

export interface LanguageQCMapResponse {
  job_id: string;
  language_qc: Record<string, LanguageQCState>;
}

export interface LanguageQCStateResponse {
  lang: string;
  state: LanguageQCState;
}

export interface QueueItem {
  job_id: string;
  job_title: string;
  job_status: string;
  lang: string;
  lang_qc_status: LanguageQCStatus;
  assigned_at?: string;
  reviewed_at?: string;
}

export interface QueueResponse {
  items: QueueItem[];
  total: number;
}

export interface JobFailure {
  step: "ingestion" | "ai_processing" | "translation" | "tts" | "render";
  type: string;
  message: string;
  retriable: boolean;
  occurred_at: string;
  retry_count: number;
}

export interface Job {
  id: string;
  client_id: string;
  title: string;
  source: Source;
  requested_outputs: RequestedOutputs;
  status: JobStatus;
  review: Review;
  outputs?: Record<string, LangOutput>;
  accessible_video_progress?: Record<string, AccessibleVideoProgressItem>;
  ai?: AISection;
  error?: Record<string, unknown>;
  failure?: JobFailure;
  retry_count?: number;
  tts_rewrites?: TTSRewriteItem[];
  project_id?: string;
  cost_tracker_project_id?: string;
  language_qc?: Record<string, LanguageQCState>;
  deadline?: string;
  created_at: string;
  updated_at: string;
  created_by_name?: string;
}

export interface LoginRequest {
  email: string;
  password: string;
}

export interface LoginResponse {
  access_token: string;
  token_type: string;
  user_id: string;
  role: string;
}

export interface RefreshResponse {
  access_token: string;
  token_type: string;
  user_id: string;
  role: string;
  email: string;
  full_name: string;
}

export interface MicrosoftLoginRequest {
  id_token: string;
}

export interface MicrosoftLoginResponse {
  access_token: string;
  token_type: string;
  user_id: string;
  role: string;
  email: string;
  full_name: string;
  auth_provider: AuthProvider;
}

export interface JobCreateRequest {
  title: string;
  requested_outputs: RequestedOutputs;
  brand_context?: string;
  project_id?: string;
  brief_id?: string;
  deadline?: string;
  initial_linguist_id?: string;
  initial_reviewer_id?: string;
}

export interface JobListResponse {
  jobs: Job[];
  total: number;
  page: number;
  size: number;
}

export interface JobDownloadsResponse {
  downloads: Record<string, Record<string, string> | string>;
}

export interface VttContentResponse {
  captions_vtt?: string;
  audio_description_vtt?: string;
  retimed_captions_vtt?: string;  // Re-timed captions for accessible videos
  etag?: string;  // SHA1 hash for optimistic locking
}

export interface VttUpdateRequest {
  captions_vtt?: string;
  audio_description_vtt?: string;
  language?: string;  // If not specified, defaults to source language
  if_match?: string;  // Optimistic locking — etag from last GET
  retranslate_languages?: boolean;
}

export interface AssetValidationResponse {
  is_valid: boolean;
  errors: string[];
  warnings: string[];
}

export interface BulkDeleteRequest {
  job_ids: string[];
}

export interface BulkDeleteResponse {
  deleted_count: number;
  total_requested: number;
  errors: string[];
}

export interface ApproveSourceRequest {
  notes?: string;
  tts_preferences?: TTSPreferences;
  accessible_video_method?: AccessibleVideoMethod;
}

export interface BulkApproveRequest {
  job_ids: string[];
  notes?: string;
  accessible_video_method?: AccessibleVideoMethod;
  tts_preferences?: TTSPreferences;
}

export interface BulkApproveResponse {
  approved_count: number;
  total_requested: number;
  errors: string[];
}

export interface BulkReturnToQCRequest {
  job_ids: string[];
  notes: string;
}

export interface BulkReturnToQCResponse {
  returned_count: number;
  total_requested: number;
  errors: string[];
}

export interface JobDeleteResponse {
  message: string;
}

// User Management types
export interface UserListResponse {
  users: User[];
  total: number;
  page: number;
  size: number;
}

export interface CreateUserRequest {
  email: string;
  password: string;
  full_name: string;
  role: UserRole;
}

export interface UpdateUserRequest {
  email?: string;
  full_name?: string;
  role?: UserRole;
  is_active?: boolean;
  pm_client_ids?: string[];
}

// ── Organization / Membership types (SaaS) ───────────────────────────────────

export type OrgRole = "owner" | "admin" | "manager" | "member" | "viewer";

export interface Organization {
  id: string;
  name: string;
  slug: string;
  is_active: boolean;
  plan: string;
  created_at: string;
  updated_at: string;
}

export interface Membership {
  membership_id: string;
  user_id: string;
  email: string;
  full_name: string;
  role_in_org: OrgRole;
  created_at?: string;
  organization_id?: string;
  organization_slug?: string;
  organization_name?: string;
}

export interface MembershipCreate {
  user_id: string;
  role_in_org: OrgRole;
}

export interface MembershipUpdate {
  role_in_org: OrgRole;
}

export interface OrganizationCreateRequest {
  name: string;
  slug: string;
}

export interface OrganizationUpdateRequest {
  name?: string;
  slug?: string;
  is_active?: boolean;
  plan?: string;
}

export interface Invitation {
  id: string;
  email: string;
  organization_id: string;
  role_in_org: OrgRole;
  invited_by_user_id: string;
  expires_at: string;
  accepted_at?: string;
  revoked_at?: string;
  created_at?: string;
  is_expired: boolean;
  is_accepted: boolean;
  is_revoked: boolean;
}

export interface InvitationCreate {
  email: string;
  role_in_org: OrgRole;
  target_team_ids?: string[];
  expires_in_days?: number;
}

export interface InvitationPreview {
  org_name: string;
  org_slug: string;
  inviter_name: string;
  role_in_org: OrgRole;
  target_email: string;
  requires_password_setup: boolean;
  requires_microsoft_signin: boolean;
  is_existing_member: boolean;
}

export interface InvitationAcceptRequest {
  token: string;
  full_name?: string;
  password?: string;
  ms_id_token?: string;
}

export interface InvitationAcceptResponse {
  access_token: string;
  refresh_token: string;
  user_id: string;
  email: string;
  full_name: string;
  redirect_to: string;
}

// ── Client / Team / Project types ────────────────────────────────────────────

export interface Client {
  id: string;
  name: string;
  slug: string;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

export interface Team {
  id: string;
  name: string;
  client_id: string;
  member_user_ids: string[];
  created_at: string;
  updated_at: string;
}

export interface Project {
  id: string;
  name: string;
  client_id: string;
  is_active: boolean;
  default_languages: string[];
  default_linguist_id?: string;
  default_reviewer_id?: string;
  created_at: string;
  updated_at: string;
}

export interface PMUser {
  id: string;
  email: string;
  full_name: string;
  role: UserRole;
}

export interface ClientCreateRequest {
  name: string;
  slug: string;
}

export interface TeamCreateRequest {
  name: string;
}

export interface ProjectCreateRequest {
  name: string;
  default_languages?: string[];
  default_linguist_id?: string;
  default_reviewer_id?: string;
}

export interface ResetPasswordResponse {
  message: string;
  temporary_password: string;
  note: string;
}

export interface AdminStatsResponse {
  total_users: number;
  total_jobs: number;
  jobs_by_status: Record<string, number>;
  active_jobs_today: number;
  avg_processing_time_hours: number;
}

// Review Notes types (for video review feature)
export interface ReviewNote {
  id: string;
  job_id: string;
  asset_key: string;
  timestamp_seconds: number;
  content: string;
  user_id: string;
  user_name: string;
  created_at: string;
  updated_at?: string;
}

export interface ReviewNoteCreateRequest {
  asset_key: string;
  timestamp_seconds: number;
  content: string;
}

export interface ReviewNoteUpdateRequest {
  content: string;
}

export interface ReviewNotesListResponse {
  notes: ReviewNote[];
  total: number;
}

// Accessible Video QC Editing Types

export interface PausePointData {
  cue_index: number;
  original_ms: number;  // Rendered timeline position (for display)
  source_ms: number | null;  // Source video cut point (for re-rendering), null = use original_ms
  adjusted_ms: number | null;
  min_bound_ms: number;
  max_bound_ms: number;
  natural_gap_ms?: number;  // Duration (ms) of natural silence at the pause point; 0 = none
}

export interface VideoSegmentMetadata {
  segment_index: number;
  start_ms: number;
  end_ms: number;
  gcs_uri: string;
  duration_ms: number;
  is_freeze_frame: boolean;
  cue_index: number | null;  // AD cue index for freeze frames
}

export type TTSRegenerationStatus = "pending" | "processing" | "completed" | "failed";

export interface TTSRegenerationItem {
  cue_index: number;
  requested_at: string;
  new_text?: string;
  status: TTSRegenerationStatus;
  error_message?: string;
}

export interface AccessibleVideoEditState {
  pause_points: PausePointData[];
  video_segments: VideoSegmentMetadata[];
  tts_regeneration_queue: TTSRegenerationItem[];
  last_render_at: string | null;
  total_duration_ms: number;
  accessible_video_url: string | null;
}

export interface PausePointUpdateRequest {
  adjusted_ms: number;
}

export interface TTSRegenerationQueueRequest {
  cue_indices: number[];
}

export interface RerenderAccessibleVideoRequest {
  whisper_refine: boolean;
}

// ── VTT Versions ──────────────────────────────────────────────────────────

export type VttKind = 'captions' | 'ad';

export interface VttVersionActor {
  user_id: string;
  user_email: string;
}

export interface VttVersionSummary {
  id?: string;
  job_id: string;
  lang: string;
  kind: VttKind;
  version: number;
  gcs_uri: string;
  created_at: string;
  created_by: VttVersionActor;
  note?: string;
  parent_version?: number;
  cue_count: number;
  byte_size: number;
}

export interface VttVersionFull extends VttVersionSummary {
  content: string;
}

export interface VttVersionListResponse {
  versions: VttVersionSummary[];
  total: number;
}

export type DiffLineType = 'unchanged' | 'added' | 'removed';

export interface DiffLine {
  type: DiffLineType;
  content: string;
  line_no_old?: number;
  line_no_new?: number;
}

export interface VttDiffResponse {
  job_id: string;
  lang: string;
  kind: VttKind;
  from_version: number;
  to_version: number;
  lines: DiffLine[];
  added_count: number;
  removed_count: number;
}

// ── Audit Log ──────────────────────────────────────────────────────────────

export type AuditSeverity = 'info' | 'warning' | 'error' | 'critical';

export interface AuditLogEntry {
  id?: string;
  timestamp: string;
  action: string;
  severity: AuditSeverity;
  description: string;
  user_id?: string;
  user_email?: string;
  user_role?: string;
  ip_address?: string;
  user_agent?: string;
  request_id?: string;
  resource_type?: string;
  resource_id?: string;
  resource_name?: string;
  details?: Record<string, unknown>;
  success: boolean;
  error_message?: string;
  environment?: string;
}

export interface AuditLogListResponse {
  logs: AuditLogEntry[];
  total_count: number;
  page: number;
  page_size: number;
  has_more: boolean;
}

export interface AuditLogQuery {
  action?: string;
  severity?: AuditSeverity;
  user_id?: string;
  user_email?: string;
  resource_type?: string;
  resource_id?: string;
  success?: boolean;
  search?: string;
  start_date?: string;
  end_date?: string;
  skip?: number;
  limit?: number;
  sort_by?: string;
  sort_order?: number;
}

// ── Glossary ────────────────────────────────────────────────────────────────

export type GlossaryStatus = 'active' | 'archived';
export type EmbeddingStatus = 'pending' | 'in_progress' | 'done' | 'failed';

export interface GlossaryVersion {
  id: string;
  glossary_id: string;
  version_number: number;
  source_xlsx_gcs_path?: string;
  term_count: number;
  embedded_count: number;
  embedding_status: EmbeddingStatus;
  created_at: string;
  created_by: string;
  change_note?: string;
}

export interface Glossary {
  id: string;
  client_id: string;
  name: string;
  description?: string;
  source_locale: string;
  source: string;
  status: GlossaryStatus;
  current_version_id?: string;
  current_version_embedding_status?: EmbeddingStatus;
  current_version_embedded_count?: number;
  current_version_term_count?: number;
  created_at: string;
  created_by: string;
}

export interface GlossaryDetail extends Glossary {
  versions: GlossaryVersion[];
}

export interface GlossaryTerm {
  id?: string;
  source_term: string;
  translations: Record<string, string>;
}

export interface GlossaryTermsResponse {
  terms: GlossaryTerm[];
  total: number;
  page: number;
  page_size: number;
}

export interface GlossaryUploadRequest {
  name: string;
  source_locale: string;
  source_locale_col: string;
  description?: string;
  change_note?: string;
}

export type BriefStatus = "draft" | "submitted" | "approved" | "rejected" | "fulfilled";

export interface JobBriefResponse {
  id: string;
  organization_id: string;
  project_id?: string;
  title: string;
  description?: string;
  requested_outputs: RequestedOutputs;
  languages: string[];
  deadline?: string;
  status: BriefStatus;
  created_by: string;
  assignee_id?: string;
  job_id?: string;
  created_at: string;
  updated_at: string;
  submitted_at?: string;
  approved_by?: string;
}

export interface JobBriefCreate {
  title: string;
  description?: string;
  requested_outputs: RequestedOutputs;
  languages?: string[];
  deadline?: string;
  project_id?: string;
  assignee_id?: string;
  source_has_ad?: boolean;
}