#!/usr/bin/env python3
import argparse
import json
import os
import re
import urllib.request
from datetime import datetime, timezone

NOTION_VERSION = "2025-09-03"
MC_DS = os.environ.get("MEMORY_CANDIDATES_DS_ID", "c9d26639-dde4-41cd-8bc8-1a5623f6c4cf")


def notion_request(method, path, payload=None):
    key = open(os.path.expanduser("~/.config/notion/api_key"), "r", encoding="utf-8").read().strip()
    data = json.dumps(payload).encode("utf-8") if payload is not None else None
    req = urllib.request.Request(
        f"https://api.notion.com/v1{path}",
        data=data,
        method=method,
        headers={
            "Authorization": f"Bearer {key}",
            "Notion-Version": NOTION_VERSION,
            "Content-Type": "application/json",
        },
    )
    with urllib.request.urlopen(req, timeout=45) as r:
        return json.loads(r.read().decode("utf-8"))


def get_text(props, name, kind="rich_text"):
    if name not in props:
        return ""
    val = props.get(name, {}).get(kind, [])
    if kind == "title":
        return "".join(x.get("plain_text", "") for x in val).strip()
    return "".join(x.get("plain_text", "") for x in val).strip()


def is_plaud_row(props):
    if get_text(props, "Plaud Record ID", "rich_text"):
        return True
    notes = get_text(props, "Notes", "rich_text").lower()
    return "plaud" in notes


def identity_score(text: str) -> int:
    t = (text or "").lower()
    score = 0
    strong = [
        "braden", "he prefers", "he values", "leadership", "coaches", "mentor",
        "communication", "style", "habit", "routine", "approach", "family", "children",
        "decision", "philosophy", "proactive", "conflict", "belief",
    ]
    for s in strong:
        if s in t:
            score += 12
    if re.search(r"\b(always|usually|consistently|tends to)\b", t):
        score += 10
    if len(t.split()) < 6:
        score -= 20
    if any(x in t for x in ["today", "this meeting", "at 3pm", "yesterday"]):
        score -= 10
    return max(0, min(100, score))


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--apply", action="store_true")
    ap.add_argument("--min-score", type=int, default=36)
    args = ap.parse_args()

    cursor = None
    scanned = plaud_rows = reclassified = 0
    skipped_low = 0

    while True:
        body = {"page_size": 100}
        if cursor:
            body["start_cursor"] = cursor
        page = notion_request("POST", f"/data_sources/{MC_DS}/query", body)

        for row in page.get("results", []):
            scanned += 1
            page_id = row.get("id")
            props = row.get("properties", {})
            if not is_plaud_row(props):
                continue
            plaud_rows += 1

            name = get_text(props, "Name", "title")
            excerpt = get_text(props, "Source Excerpt", "rich_text")
            text = name or excerpt
            score = identity_score(text)
            if score < args.min_score:
                skipped_low += 1
                continue

            confidence = "High" if score >= 60 else "Medium"
            note = f"Plaud identity reclass score={score} at {datetime.now(timezone.utc).isoformat()}"
            patch_props = {
                "Type": {"select": {"name": "Fact"}},
                "Confidence": {"select": {"name": confidence}},
            }
            # append/update Notes safely as replacement text
            existing_notes = get_text(props, "Notes", "rich_text")
            merged = (existing_notes + "\n" + note).strip()[:1800]
            patch_props["Notes"] = {"rich_text": [{"type": "text", "text": {"content": merged}}]}

            if args.apply:
                notion_request("PATCH", f"/pages/{page_id}", {"properties": patch_props})
            reclassified += 1

        if not page.get("has_more"):
            break
        cursor = page.get("next_cursor")

    print(json.dumps({
        "apply": args.apply,
        "scanned": scanned,
        "plaud_rows": plaud_rows,
        "reclassified": reclassified,
        "skipped_low_score": skipped_low,
        "min_score": args.min_score,
    }, indent=2))


if __name__ == "__main__":
    main()
