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

from __future__ import annotations

import datetime as dt
import json
import sqlite3
import sys

from process_ledger import ensure_schema, record_event

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-162"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-162-locational-comitative-possessive-frames-process.md"
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "CONSTRUCTION: LOCATIONAL, COMITATIVE, AND POSSESSIVE FRAME CONSOLIDATION (Rule 120). 50 rows. DESIGN: "
    "hand-authored rows drilling solid locationals, location/source alternations, sourced comitatives, possessive "
    "noun phrases and possessive stems, and perception/location contrasts while reusing Rule 119 lexicon. SOURCE "
    "CONTROLS: Patz case tables, possessive examples 44-49, comitative table/ex.50-53/ex.163, location-word "
    "section ex.106-112, wujurr-bu time note, ex.142-143 yinyay-mba, Text 11/12 wangkarwangkar/badabada examples, "
    "plus dictionary.yaml target heads. PROCESS STORAGE: source pass, duplicate repair before banking, lint, "
    "five-lens review, close, export, docs, and live verification are stored."
)

LESSONS = [
    ("morphology", "`badabada` and `wangkarwangkar` are solid lexicalized locationals; never hyphenate them as productive reduplications.", "Rule 120: solid locationals."),
    ("morphology", "`badabada-mundu` and `wangkarwangkar-mundu` are sourced source/abessive-style locationals meaning from down/up there.", "Rule 120: locational source."),
    ("morphology", "`yinyay-mba` is the safe there-LOC form; keep the `-mba` allomorph visible.", "Rule 120: yinyay-mba."),
    ("morphology", "`wujurr-bu` is the safe night/darkness LOC time expression.", "Rule 120: wujurr-bu."),
    ("morphology", "Neutral ABL `-muny` remains the safe source marker for `bayan-muny`, `wawubaja-muny`, and `manjal-muny`.", "Rule 120: neutral ABL."),
    ("morphology", "Sourced comitatives in this batch are `nganjan-anji`, `jawun-unji`, `kadar-anji`, `juku-ji`, and `kambi-ji`; do not analogize beyond them.", "Rule 120: comitative forms."),
    ("morphology", "`mayi kaya-nga` and `kambi ngamu-ngu` follow Patz's possessive table and need no separate possessive particle.", "Rule 120: possessive NPs."),
    ("morphology", "Possessive stems can carry case in source phrases, e.g. `maral-andamun-bu`, `maral-andamun-muny`, and `yaba-ndamun-muny`.", "Rule 120: possessive case stacking."),
    ("syntax", "Comitative, time, and source NPs can co-occur in one plain motion clause if each is sourced and not overloaded.", "Rule 120: clause layering."),
    ("syntax", "Transitive rows still require visible objects even when the construction focus is location or possession.", "Rule 120: object visibility."),
    ("syntax", "Perception rows preserve the Rule 118 split: common-noun A with ERG, pronoun A unmarked.", "Rule 120: perception A marking."),
    ("syntax", "Possessive object NPs can be the object of `mani-l`, `nuka-l`, `wundi-l`, `daji-l`, and `nyaji-l` without changing the verb frame.", "Rule 120: possessive objects."),
    ("lexicon", "`dawar` remains the safe star word and `kija` remains moon/month only.", "Rule 120: celestial guard."),
    ("lexicon", "`jarramali` is used in the thunder sense where it is heard at night.", "Rule 120: jarramali sense."),
    ("fidelity", "Rows with sourced possessive examples should keep English close to the Kuku, even when the possessive chain is compact.", "Rule 120: possessive fidelity."),
    ("fidelity", "Rows using `kadar-anji` are best translated plainly as 'with a wallaby' and not expanded to carrying/hunting unless sourced.", "Rule 120: comitative fidelity."),
    ("register", "The construction batch is intentionally plain; the value is repeated case-frame contrast, not rhetorical richness.", "Rule 120: register scope."),
    ("process", "Duplicate detection before banking is part of the evidence trail; Batch 162 repaired two exact-surface duplicates before insert.", "Rule 120: duplicate preflight."),
    ("process", "A construction batch can and should reuse the previous lexical batch's heads rather than adding new words.", "Rule 120: cadence discipline."),
    ("process", "No-repair five-lens review still needs an explicit event, because green lint is not a substitute for linguistic review.", "Rule 120: review evidence."),
]

LEXEMES = [
    ("badabada", "locational", None, "solid; ABESS badabada-mundu", "down there; underneath", "batch-162: solid locational, never hyphenated."),
    ("badabada-mundu", "case-form", None, "ABESS/source", "from down there", "batch-162: source expression from Patz ex.110."),
    ("wangkarwangkar", "locational", None, "solid; ABESS wangkarwangkar-mundu", "up there; above", "batch-162: solid locational, never hyphenated."),
    ("wangkarwangkar-mundu", "case-form", None, "ABESS/source", "from up there", "batch-162: source expression from Patz Text 12."),
    ("yinyay-mba", "case-form", None, "LOC", "there-LOC", "batch-162: there-location form from Patz ex.142-143."),
    ("wujurr-bu", "case-form", None, "LOC", "at/during the night", "batch-162: night-time LOC expression."),
    ("bayan-ba", "case-form", None, "LOC", "house/camp-LOC", "batch-162: goal/place form in motion rows."),
    ("bayan-muny", "case-form", None, "ABL", "from house/camp", "batch-162: source form in motion and possessive rows."),
    ("wawubaja-nga", "case-form", None, "LOC", "river-LOC", "batch-162: river goal/place form."),
    ("wawubaja-muny", "case-form", None, "ABL", "from river", "batch-162: river source form."),
    ("manjal-muny", "case-form", None, "ABL", "from mountain", "batch-162: mountain source form."),
    ("baya ngundu-ba", "locational-phrase", None, "LOC", "near the fire", "batch-162: near-fire location in sleep row."),
    ("nganjan-anji", "case-form", None, "COMIT:pt", "with father", "batch-162: sourced potent comitative."),
    ("jawun-unji", "case-form", None, "COMIT:pt", "with a friend", "batch-162: sourced potent comitative."),
    ("kadar-anji", "case-form", None, "COMIT:pt", "with a wallaby", "batch-162: sourced potent comitative."),
    ("juku-ji", "case-form", None, "COMIT", "with a stick", "batch-162: sourced neutral comitative."),
    ("kambi-ji", "case-form", None, "COMIT", "with clothes", "batch-162: sourced neutral comitative."),
    ("mayi kaya-nga", "possessive-np", None, "POSS.ABS", "the dog's food", "batch-162: Patz possessive table form drilled as object."),
    ("kambi ngamu-ngu", "possessive-np", None, "POSS.ABS", "mother's clothes", "batch-162: Patz possessive table form drilled as object."),
    ("maral-andamun-bu", "case-form", None, "POSS-ERG", "girl's ... as ERG possessor phrase", "batch-162: possessive stem with ERG in girl's mother rows."),
    ("maral-andamun-muny", "case-form", None, "POSS-ABL", "from the girl's ...", "batch-162: possessive stem with ABL in nested source row."),
    ("yaba-ndamun-muny", "case-form", None, "POSS-ABL", "from elder brother's ...", "batch-162: nested possessive ABL source row."),
    ("dingkar-amu ngamu-mu bayan", "possessive-np", None, "POSS.ABS", "the man's mother's house", "batch-162: Patz nested possessive example."),
    ("dawar", "noun", None, "NA", "star", "batch-162: safe star lexeme retained."),
    ("kija", "noun", None, "NA", "moon; month", "batch-162: moon-only guard retained."),
    ("nyaji-l", "transitive-verb", "l", "NA", "see; hear", "batch-162: common-noun A ERG, pronoun A unmarked."),
    ("warrmba-bunga-l", "transitive-verb", "l", "NA", "find", "batch-162: found object plus locational frame."),
    ("wundi-l", "transitive-verb", "l", "NA", "take; bring", "batch-162: possessive object plus goal/source frame."),
    ("dunga-y", "intransitive-verb", "y", "NA", "go", "batch-162: locational/comitative motion rows."),
    ("kada-y", "intransitive-verb", "y", "NA", "come", "batch-162: source/comitative motion rows."),
    ("bunda-y", "intransitive-verb", "y", "NA", "sit; stay", "batch-162: locational posture rows."),
    ("wuna-y", "intransitive-verb", "y", "NA", "lie; rest", "batch-162: rest/sleep location rows."),
]


def main() -> int:
    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    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-162-verify", note, NOW),
        )
    record_event(
        db,
        batch_label=LABEL,
        phase="review",
        event_type="five-lens-pass",
        actor="claude-main",
        detail=(
            "Manual five-lens review passed all 50 Rule 120 rows with no row repairs required. Morphology checked "
            "solid locationals, -mundu source forms, -muny ABL forms, -mba yinyay locative, wujurr-bu, sourced "
            "comitatives, possessive case stacking, ERG A marking, and past/nonpast surfaces. Lexicon checked every "
            "content head against dictionary.yaml/Patz evidence. Syntax checked co-occurring time/source/comitative "
            "NPs, overt objects, and perception A marking. Fidelity kept English close to the sourced Kuku frames. "
            "Register stayed plain construction-drill style pending elder verification."
        ),
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="review",
        event_type="review-detail",
        actor="claude-main",
        detail=(
            "No repairs were needed during Batch 162 five-lens review. Explicit retained decisions: badabada and "
            "wangkarwangkar solid; no maja-nga; no yunga-l; no babaji-y; kija moon-only; dawar star; sourced "
            "comitatives only; common-noun nyaji-l perceivers marked ERG; possessive stems follow Patz examples."
        ),
        artifact_path=PROCESS_LOG,
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="review",
        event_type="lesson-inventory",
        actor="claude-main",
        detail=f"Inserted {len(LESSONS)} Rule 120 lessons covering morphology, syntax, lexicon, fidelity, register, and process safeguards.",
        artifact_path="batch_scripts/close_162.py",
        created_at=NOW,
    )
    record_event(
        db,
        batch_label=LABEL,
        phase="review",
        event_type="lexeme-source-log",
        actor="claude-main",
        detail=f"Inserted {len(LEXEMES)} lexeme/source-log rows for Rule 120 locational, comitative, possessive, and predicate forms.",
        artifact_path="batch_scripts/close_162.py",
        created_at=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))
    record_event(
        db,
        batch_label=LABEL,
        phase="close",
        event_type="close-success",
        actor="claude-main",
        detail="Closed Batch 162: 50 accepted Rule 120 construction rows, five-lens reviews, lessons, lexeme/source logs, and process evidence stored.",
        command="python3 batch_scripts/close_162.py",
        artifact_path="batch_scripts/close_162.py",
        created_at=NOW,
    )
    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]
    under_review_remaining = db.execute("SELECT COUNT(*) FROM sentences WHERE status='under_review'").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-162-verify'").fetchone()[0]
    process_events = db.execute("SELECT COUNT(*) FROM process_events WHERE batch_label=?", (LABEL,)).fetchone()[0]
    print(
        f"closed {LABEL}: 50 accepted rows, {reviews} review passes, "
        f"{lesson_count} lessons, {lexeme_logs} lexeme/source-log rows, "
        f"{process_events} process events, under_review={under_review_remaining}, "
        f"verified corpus={verified}"
    )
    return 0


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