/**
 * AI-generated course plan — types mirror the backend controller's
 * response shape in `encoach_ai_course.controllers.course_plan`.
 */

export type CoursePlanSkill =
  | "reading"
  | "writing"
  | "listening"
  | "speaking"
  | "grammar"
  | "vocabulary"
  | "integrated";

export type CoursePlanMaterialType =
  | "reading_text"
  | "listening_script"
  | "speaking_prompt"
  | "writing_prompt"
  | "grammar_lesson"
  | "vocabulary_list"
  | "practice"
  | "interactive_workbook"
  | "other";

// ---------------------------------------------------------------------------
// Interactive workbooks — schema mirrors backend `_WEEK_JSON_HINT_V2` and
// `ExerciseExtractor` output. The renderer in `InteractiveWorkbook.tsx`
// is a discriminated-union switch on `type`.
// ---------------------------------------------------------------------------

export type WorkbookExerciseType =
  | "gap_fill"
  | "multiple_choice"
  | "match_pairs"
  | "reorder_words"
  | "transformation"
  | "short_answer";

export interface WorkbookExerciseBase {
  id: string;
  type: WorkbookExerciseType;
  hint?: string;
  rationale?: string;
}
export interface GapFillExercise extends WorkbookExerciseBase {
  type: "gap_fill";
  stem: string;
  answer: string;
  alt?: string[];
}
export interface MultipleChoiceExercise extends WorkbookExerciseBase {
  type: "multiple_choice";
  stem: string;
  options: string[];
  answer: string;
}
export interface MatchPairsExercise extends WorkbookExerciseBase {
  type: "match_pairs";
  left: string[];
  right: string[];
  answer: number[][];
}
export interface ReorderWordsExercise extends WorkbookExerciseBase {
  type: "reorder_words";
  tokens: string[];
  answer: string;
}
export interface TransformationExercise extends WorkbookExerciseBase {
  type: "transformation";
  from: string;
  instruction: string;
  answer: string;
  alt?: string[];
}
export interface ShortAnswerExercise extends WorkbookExerciseBase {
  type: "short_answer";
  stem: string;
  answer: string;
  accepted?: string[];
}
export type WorkbookExercise =
  | GapFillExercise
  | MultipleChoiceExercise
  | MatchPairsExercise
  | ReorderWordsExercise
  | TransformationExercise
  | ShortAnswerExercise;

export interface WorkbookLessonPlan {
  warmup?: string;
  presentation?: string;
  controlled_practice?: string;
  freer_practice?: string;
  exit_ticket?: string;
}

export interface WorkbookBody {
  lesson_plan?: WorkbookLessonPlan;
  exercises: WorkbookExercise[];
}

export interface WorkbookGroundedSource {
  source_id: number;
  title: string;
  chunks_used: number;
}

export interface WorkbookExtractedFrom {
  source_id: number;
  source_title?: string;
  page_hint?: string;
  topic_keywords?: string[];
  chunk_indices?: number[];
}

export interface WorkbookAttemptScoreItem {
  id: string;
  correct: boolean;
  expected: unknown;
  given: unknown;
}
export interface WorkbookAttemptScore {
  items: WorkbookAttemptScoreItem[];
  correct: number;
  total: number;
  percent: number;
}
export interface WorkbookAttempt {
  id: number;
  material_id: number;
  plan_id: number | null;
  student_id: number;
  student_name: string;
  attempt_number: number;
  is_final: boolean;
  submitted_at: string | null;
  last_updated_at: string | null;
  correct_count: number;
  total_count: number;
  percent: number;
  answers: Record<string, unknown>;
  score: WorkbookAttemptScore | Record<string, never>;
}

export interface CoursePlanOutcome {
  code: string;
  description: string;
}

export interface CoursePlanGrammarItem {
  code: string;
  label: string;
  sub_items?: string[];
}

export interface CoursePlanAssessmentComponent {
  name: string;
  weight: number;
}

export interface CoursePlanAssessment {
  continuous_assessment?: {
    total_weight?: number;
    components?: CoursePlanAssessmentComponent[];
  };
  final_exam?: {
    total_weight?: number;
  };
}

export interface CoursePlanResource {
  type: string;
  citation: string;
}

export interface CoursePlanWeekItem {
  skill: CoursePlanSkill | string;
  outcome_codes: string[];
  remarks?: string;
}

export interface CoursePlanWeek {
  id: number;
  week_number: number;
  date_label: string;
  unit: string;
  focus: string;
  items: CoursePlanWeekItem[];
  material_count: number;
}

export interface CoursePlanMaterial {
  id: number;
  plan_id: number;
  week_id: number | null;
  week_number: number;
  skill: string;
  material_type: CoursePlanMaterialType | string;
  title: string;
  is_static?: boolean;
  share_date?: string | null;
  summary: string;
  /** Loose shape: depends on material_type. */
  body: Record<string, unknown>;
  body_text: string;
  /** Citations for materials produced by the v2/RAG generator. */
  grounded_on?: WorkbookGroundedSource[];
  /** Provenance for materials mined out of indexed PDFs. */
  extracted_from?: WorkbookExtractedFrom | null;
  media?: CoursePlanMedia[];
}

// ---------------------------------------------------------------------------
// Phase A — Reference sources
// ---------------------------------------------------------------------------

export type CoursePlanSourceKind = "file" | "url" | "text" | "resource";
export type CoursePlanSourceStatus = "pending" | "indexing" | "indexed" | "failed";

export interface CoursePlanSource {
  id: number;
  plan_id: number;
  name: string;
  kind: CoursePlanSourceKind;
  file_name: string;
  mime_type: string;
  url: string;
  has_inline_text: boolean;
  /** Set when the source is linked to an item from /admin/resources. */
  resource_id?: number | null;
  resource_name?: string;
  resource_type?: string;
  status: CoursePlanSourceStatus;
  error: string;
  chunks_count: number;
  extracted_chars: number;
  indexed_at: string | null;
  created_at: string | null;
}

// ---------------------------------------------------------------------------
// Phase B — Deliverables preview / progress
// ---------------------------------------------------------------------------

export type DeliverableStatus = "planned" | "generated" | "ready";

export interface CoursePlanDeliverable {
  skill: string;
  material_type: string;
  material_id: number | null;
  title: string;
  status: DeliverableStatus;
  media: Array<{
    id: number;
    kind: "audio" | "image" | "video";
    status: string;
    provider: string;
  }>;
}

export interface CoursePlanDeliverablesWeek {
  week_number: number;
  date_label: string;
  unit: string;
  focus: string;
  items_total: number;
  deliverables: CoursePlanDeliverable[];
}

export interface CoursePlanDeliverables {
  summary: {
    total: number;
    planned: number;
    generated: number;
    ready: number;
    percent_ready: number;
    media: {
      audio: number;
      image: number;
      video: number;
      audio_ready: number;
      image_ready: number;
      video_ready: number;
    };
  };
  weeks: CoursePlanDeliverablesWeek[];
}

// ---------------------------------------------------------------------------
// Phase C — Multimedia
// ---------------------------------------------------------------------------

export type CoursePlanMediaKind = "audio" | "image" | "video";
export type CoursePlanMediaStatus = "queued" | "generating" | "ready" | "failed";
export type CoursePlanMediaProvider =
  | "polly"
  | "elevenlabs"
  | "openai_image"
  | "ffmpeg"
  | "elai"
  // Free fallbacks (Phase 24.1)
  | "pillow"
  | "unsplash"
  | "gtts"
  | "silent"
  | "static"
  | "mock"
  | "auto"
  | "manual";

export interface CoursePlanMedia {
  id: number;
  plan_id: number;
  week_id: number | null;
  material_id: number | null;
  kind: CoursePlanMediaKind;
  provider: CoursePlanMediaProvider | string;
  title: string;
  voice: string;
  language: string;
  style: string;
  mime_type: string;
  size_bytes: number;
  duration_seconds: number;
  width: number;
  height: number;
  attachment_id: number | null;
  /** REST URL with ``Content-Disposition: attachment`` — used by the
   *  download buttons. The frontend appends ``?token=<jwt>`` so it works
   *  from plain ``<a download>`` tags. */
  download_url: string;
  /** REST URL with ``Content-Disposition: inline`` — used as the ``src``
   *  for ``<img>`` / ``<audio>`` / ``<video>`` tags. The frontend appends
   *  ``?token=<jwt>`` because browsers can't attach custom headers to
   *  these element fetches. */
  preview_url?: string;
  status: CoursePlanMediaStatus;
  error: string;
  cost_cents: number;
  created_at: string | null;
}

// ---------------------------------------------------------------------------
// Phase D — Assignments
// ---------------------------------------------------------------------------

export type CoursePlanAssignmentMode = "batch" | "students" | "entities";
export type CoursePlanAssignmentState = "active" | "archived";

export interface CoursePlanAssignment {
  id: number;
  plan_id: number;
  plan_name: string;
  mode: CoursePlanAssignmentMode;
  batch_id: number | null;
  batch_name: string;
  student_user_ids: number[];
  student_user_names: string[];
  entity_ids?: number[];
  entity_names?: string[];
  student_count: number;
  assigned_by_id: number | null;
  assigned_by_name: string;
  due_date: string | null;
  message: string;
  state: CoursePlanAssignmentState;
  created_at: string | null;
}

export interface CoursePlan {
  id: number;
  name: string;
  entity_id?: number | null;
  entity_name?: string;
  course_id: number | null;
  course_name: string;
  cefr_level: string;
  total_weeks: number;
  contact_hours_per_week: number;
  skills_division: string;
  description: string;
  status: "draft" | "generated" | "approved" | "archived";
  objectives: string[];
  outcomes: Partial<Record<CoursePlanSkill, CoursePlanOutcome[]>>;
  grammar: CoursePlanGrammarItem[];
  assessment: CoursePlanAssessment;
  resources: CoursePlanResource[];
  week_count: number;
  material_count: number;
  source_count?: number;
  media_count?: number;
  assignment_count?: number;
  created_at: string | null;
  weeks?: CoursePlanWeek[];
  materials?: CoursePlanMaterial[];
  sources?: CoursePlanSource[];
  media?: CoursePlanMedia[];
  assignments?: CoursePlanAssignment[];
  /** Present on the student-list endpoint payload. */
  assignment?: CoursePlanAssignment;
}

export interface CoursePlanGenerateBrief {
  title: string;
  entity_id?: number;
  cefr_level?: string;
  total_weeks?: number;
  contact_hours_per_week?: number;
  skills_division?: string;
  grammar_focus?: string[];
  resources?: string[];
  learner_profile?: string;
  notes?: string;
  course_id?: number;
}
