#!/usr/bin/env python3
"""
Build a review sheet of AI translation and transliteration quality, using real
published content from the archive.

The point is that no public benchmark answers the question that matters here.
Benchmarks score news and Wikipedia prose; Shodh Sanchayan publishes scholarly
Hindi full of Sanskrit-derived terminology. The only judgement worth having is
the chief editor's, on his own material.

So this pulls genuine Hindi titles and abstracts straight from archive_articles,
runs them through the API's own /ai endpoints — the real code path, real prompts,
whatever model is currently configured — and writes an HTML sheet with the source
and the output side by side, with somewhere to mark each one.

Run the API first, then:

    python3 scripts/ai_translation_bakeoff.py --count 5

Switch models by editing AI_MODEL in .env and restarting the API, then run again
with a different --label; each run writes its own file.
"""

import argparse
import html
import json
import os
import subprocess
import sys
import time
import urllib.error
import urllib.request
from datetime import datetime
from pathlib import Path

API = os.environ.get("BAKEOFF_API", "http://localhost:8081/api")
# A seeded UAT author; this only needs a login, not any particular privilege.
LOGIN = {"email": "lekhak1@test.shodh.net", "password": "Lekhak@2026"}

OUT_DIR = Path(__file__).resolve().parent.parent / "legacy-import" / "bakeoff"


def post(path, payload, token=None):
    """POST JSON, returning (parsed body, seconds elapsed)."""
    req = urllib.request.Request(
        f"{API}{path}",
        data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
        headers={"Content-Type": "application/json; charset=utf-8",
                 **({"Authorization": f"Bearer {token}"} if token else {})},
        method="POST",
    )
    started = time.time()
    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            return json.loads(resp.read().decode("utf-8")), time.time() - started
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", "replace")
        return {"__error__": f"HTTP {e.code}: {body[:300]}"}, time.time() - started
    except Exception as e:  # noqa: BLE001 - surfaced into the report, not raised
        return {"__error__": str(e)}, time.time() - started


def fetch_samples(count):
    """Real Hindi titles and abstracts, shortest first so runs stay quick."""
    sql = f"""
        SELECT title_hi, COALESCE(abstract_hi, '')
          FROM archive_articles
         WHERE title_hi IS NOT NULL AND abstract_hi IS NOT NULL
           AND length(abstract_hi) BETWEEN 300 AND 2500
         ORDER BY length(abstract_hi)
         LIMIT {int(count)};
    """
    out = subprocess.run(
        ["psql", "-h", "localhost", "-p", os.environ.get("DB_PORT", "5433"),
         "-U", "shodh", "-d", "shodh_sanchayan", "-t", "-A", "-F", "\x1f", "-c", sql],
        capture_output=True, text=True,
        env={**os.environ, "PGPASSWORD": os.environ.get("DB_PASS", "shodh_secret")},
    )
    if out.returncode != 0:
        sys.exit(f"Could not read the archive: {out.stderr.strip()}")

    rows = []
    for line in out.stdout.strip().split("\n"):
        if "\x1f" in line:
            title, abstract = line.split("\x1f", 1)
            rows.append({"title": title.strip(), "abstract": abstract.strip()})
    return rows


def render(results, label, model, generated_at):
    def esc(s):
        return html.escape(s or "")

    rows = []
    for i, r in enumerate(results, 1):
        rows.append(f"""
        <section>
          <h2>{i}. Title</h2>
          <table>
            <tr><th>Hindi (source)</th><td class="hi">{esc(r['title'])}</td></tr>
            <tr><th>English</th><td>{esc(r['title_en'])}</td></tr>
            <tr><th>Transliteration</th><td>{esc(r['title_tr'])}</td></tr>
            <tr><th>Time</th><td class="meta">{r['title_secs']:.1f}s</td></tr>
            <tr><th>Acceptable?</th><td class="mark">☐ yes &nbsp; ☐ needs editing &nbsp; ☐ no</td></tr>
          </table>

          <h2>{i}. Abstract</h2>
          <table>
            <tr><th>Hindi (source)</th><td class="hi">{esc(r['abstract'])}</td></tr>
            <tr><th>English</th><td>{esc(r['abstract_en'])}</td></tr>
            <tr><th>Time</th><td class="meta">{r['abstract_secs']:.1f}s</td></tr>
            <tr><th>Acceptable?</th><td class="mark">☐ yes &nbsp; ☐ needs editing &nbsp; ☐ no</td></tr>
          </table>
        </section>""")

    return f"""<!doctype html>
<html lang="en"><head><meta charset="utf-8">
<title>AI translation review — {esc(label)}</title>
<style>
  body {{ font-family: -apple-system, system-ui, sans-serif; max-width: 62rem;
         margin: 2rem auto; padding: 0 1rem; color: #1a1a1a; line-height: 1.55; }}
  h1 {{ font-size: 1.4rem; margin-bottom: .25rem; }}
  .sub {{ color: #666; font-size: .85rem; margin-bottom: 2rem; }}
  section {{ border-top: 2px solid #eee; padding-top: 1rem; margin-top: 2rem; }}
  h2 {{ font-size: .95rem; text-transform: uppercase; letter-spacing: .04em;
        color: #0f1f99; margin: 1.25rem 0 .5rem; }}
  table {{ width: 100%; border-collapse: collapse; }}
  th {{ text-align: left; width: 9.5rem; vertical-align: top; padding: .5rem .75rem .5rem 0;
        font-weight: 600; font-size: .8rem; color: #555; }}
  td {{ padding: .5rem 0; vertical-align: top; border-bottom: 1px solid #f0f0f0; }}
  .hi {{ font-size: 1.02rem; }}
  .meta {{ color: #777; font-size: .85rem; }}
  .mark {{ font-size: 1rem; letter-spacing: .02em; }}
  .err {{ color: #b00; }}
  @media print {{ section {{ page-break-inside: avoid; }} }}
</style></head><body>
<h1>AI translation &amp; transliteration — review sheet</h1>
<div class="sub">
  Model: <strong>{esc(model)}</strong> &middot; {esc(label)} &middot; generated {esc(generated_at)}<br>
  Source text is real published content from the Shodh Sanchayan archive.
  Please mark each output.
</div>
{''.join(rows)}
</body></html>"""


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--count", type=int, default=5, help="how many articles to sample")
    ap.add_argument("--label", default="run", help="label for this run, used in the filename")
    args = ap.parse_args()

    token_body, _ = post("/auth/login", LOGIN)
    token = token_body.get("token")
    if not token:
        sys.exit(f"Could not log in — is the API running at {API}? {token_body}")

    status_req = urllib.request.Request(f"{API}/ai/status",
                                        headers={"Authorization": f"Bearer {token}"})
    with urllib.request.urlopen(status_req, timeout=30) as resp:
        if not json.loads(resp.read()).get("configured"):
            sys.exit("AI is not configured — set AI_API_KEY in .env and restart the API.")

    samples = fetch_samples(args.count)
    if not samples:
        sys.exit("No suitable Hindi articles found in the archive.")

    print(f"Running {len(samples)} articles through the configured model…\n")
    results = []
    for i, s in enumerate(samples, 1):
        t_en, t_secs = post("/ai/translate",
                            {"text": s["title"], "from": "Hindi", "to": "English"}, token)
        t_tr, tr_secs = post("/ai/transliterate", {"text": s["title"]}, token)
        a_en, a_secs = post("/ai/translate",
                            {"text": s["abstract"], "from": "Hindi", "to": "English"}, token)

        results.append({
            **s,
            "title_en": t_en.get("translated", t_en.get("__error__", "")),
            "title_tr": t_tr.get("transliterated", t_tr.get("__error__", "")),
            "abstract_en": a_en.get("translated", a_en.get("__error__", "")),
            "title_secs": t_secs + tr_secs,
            "abstract_secs": a_secs,
        })
        print(f"  {i}/{len(samples)}  {s['title'][:48]}…  "
              f"({t_secs + tr_secs:.1f}s title, {a_secs:.1f}s abstract)")

    model = os.environ.get("AI_MODEL", "")
    if not model:
        for line in (Path(__file__).resolve().parent.parent / ".env").read_text().splitlines():
            if line.startswith("AI_MODEL="):
                model = line.split("=", 1)[1].strip() or "(provider default)"

    OUT_DIR.mkdir(parents=True, exist_ok=True)
    stamp = datetime.now().strftime("%Y%m%d-%H%M")
    path = OUT_DIR / f"review-{args.label}-{stamp}.html"
    path.write_text(render(results, args.label, model, datetime.now().strftime("%d %b %Y, %H:%M")),
                    encoding="utf-8")

    slowest = max(r["abstract_secs"] for r in results)
    print(f"\nWrote {path}")
    print(f"Slowest abstract: {slowest:.1f}s (the submit form times out at 45s)")


if __name__ == "__main__":
    main()
