"""Author Persian lesson content with Claude, cache to lessons/data/<id>.json.

Run offline (not at request time):
    set -a; source .env; set +a
    ./.venv/bin/python gen_lessons.py            # generate any missing lessons
    ./.venv/bin/python gen_lessons.py --force    # regenerate all
    ./.venv/bin/python gen_lessons.py taarof food-guest   # specific ids

Output schema per lesson file:
    {"items": [{"persian","translit","english","note"?}],
     "dialogue": [{"persian","translit","english"}]}
"""
import json
import os
import re
import sys
from pathlib import Path

import anthropic

from lessons import DATA_DIR, load_specs

MODEL = os.environ.get("LESSON_MODEL", "claude-sonnet-4-6")

AUTHOR_SYSTEM = """You author short, casual, conversational Persian (Farsi) lessons for a half-Persian \
intermediate learner whose ONLY goal is speaking fluently in everyday life. He does NOT care about \
reading/writing, the alphabet, or formal register. Transliteration is the star.

Hard rules:
- Register: casual spoken Tehrani. Use real contractions people say out loud (miram not miravam, \
mikham not mikhaaham, chetori, khoobam, mishe, nemidoonam). Never formal/literary unless the phrase only \
exists formally.
- Transliteration: informal Iranian "Finglish" an English speaker can sound out. Use kh, sh, ch, zh, gh; \
long a -> aa; short vowels a/e/o; silent final he -> e; apostrophe for ع often dropped. NO academic \
diacritics (no ḫ, ʿ, ā).
- Persian script: still include it (it drives the audio), but it is secondary.
- english: plain, natural meaning — how someone would actually translate it, not word-for-word.
- note: OPTIONAL one short line — a usage/cultural tip, when to say it, or a register warning. Omit \
(set to "") if there's nothing genuinely useful. Keep notes rare and high-signal.

Output ONLY valid minified-ish JSON (no markdown fences, no prose) with EXACTLY this shape:
{"items":[{"persian":"...","translit":"...","english":"...","note":"..."}],
 "dialogue":[{"persian":"...","translit":"...","english":"..."}]}

- items: 8-12 of the most useful real phrases for the topic.
- dialogue: one short, natural 4-8 line exchange between two friends/family that USES phrases from the \
lesson, so he hears them in context."""


def author_lesson(client: anthropic.Anthropic, spec: dict) -> dict:
    msg = client.messages.create(
        model=MODEL,
        max_tokens=2500,
        system=AUTHOR_SYSTEM,
        messages=[{"role": "user", "content":
                   f"Lesson topic: {spec['title']}\n\nCover: {spec['prompt']}"}],
    )
    text = msg.content[0].text.strip()
    # Strip accidental code fences, then grab the outermost JSON object.
    text = re.sub(r"^```(?:json)?|```$", "", text, flags=re.MULTILINE).strip()
    start, end = text.find("{"), text.rfind("}")
    data = json.loads(text[start:end + 1])
    assert isinstance(data.get("items"), list) and data["items"], "no items returned"
    for it in data["items"]:
        assert it.get("persian") and it.get("translit") and it.get("english"), f"bad item: {it}"
        it.setdefault("note", "")
    data.setdefault("dialogue", [])
    return data


def main(argv: list):
    force = "--force" in argv
    wanted = [a for a in argv if not a.startswith("--")]
    DATA_DIR.mkdir(parents=True, exist_ok=True)
    client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

    specs = load_specs()
    if wanted:
        specs = [s for s in specs if s["id"] in wanted]

    for spec in specs:
        out = DATA_DIR / f"{spec['id']}.json"
        if out.exists() and not force:
            print(f"skip   {spec['id']} (exists)")
            continue
        print(f"author {spec['id']} ...", flush=True)
        data = author_lesson(client, spec)
        out.write_text(json.dumps(data, ensure_ascii=False, indent=2))
        print(f"  -> {len(data['items'])} items, {len(data.get('dialogue', []))} dialogue lines")


if __name__ == "__main__":
    main(sys.argv[1:])
