#!/usr/bin/env python3
"""Close batch-137 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-137"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LEXICAL: HANDLING, PLACEMENT, TRANSFER, AND MANIPULATION VERBS (Rule 95). 50 rows. DESIGN: lexical-control "
    "batch after Rule 94 case-frame construction; transitive A/O frames and recipient/placement cases were kept "
    "explicit. COVERED: `manil` get/take, `bawal` leave, `yijarril` put/place, `jurrngal` push, `kulbal` pull/lift, "
    "`kajal` tie, `dajil` give with LOC:pt recipient, `wundil` bring/take, `karrbal` grab, `jarrakulbal` carry, "
    "`yilbal` throw, `mujal` gather, `wuljil` bail/empty, `yakal` cut, `dumbarril` break/tear/rip, `nandal` close/"
    "shut/bury, `walngal` open/wake/take off, `buyandi-l` put in container, `yanday-bungal` prepare, `muru-bungal` "
    "put together, and `kuna-bungal` join/tie. SOURCE CAUTIONS: loan-heavy examples with table/gate/bucket/cassette/"
    "torch/brake/vehicle were deliberately avoided; `yakal` kept to simple cut rows; `buyandi-l` kept literal in "
    "container contexts; `walngal` polysemy logged. Pre-close lint scanned 6947 rows with 0 issues; verified metric "
    "remained 6897 before close. A review pass corrected three `dumbarrin` analysis fields from unsegmented "
    "`dumbarriny` to `dumbarri-ny` before close."
)

LESSONS = [
    ("lexicon", "`manil` is the basic get/take verb; it supports food, animal, firewood, and stone object frames.", "cheatsheet Rule 95: manil."),
    ("lexicon", "`bawal` is leave/quit; use it for leaving an object or place, not for general motion away.", "cheatsheet Rule 95: bawal."),
    ("lexicon", "`yijarril` is put/place; placement targets should be explicit LOCs when relevant.", "cheatsheet Rule 95: yijarril."),
    ("lexicon", "`dajil` give takes the thing as ABS object and the recipient in LOC:pt in the Patz examples.", "cheatsheet Rule 95: dajil recipient frame."),
    ("lexicon", "`wundil`, `jarrakulbal`, and `barrmal` must stay distinct: bring/take, carry, and escort/take-a-person respectively.", "dictionary errata: transfer/carry split."),
    ("lexicon", "`walngal` is polysemous: open, wake someone, take clothes/shoes off. Keep the English aligned to the object.", "dictionary errata: walngal polysemy."),
    ("lexicon", "`nandal` covers close/shut/bury; use simple object frames and avoid English door/gate loans.", "dictionary errata: nandal caution."),
    ("lexicon", "`buyandi-l` is grammar-added and should stay in literal container contexts.", "dictionary errata: buyandi-l caution."),
    ("lexicon", "`yanday-bungal`, `muru-bungal`, and `kuna-bungal` are -bungal manipulation compounds; do not generalize arbitrary X-bungal compounds.", "dictionary errata: -bungal handling compounds."),
    ("process", "Loan-heavy dictionary examples are evidence for the headword but not a mandate to bank loan rows in a native-lexicon batch.", "operator guide: lexical loan restraint."),
    ("process", "After mechanical lint, still read the analysis fields; the batch caught and fixed unsegmented `dumbarrin` analyses before close.", "operator guide: manual review after lint."),
    ("process", "Handling-verb rows should keep A/O order and case frames visible; do not hide the target construction in long narrative rows.", "operator guide: lexical batch row shape."),
]

LEXEMES = [
    ("manil", "verb-tr", "l", "NA", "get; take", "batch-137: basic get/take handling verb."),
    ("bawal", "verb-tr", "l", "NA", "leave; quit", "batch-137: leave object/place, quit activity."),
    ("yijarril", "verb-tr", "l", "NA", "put; place", "batch-137: placement with LOC target."),
    ("jurrngal", "verb-tr", "l", "NA", "push down; upset", "batch-137: push stone frame."),
    ("kulbal", "verb-tr", "l", "NA", "pull; lift", "batch-137: pull bamboo/lift log."),
    ("kajal", "verb-tr", "l", "NA", "tie", "batch-137: tie bag/spear."),
    ("dajil", "verb-tr", "l", "NA", "give", "batch-137: give with LOC:pt recipient."),
    ("wundil", "verb-tr", "l", "NA", "bring; take", "batch-137: transfer take/bring rows."),
    ("karrbal", "verb-tr", "l", "NA", "catch; grab; touch; arrest", "batch-137: grab/catch rows."),
    ("jarrakulbal", "verb-tr", "l", "NA", "carry", "batch-137: carry baby/wood."),
    ("yilbal", "verb-tr", "l", "NA", "throw", "batch-137: throw object/location rows."),
    ("mujal", "verb-tr", "l", "NA", "collect; gather", "batch-137: gather firewood, mussels, green ants."),
    ("wuljil", "verb-tr", "l", "NA", "empty out; bail out", "batch-137: bail water / empty honey."),
    ("yakal", "verb-tr", "l", "NA", "cut", "batch-137: simple meat/fish cut rows."),
    ("dumbarril", "verb-tr", "l", "NA", "break; tear; rip", "batch-137: break billycan/stick; analysis corrected to dumbarri-ny."),
    ("nandal", "verb-tr", "l", "NA", "close; shut; bury", "batch-137: close bag, bury dog."),
    ("walngal", "verb-tr", "l", "NA", "open; wake someone; take clothes off", "batch-137: polysemy separated by object."),
    ("buyandi-l", "verb-tr", "l", "NA", "put in container", "batch-137: grammar-added container verb."),
    ("yanday-bungal", "verb-tr", "l", "NA", "get ready; prepare", "batch-137: prepare spear/grass."),
    ("muru-bungal", "verb-tr", "l", "NA", "put things together", "batch-137: put bones together."),
    ("kuna-bungal", "verb-tr", "l", "NA", "join; tie something to something", "batch-137: tie/join with rope."),
]


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, LABEL,
            ),
        )
        db.execute(
            "INSERT INTO lexeme_log(headword, action, detail, created_at) VALUES(?,?,?,?)",
            (headword, "batch-137-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]
    lesson_count = db.execute("SELECT COUNT(*) FROM lessons WHERE batch_id=?", (batch_id,)).fetchone()[0]
    lexeme_logs = db.execute("SELECT COUNT(*) FROM lexeme_log WHERE action='batch-137-verify'").fetchone()[0]
    print(
        f"closed {LABEL}: 50 accepted rows, {reviews} review passes, "
        f"{lesson_count} lessons, {lexeme_logs} lexeme/source-log rows, verified corpus={verified}"
    )
    return 0


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