#!/usr/bin/env python3
"""
notion-apikeys - Query Notion 'API' database for API keys
Usage:
  query.py <service_name>         Look up a service by name
  query.py --list                 List all entries
  query.py --find-db              Discover database structure/properties
  query.py --setup                Interactive setup (save token + db-id)
"""

import sys
import json
import os
import argparse

CONFIG_FILE = os.path.expanduser("~/.config/notion-apikeys.json")
NOTION_VERSION = "2022-06-28"
NOTION_BASE = "https://api.notion.com/v1"


def get_headers(token):
    return {
        "Authorization": f"Bearer {token}",
        "Notion-Version": NOTION_VERSION,
        "Content-Type": "application/json",
    }


def notion_request(method, path, token, payload=None):
    try:
        import urllib.request
        import urllib.error

        url = f"{NOTION_BASE}{path}"
        data = json.dumps(payload).encode() if payload is not None else None
        req = urllib.request.Request(url, data=data, headers=get_headers(token), method=method)
        with urllib.request.urlopen(req) as resp:
            return json.loads(resp.read())
    except Exception as e:
        if hasattr(e, "read"):
            err = e.read().decode()
            try:
                err = json.loads(err)
            except Exception:
                pass
            print(f"Notion API error: {err}", file=sys.stderr)
        else:
            print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def find_database(token, name="API"):
    result = notion_request("POST", "/search", token, {
        "query": name,
        "filter": {"value": "database", "property": "object"},
        "page_size": 20,
    })
    dbs = result.get("results", [])
    for db in dbs:
        title_parts = db.get("title", [])
        db_name = "".join(t.get("plain_text", "") for t in title_parts).strip()
        if db_name.lower() == name.lower():
            return db["id"], db_name, db.get("properties", {})
    # If no exact match, return all found
    return None, None, dbs


def query_database(token, db_id, filter_text=None):
    payload = {"page_size": 100}
    if filter_text:
        payload["filter"] = {
            "or": [
                {"property": "Name", "title": {"contains": filter_text}},
            ]
        }
    return notion_request("POST", f"/databases/{db_id}/query", token, payload)


def extract_value(prop):
    ptype = prop.get("type", "")
    if ptype == "title":
        return "".join(t.get("plain_text", "") for t in prop.get("title", []))
    elif ptype == "rich_text":
        return "".join(t.get("plain_text", "") for t in prop.get("rich_text", []))
    elif ptype in ("url", "email", "phone_number"):
        return prop.get(ptype) or ""
    elif ptype == "select":
        s = prop.get("select")
        return s.get("name", "") if s else ""
    elif ptype == "multi_select":
        return ", ".join(s.get("name", "") for s in prop.get("multi_select", []))
    elif ptype == "number":
        v = prop.get("number")
        return str(v) if v is not None else ""
    elif ptype == "checkbox":
        return "✓" if prop.get("checkbox") else "✗"
    elif ptype == "date":
        d = prop.get("date")
        return d.get("start", "") if d else ""
    return ""


def load_config():
    if os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE) as f:
            return json.load(f)
    return {}


def save_config(config):
    os.makedirs(os.path.dirname(CONFIG_FILE), exist_ok=True)
    with open(CONFIG_FILE, "w") as f:
        json.dump(config, f, indent=2)


def main():
    parser = argparse.ArgumentParser(description="Notion API key lookup")
    parser.add_argument("service", nargs="?", help="Service name to look up")
    parser.add_argument("--list", action="store_true", help="List all entries")
    parser.add_argument("--find-db", action="store_true", help="Discover DB structure")
    parser.add_argument("--setup", action="store_true", help="Save token + db-id to config")
    parser.add_argument("--token", help="Notion token (overrides config/env)")
    parser.add_argument("--db-id", help="Notion database ID (overrides config)")
    args = parser.parse_args()

    config = load_config()
    token = args.token or os.environ.get("NOTION_TOKEN") or config.get("token")
    db_id = args.db_id or config.get("database_id")

    # Setup mode
    if args.setup:
        if not token:
            token = input("Notion Integration Token (secret_...): ").strip()
        if not db_id:
            print("Finding 'API' database automatically...")
            found_id, found_name, _ = find_database(token, "API")
            if found_id:
                print(f"Found: '{found_name}' (ID: {found_id})")
                db_id = found_id
            else:
                db_id = input("Database ID (or leave blank to auto-find each time): ").strip()
        config["token"] = token
        if db_id:
            config["database_id"] = db_id
        save_config(config)
        print(f"✓ Config saved to {CONFIG_FILE}")
        return

    if not token:
        print("ERROR: Notion token required.", file=sys.stderr)
        print("  Run: query.py --setup", file=sys.stderr)
        print("  Or set: NOTION_TOKEN env var", file=sys.stderr)
        sys.exit(1)

    # Auto-discover database if needed
    if not db_id:
        found_id, found_name, found_dbs = find_database(token, "API")
        if found_id:
            db_id = found_id
        else:
            print("ERROR: Could not find 'API' database.", file=sys.stderr)
            print(f"Found databases: {[d.get('id') for d in found_dbs]}", file=sys.stderr)
            sys.exit(1)

    # Find database structure
    if args.find_db:
        found_id, found_name, props = find_database(token, "API")
        if found_id:
            print(f"Database: '{found_name}' (ID: {found_id})")
            print("Properties:")
            for name, prop in props.items():
                print(f"  • {name} ({prop.get('type', '?')})")
        return

    # Query
    filter_text = args.service if not args.list else None
    result = query_database(token, db_id, filter_text)
    pages = result.get("results", [])

    if not pages:
        label = f" for '{args.service}'" if args.service else ""
        print(f"No entries found{label}.")
        return

    for page in pages:
        props = page.get("properties", {})
        values = {k: extract_value(v) for k, v in props.items()}
        name = next((values[k] for k, v in props.items() if v.get("type") == "title"), "Unknown")
        print(f"\n── {name} ──")
        for k, val in values.items():
            if val and props[k].get("type") != "title":
                # Mask long keys for security in list mode
                if args.list and len(val) > 20 and k.lower() in ("key", "api key", "token", "secret", "value"):
                    val = val[:8] + "..." + val[-4:]
                print(f"  {k}: {val}")


if __name__ == "__main__":
    main()
