#!/usr/bin/env python3
"""
report-application.py v2 — kelola aplikasi di BE (ANTRIAN queued → submitted).

ANTRIAN DIISI OLEH BE (priority/import/admin) — agent HANYA MENGAMBIL & MELAPORKAN.

Subperintah:
  pick    GET    /v1/agent/applications?status=queued&random=1&limit=N
                  → ambil lowongan ACAK dari antrian queued (agent tinggal lamar)
  update  PATCH  /v1/agent/applications/status  (--id <uuid> ATAU --job-url <url>)
                  → ubah status setelah selesai: submitted | failed | skipped | duplicate
                  (failed = sudah dicoba melamar tapi gagal; skipped = tidak dilamar)

Auth: X-Internal-Token (dari agent-config.env). Respons sukses BE dibungkus
{"data":{...}} — otomatis di-unwrap.

Contoh:
  # ambil 1 lowongan acak dari antrian
  python3 report-application.py pick

  # setelah sukses melamar → ubah status (by id ATAU by url+user_id)
  python3 report-application.py update --id <uuid> --status submitted
  python3 report-application.py update --job-url https://... --status submitted
"""
import argparse
import json
import sys
import urllib.error
import urllib.request
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent


def load_config():
    cfg = {}
    try:
        for line in (BASE_DIR / "agent-config.env").read_text().splitlines():
            line = line.strip()
            if line and "=" in line and not line.startswith("#"):
                k, _, v = line.partition("=")
                cfg[k.strip()] = v.strip()
    except FileNotFoundError:
        pass
    return cfg


def api(cfg, method, path, payload=None, timeout=15):
    url = cfg["BE_API_URL"].rstrip("/") + path
    data = json.dumps(payload).encode() if payload is not None else None
    req = urllib.request.Request(url, data=data, method=method, headers={
        "Content-Type": "application/json",
        "X-Internal-Token": cfg["BE_INTERNAL_TOKEN"],
    })
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            body = resp.read().decode() or "{}"
            try:
                d = json.loads(body)
            except Exception:
                d = {}
            if isinstance(d, dict) and "data" in d:
                d = d["data"]
            return {"ok": True, "status": resp.status, "data": d}
    except urllib.error.HTTPError as e:
        try:
            d = json.loads(e.read().decode() or "{}")
        except Exception:
            d = {}
        if isinstance(d, dict) and "data" in d:
            d = d["data"]
        return {"ok": False, "status": e.code, "data": d}
    except Exception as e:
        return {"ok": False, "status": 0, "data": {"error": str(e)}}


def cmd_update(cfg, args):
    payload = {"status": args.status}
    if args.id:
        payload["id"] = args.id
    elif args.job_url:
        payload["user_id"] = cfg["USER_ID"]
        payload["job_url"] = args.job_url
    else:
        print("WAJIB: --id <uuid> ATAU --job-url <url>", file=sys.stderr)
        return 2
    r = api(cfg, "PATCH", "/v1/agent/applications/status", payload)
    with open(BASE_DIR / "report-application.log", "a") as lf:
        lf.write(f"{__import__('datetime').datetime.now().isoformat()} update {payload} -> HTTP {r['status']}\n")
    if r["ok"]:
        print(f"OK: status → {args.status} (id={r['data'].get('id', '?')})")
        return 0
    if r["status"] == 403:
        print(f"QUOTA_EXCEEDED: {r['data'].get('error', {}).get('message', 'Kuota penuh.')}", file=sys.stderr)
        return 3
    if r["status"] == 404:
        print("NOT_FOUND: baris tidak ditemukan (id / url+user_id)", file=sys.stderr)
        return 5
    if r["status"] == 401:
        print("AUTH_FAIL: X-Internal-Token salah/berubah — cek agent-config.env", file=sys.stderr)
        return 2
    print(f"ERROR: HTTP {r['status']} {r['data']}", file=sys.stderr)
    return 1


def cmd_pick(cfg, args):
    q = f"user_id={cfg['USER_ID']}&status=queued&random=1&limit={args.limit}"
    r = api(cfg, "GET", f"/v1/agent/applications?{q}")
    if not r["ok"]:
        print(f"ERROR: HTTP {r['status']} {r['data']}", file=sys.stderr)
        return 1
    apps = r["data"].get("applications", r["data"].get("items", []))
    if not apps:
        print("ANTRIAN KOSONG")
        return 6
    for a in apps:
        print(json.dumps(a, ensure_ascii=False))
    return 0


def main():
    p = argparse.ArgumentParser(description="Kelola aplikasi di BE (ambil antrian queued → update status)")
    sub = p.add_subparsers(dest="cmd", required=True)

    pu = sub.add_parser("update", help="PATCH — ubah status (by id ATAU by url+user_id)")
    pu.add_argument("--id", default="")
    pu.add_argument("--job-url", default="")
    pu.add_argument("--status", required=True, choices=["submitted", "failed", "skipped", "duplicate"])
    pu.set_defaults(fn=cmd_update)

    pp = sub.add_parser("pick", help="GET — ambil acak dari antrian queued")
    pp.add_argument("--limit", type=int, default=1)
    pp.set_defaults(fn=cmd_pick)

    args = p.parse_args()
    cfg = load_config()
    if not cfg.get("BE_API_URL") or not cfg.get("BE_INTERNAL_TOKEN") or not cfg.get("USER_ID"):
        print("agent-config.env belum lengkap (BE_API_URL, BE_INTERNAL_TOKEN, USER_ID)", file=sys.stderr)
        return 2
    return args.fn(cfg, args)


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