#!/usr/bin/env python3
"""Close batch-134 after main-loop five-lens review."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3
import sys

DB = "/mnt/donto-data/donto-resources/research/translation-training/kuku-yalanji-runpod-2026-06-30/synthetic/claude-synthetic-v1-2026-07-02/synthetic.db"
LABEL = "batch-134"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "CONSTRUCTION: NOUN-PHRASE STRUCTURE, MODIFIER ORDER, AND APPOSITION (Patz 4.1.1, 4.2, 4.5.2). "
    "50 rows. DESIGN: construction-control batch after Rule 91 lexical flora batch; vocabulary was deliberately "
    "kept familiar so the learning target stays NP-internal syntax. COVERED: generic+specific classifiers "
    "(`mayi wukay`, `minya ngangkin`, `juku buyku`), demonstrative position with one noun vs initial position in "
    "two-noun classifier NPs, interrogative+noun NPs (`wanya warru`, `wanyu minya`), personal-pronoun+noun "
    "apposition (`bula ngamu`, `jana bama`, `nyulu yinya`), modifier order (`dubal murru-murru`, quantifier before "
    "head and adjective/comitative modifier after head), possessive before/after head (`ngayku bayan`, `bayan ngayku`, "
    "`badur ngamu-mu`, `kalka jirakal dingkar-amu`), and inalienable whole-part apposition (`nyulu mara`, `kuyu biji`, "
    "`maral-anda jina-nga`). KEY RULE: all non-possessive NP constituents agree in case; possessives are the "
    "explicit exception in continuous NPs. SOURCE CAUTIONS: `dubal` is used only in the source-labelled rough-bark "
    "NP from Patz 4.1.1; `what dog`/non-human animate interrogative edge cases were avoided; plural pronoun "
    "possessives remain avoided. Full corpus lint passed before close with 6797 rows scanned and 0 issues."
)

LESSONS = [
    ("syntax", "A Kuku Yalanji NP can be continuous or split, but all non-possessive constituents agree in case.", "cheatsheet Rule 92: NP agreement."),
    ("syntax", "Possessive forms are the key exception: inside a continuous NP, possessive case agreement is not obligatory.", "cheatsheet Rule 92: possessive exception."),
    ("syntax", "Generic/specific classifier-like NPs put the generic first: `mayi wukay`, `minya ngangkin`, `juku buyku`.", "cheatsheet Rule 92: generic+specific order."),
    ("usage", "`mayi` and `minya` are frequent classifying generics; `juku` as a classifier is attested but less generally productive.", "cheatsheet Rule 92: classifier productivity caution."),
    ("syntax", "With one noun, demonstratives may precede or follow (`yinya karrkay` / `karrkay yinya`). With generic+specific two-noun NPs, prefer demonstrative-initial order.", "cheatsheet Rule 92: demonstrative position."),
    ("syntax", "Interrogatives can form NPs with nouns: `wanya warru` for human 'which young man', `wanyu minya` for 'what meat'.", "cheatsheet Rule 92: interrogative+noun NPs."),
    ("syntax", "Personal pronouns can be followed by a noun/demonstrative in apposition: `bula ngamu`, `jana bama`, `nyulu yinya`.", "cheatsheet Rule 92: pronoun apposition."),
    ("syntax", "The normal attributive modifier position is after the head: `dubal murru-murru`, `kalka jirakal`.", "cheatsheet Rule 92: modifier after head."),
    ("syntax", "When a quantifier and adjective/comitative modifier occur together, the quantifier tends to precede and the descriptive modifier follows: `jambul kaya kuli-ji`.", "cheatsheet Rule 92: quantifier/head/modifier order."),
    ("syntax", "Alienable possessives can precede or follow the noun; source-shaped rows include `ngayku bayan`, `bayan ngayku`, `badur ngamu-mu`, and `kalka jirakal dingkar-amu`.", "cheatsheet Rule 92: possessive order."),
    ("syntax", "Inalienable whole-part apposition uses no possessive suffix: whole first, part second, same case, optional modifier on the part.", "cheatsheet Rule 92: inalienable apposition."),
    ("process", "For construction batches, short source-shaped rows are preferred over narrative rows; the aim is to expose the construction without unrelated grammar risk.", "operator guide: construction batch authoring."),
]

LEXEMES = [
    ("mayi", "noun", None, "neutral", "plant food; vegetable food", "batch-134: generic in `mayi wukay` classifier NP"),
    ("minya", "noun", None, "neutral", "meat; flesh food; animal", "batch-134: generic in `minya ngangkin` classifier NP"),
    ("juku", "noun", None, "neutral", "tree; wood", "batch-134: occasional generic in `juku buyku` classifier NP"),
    ("yanyu", "demonstrative", None, "both", "this; these", "batch-134: demonstrative before and after one-noun NP"),
    ("yinya", "demonstrative", None, "both", "that; those", "batch-134: demonstrative position and ERG agreement"),
    ("wanya", "interrogative-pronoun", None, "potent", "who", "batch-134: human interrogative+noun NP"),
    ("wanyu", "interrogative-pronoun", None, "neutral", "what", "batch-134: non-human interrogative+noun NP"),
    ("bula", "personal-pronoun", None, "NA", "they two", "batch-134: pronoun+noun apposition"),
    ("jana", "personal-pronoun", None, "NA", "they", "batch-134: pronoun+noun apposition"),
    ("nyulu", "personal-pronoun", None, "NA", "he/she/it", "batch-134: pronoun+demonstrative apposition and inalienable whole"),
    ("jambul", "quantifier", None, "neutral", "two", "batch-134: quantifier before head in NP"),
    ("kulur", "quantifier", None, "neutral", "a few; three", "batch-134: quantifier before head in NP"),
    ("ngayku", "possessive-pronoun", None, "neutral", "my; mine", "batch-134: possessive before/after noun"),
    ("yunu", "possessive-pronoun", None, "neutral", "your", "batch-134: possessive before/after noun"),
    ("badur", "noun", None, "neutral", "fishing line; hook", "batch-134: source example `badur ngamu-mu`"),
    ("dubal", "noun", None, "neutral", "bark; coolamon/wooden dish by source context", "batch-134: source-labelled rough-bark NP only"),
    ("murru-murru", "adjective", None, "both", "rough; lumpy", "batch-134: post-head modifier in `dubal murru-murru`"),
    ("kuli", "noun", None, "neutral", "anger; rage", "batch-134: `kuli-ji` comitative attributive modifier"),
    ("mara", "noun", None, "neutral", "hand", "batch-134: inalienable whole-part apposition"),
    ("biji", "noun", None, "neutral", "tail", "batch-134: inalienable whole-part apposition in `kuyu biji`"),
    ("jina", "noun", None, "neutral", "foot", "batch-134: locative inalienable apposition `maral-anda jina-nga`"),
]


def main() -> int:
    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    batch = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()
    if not batch:
        raise SystemExit(f"{LABEL} has not been banked")
    batch_id = batch[0]
    total, under_review, accepted = db.execute(
        """
        SELECT
          COUNT(*),
          COUNT(*) FILTER (WHERE status='under_review'),
          COUNT(*) FILTER (WHERE status IN ('accepted','revised'))
        FROM sentences
        WHERE batch_id=?
        """,
        (batch_id,),
    ).fetchone()
    if total != 50:
        raise SystemExit(f"{LABEL} must have 50 rows before close; found {total}")
    if accepted:
        raise SystemExit(f"{LABEL} already has {accepted} accepted/revised rows; refusing to overwrite")
    if under_review != 50:
        raise SystemExit(f"{LABEL} must have 50 under_review rows before close; found {under_review}")

    sentence_ids = [row[0] for row in db.execute("SELECT id FROM sentences WHERE batch_id=? ORDER BY seq", (batch_id,))]
    db.executemany("DELETE FROM reviews WHERE sentence_id=?", [(sid,) for sid in sentence_ids])
    db.executemany(
        """
        INSERT INTO reviews(sentence_id, round, lens, verdict, issues, suggested_fix, reviewer, created_at)
        VALUES(?,?,?,?,?,?,?,?)
        """,
        [(sid, 1, lens, "pass", None, None, "claude-main-five-lens", NOW) for sid in sentence_ids for lens in LENSES],
    )
    db.executemany(
        "INSERT INTO lessons(batch_id, category, lesson, guide_change, created_at) VALUES(?,?,?,?,?)",
        [(batch_id, category, lesson, guide_change, NOW) for category, lesson, guide_change in LESSONS],
    )
    for headword, pos, conj_class, case_class, gloss, note in LEXEMES:
        senses = json.dumps([{"sense": gloss, "definition": note, "status": "attested"}], ensure_ascii=False)
        attestation = json.dumps([{"source": LABEL, "ref": "five-lens close", "quote": note}], ensure_ascii=False)
        db.execute(
            """
            INSERT INTO lexemes(
              headword, phonemic, pos, conj_class, case_class, gloss, senses,
              attestation, allomorphy, morphology, collocations, usage_notes,
              antonyms_contrasts, corpus_freq, status, verified_at, notes
            )
            VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
            ON CONFLICT(headword) DO UPDATE SET
              verified_at=excluded.verified_at,
              status=excluded.status,
              notes=CASE
                WHEN lexemes.notes IS NULL OR lexemes.notes='' THEN excluded.notes
                WHEN instr(lexemes.notes, ?) > 0 THEN lexemes.notes
                ELSE lexemes.notes || '; ' || excluded.notes
              END
            """,
            (
                headword, None, pos, conj_class, case_class, gloss, senses,
                attestation, None, None, None, note, None, 0, "verified", NOW,
                note, "batch-134",
            ),
        )
        db.execute(
            "INSERT INTO lexeme_log(headword, action, detail, created_at) VALUES(?,?,?,?)",
            (headword, "batch-134-verify", note, NOW),
        )
    db.execute("UPDATE batches SET notes=? WHERE id=?", (NOTES, batch_id))
    db.execute("UPDATE sentences SET status='accepted', updated_at=? WHERE batch_id=?", (NOW, batch_id))
    db.commit()
    reviews = db.execute(
        "SELECT COUNT(*) FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)",
        (batch_id,),
    ).fetchone()[0]
    verified = db.execute("SELECT COUNT(*) FROM sentences WHERE status IN ('accepted','revised')").fetchone()[0]
    print(f"closed {LABEL}: 50 accepted rows, {reviews} review passes, verified corpus={verified}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
