import { supabase } from "@/lib/supabase"
import type { Question, SessionPart } from "@/types"

type AnswerChoiceRow = { value: string; label_text: string | null; is_correct: boolean }
type QuestionRow = { id: number; question_text: string | null; explanation: string | null; group_id: number; answer_choice: AnswerChoiceRow[] }
type GroupRow = { id: number; part_id: number; audio_url: string | null; image_url: string | null; passage_text: string | null }
type PartRow = { id: number; part_number: number }

function buildOptions(choices: AnswerChoiceRow[]): string[] {
  return [...choices].sort((a, b) => a.value.localeCompare(b.value)).map(c => c.label_text ?? '')
}

function getCorrectIndex(choices: AnswerChoiceRow[]): number {
  const sorted = [...choices].sort((a, b) => a.value.localeCompare(b.value))
  const idx = sorted.findIndex(c => c.is_correct)
  return idx >= 0 ? idx : 0
}

function rowToQuestion(row: QuestionRow, group: GroupRow, partNumber: number): Question {
  return {
    id: row.id,
    partNumber,
    text: row.question_text,
    options: buildOptions(row.answer_choice),
    correctAnswer: getCorrectIndex(row.answer_choice),
    explanation: row.explanation,
    groupId: row.group_id,
    audioUrl: group.audio_url ?? undefined,
    imageUrl: group.image_url ?? undefined,
    passageText: group.passage_text ?? undefined,
  }
}

/**
 * Fetch all questions for a test, optionally filtered to specific part numbers.
 * partNumbers=[] or undefined → fetch all parts of the test.
 * Returns questions grouped into SessionPart[] ordered by part_number.
 */
export async function fetchQuestionsForTest(
  testId: number,
  partNumbers?: number[],
): Promise<SessionPart[]> {
  // Step 1: Get parts for this test
  let partsQuery = supabase.from('part').select('id, part_number, title').eq('test_id', testId).order('part_number')
  if (partNumbers?.length) partsQuery = partsQuery.in('part_number', partNumbers)
  const { data: parts, error: partsError } = await partsQuery
  if (partsError) throw partsError
  if (!parts?.length) return []

  const partRows = parts as (PartRow & { title: string })[]
  const partIds = partRows.map(p => p.id)
  const partNumberById = new Map(partRows.map(p => [p.id, p.part_number]))
  const partTitleByNumber = new Map(partRows.map(p => [p.part_number, p.title]))

  // Step 2: Get question_groups for those parts
  const { data: groups, error: groupsError } = await supabase
    .from('question_group')
    .select('id, part_id, audio_url, image_url, passage_text')
    .in('part_id', partIds)
  if (groupsError) throw groupsError
  if (!groups?.length) return []

  const groupMap = new Map<number, GroupRow>((groups as GroupRow[]).map(g => [g.id, g]))
  const groupIds = (groups as GroupRow[]).map(g => g.id)

  // Step 3: Get questions with answer choices
  const { data: rows, error } = await supabase
    .from('question')
    .select('id, question_text, explanation, group_id, answer_choice(value, label_text, is_correct)')
    .in('group_id', groupIds)
    .order('question_number')
  if (error) throw error

  const questions = (rows as QuestionRow[] ?? [])
    .map(row => {
      const group = groupMap.get(row.group_id)!
      const partNumber = partNumberById.get(group.part_id)!
      return rowToQuestion(row, group, partNumber)
    })
    .filter(q => q.options.length > 0)

  // Group into SessionPart[] ordered by partNumber
  const byPart = new Map<number, Question[]>()
  for (const q of questions) {
    if (!byPart.has(q.partNumber)) byPart.set(q.partNumber, [])
    byPart.get(q.partNumber)!.push(q)
  }

  return partRows
    .filter(p => byPart.has(p.part_number))
    .map(p => ({
      partNumber: p.part_number,
      partName: partTitleByNumber.get(p.part_number) ?? `Part ${p.part_number}`,
      questions: byPart.get(p.part_number)!,
    }))
}
