/**
 * Import flashcard data from JSON files into Supabase.
 *
 * Usage:
 *   SUPABASE_URL=https://xxx.supabase.co SUPABASE_SERVICE_ROLE_KEY=ey... npx tsx supabase/scripts/import-flashcards.ts
 *
 * Requires: @supabase/supabase-js (already in project deps)
 */

import { createClient } from "@supabase/supabase-js"
import { readFileSync, existsSync } from "fs"
import { resolve, dirname } from "path"
import { fileURLToPath } from "url"

const __dirname = dirname(fileURLToPath(import.meta.url))
const DATA_DIR = resolve(__dirname, "../data")

const supabaseUrl = process.env.SUPABASE_URL
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY

if (!supabaseUrl || !serviceRoleKey) {
  console.error("Missing env vars: SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY")
  process.exit(1)
}

const supabase = createClient(supabaseUrl, serviceRoleKey)

interface RawList {
  id: string
  title: string
  is_public: boolean
  type: "parent" | "term"
  parent_id: string | null
  child_ids: string[]
}

interface RawTerm {
  word: string
  part_of_speech: string | null
  phonetic: string | null
  definition: string | null
  example: string | null
  image_url: string | null
  audio_tts_text: string | null
  audio_lang: string | null
  display_order: number
}

function readJson<T>(path: string): T {
  return JSON.parse(readFileSync(path, "utf-8"))
}

async function importLists(lists: RawList[]) {
  // Insert parent lists first (parent_id = null), then children
  const parents = lists.filter((l) => l.parent_id === null)
  const children = lists.filter((l) => l.parent_id !== null)

  for (const batch of [parents, children]) {
    const rows = batch.map((l) => ({
      id: Number(l.id),
      title: l.title,
      is_public: l.is_public,
      type: l.type,
      parent_id: l.parent_id ? Number(l.parent_id) : null,
    }))

    if (rows.length === 0) continue

    const { error } = await supabase.from("flashcard_list").upsert(rows, {
      onConflict: "id",
    })

    if (error) {
      console.error(`Error inserting lists batch:`, error.message)
    } else {
      console.log(`Imported ${rows.length} lists`)
    }
  }
}

async function importTerms(listId: number) {
  const filePath = resolve(DATA_DIR, `terms/flashcard_terms_${listId}.json`)
  if (!existsSync(filePath)) {
    console.log(`  No terms file for list ${listId}, skipping`)
    return 0
  }

  const terms = readJson<RawTerm[]>(filePath)
  if (terms.length === 0) {
    console.log(`  List ${listId}: empty, skipping`)
    return 0
  }

  const rows = terms.map((t) => ({
    list_id: listId,
    word: t.word,
    part_of_speech: t.part_of_speech,
    phonetic: t.phonetic,
    definition: t.definition,
    example: t.example,
    image_url: t.image_url,
    audio_tts_text: t.audio_tts_text,
    audio_lang: t.audio_lang || "en-US",
    display_order: t.display_order,
  }))

  // Supabase has a row limit per request, batch in chunks of 500
  const BATCH_SIZE = 500
  let imported = 0

  for (let i = 0; i < rows.length; i += BATCH_SIZE) {
    const chunk = rows.slice(i, i + BATCH_SIZE)
    const { error } = await supabase.from("flashcard_term").insert(chunk)

    if (error) {
      console.error(`  List ${listId} batch ${i}: ${error.message}`)
    } else {
      imported += chunk.length
    }
  }

  console.log(`  List ${listId}: ${imported}/${terms.length} terms`)
  return imported
}

async function updateTotalWords(listId: number) {
  const { count } = await supabase
    .from("flashcard_term")
    .select("*", { count: "exact", head: true })
    .eq("list_id", listId)

  if (count !== null) {
    await supabase
      .from("flashcard_list")
      .update({ total_words: count })
      .eq("id", listId)
  }
}

async function main() {
  console.log("=== Flashcard Import ===\n")

  // 1. Import lists
  const listsPath = resolve(DATA_DIR, "flashcard_lists.json")
  const lists = readJson<RawList[]>(listsPath)
  console.log(`Found ${lists.length} lists`)
  await importLists(lists)

  // 2. Import terms for each list
  console.log("\nImporting terms...")
  let totalTerms = 0

  for (const list of lists) {
    const count = await importTerms(Number(list.id))
    totalTerms += count
  }

  // 3. Update total_words counts
  console.log("\nUpdating word counts...")
  for (const list of lists) {
    await updateTotalWords(Number(list.id))
  }

  console.log(`\nDone! ${lists.length} lists, ${totalTerms} terms imported.`)
}

main().catch((err) => {
  console.error("Fatal:", err)
  process.exit(1)
})
