#!/usr/bin/env python3
"""odysseus-contacts — Unix-style CLI for the contacts feature.

Talks to the same CardDAV server the web UI does, using credentials
from `data/settings.json` (set via the Settings → Connections panel).
Output is JSON on stdout, errors on stderr, non-zero exit on failure.

    odysseus-contacts list | jq -r '.[] | .name + "\\t" + .email'
    odysseus-contacts search alice
    odysseus-contacts add --name "Alice Doe" --email alice@example.com

Subcommands:
    list      List all contacts
    search    Filter contacts by case-insensitive substring match
    add       Add a new contact (name + email)
    config    Show the current CardDAV config (URL/user; password masked)
"""


from __future__ import annotations
import sys
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "_lib"))
from cli import quiet_logs, emit, fail, common_parser, run, REPO_ROOT as _REPO_ROOT
quiet_logs()


import argparse
import json
import logging
import os
import sys
from pathlib import Path

def quiet_logs() -> None:
    level_name = os.environ.get("LOG_LEVEL", "WARNING").upper()
    level = getattr(logging, level_name, logging.WARNING)
    root = logging.getLogger()
    root.setLevel(level)
    for handler in root.handlers:
        handler.setLevel(level)


quiet_logs()

try:
    from routes.contacts_routes import (
        _get_carddav_config,
        _fetch_contacts,
        _create_contact,
    )
    quiet_logs()
except ModuleNotFoundError as e:
    sys.stderr.write(f"error: {e}\nhint: run from repo root with venv active.\n")
    sys.exit(2)


def fail(msg: str, code: int = 1) -> None:
    sys.stderr.write(f"error: {msg}\n")
    sys.exit(code)


def _contact_rows(contacts):
    return [c for c in contacts or [] if isinstance(c, dict)]


# ─── list ────────────────────────────────────────────────────────────

def cmd_list(args) -> None:
    cfg = _get_carddav_config()
    if not cfg["url"]:
        fail("CardDAV not configured. Set carddav_url/username/password in the web UI.")
    contacts = _contact_rows(_fetch_contacts(force=args.refresh))
    emit(contacts, args)


# ─── search ──────────────────────────────────────────────────────────

def cmd_search(args) -> None:
    cfg = _get_carddav_config()
    if not cfg["url"]:
        fail("CardDAV not configured.")
    q = args.query.lower()
    contacts = _contact_rows(_fetch_contacts())
    matches = [
        c for c in contacts
        if q in (c.get("name") or "").lower() or q in (c.get("email") or "").lower()
    ]
    emit(matches, args)


# ─── add ─────────────────────────────────────────────────────────────

def cmd_add(args) -> None:
    cfg = _get_carddav_config()
    if not cfg["url"]:
        fail("CardDAV not configured.")
    ok = _create_contact(args.name, args.email)
    if not ok:
        fail("CardDAV PUT failed (see LOG_LEVEL=DEBUG for detail)")
    emit({"ok": True, "name": args.name, "email": args.email}, args)


# ─── config ──────────────────────────────────────────────────────────

def cmd_config(args) -> None:
    cfg = _get_carddav_config()
    safe = dict(cfg)
    if safe.get("password"):
        safe["password"] = "***"
    emit(safe, args)


# ─── argparse ────────────────────────────────────────────────────────

def _build_parser() -> argparse.ArgumentParser:
    common = argparse.ArgumentParser(add_help=False)
    common.add_argument("--pretty", action="store_true", help="Pretty-print JSON")

    p = argparse.ArgumentParser(
        prog="odysseus-contacts",
        description="Shell-friendly wrapper around the Odysseus contacts (CardDAV) feature.",
        parents=[common],
    )
    sub = p.add_subparsers(dest="cmd", required=True)

    pl = sub.add_parser("list", help="list all contacts", parents=[common])
    pl.add_argument("--refresh", action="store_true", help="bypass cache and re-fetch")
    pl.set_defaults(func=cmd_list)

    ps = sub.add_parser("search", help="filter by name/email substring", parents=[common])
    ps.add_argument("query")
    ps.set_defaults(func=cmd_search)

    pa = sub.add_parser("add", help="add a new contact", parents=[common])
    pa.add_argument("--name", required=True)
    pa.add_argument("--email", required=True)
    pa.set_defaults(func=cmd_add)

    pc = sub.add_parser("config", help="show CardDAV config (password masked)", parents=[common])
    pc.set_defaults(func=cmd_config)

    return p


if __name__ == "__main__":
    sys.exit(run(_build_parser()))
