#!/usr/bin/env python3
"""
otp_watcher.py — standalone CLI entry point.

Run directly (python3 otp_watcher.py) when you want the watcher without
the menu bar UI. Reads config.json (auto-migrates .env credentials on
first run).

All IMAP logic lives in otp_service.py.
All config logic lives in config.py.
"""

import json
import os
import subprocess
import time
import threading
from datetime import datetime
from pathlib import Path

SEEN_UIDS_FILE = Path(__file__).parent / ".seen_uids.json"
_seen_lock     = threading.Lock()


# ── Seen UIDs persistence ─────────────────────────────────────────────────────

def load_seen_uids():
    if SEEN_UIDS_FILE.exists():
        try:
            return set(json.loads(SEEN_UIDS_FILE.read_text()))
        except Exception:
            pass
    return set()


def save_seen_uids(uids):
    with _seen_lock:
        recent = sorted(uids)[-500:]
        SEEN_UIDS_FILE.write_text(json.dumps(recent))


# ── Clipboard & notification (standalone mode) ────────────────────────────────

def copy_to_clipboard(text):
    subprocess.run(["pbcopy"], input=text.encode("utf-8"), check=True)


def notify(title, message):
    script = 'display notification "{}" with title "{}" sound name "Glass"'.format(
        message.replace('"', '\\"'),
        title.replace('"', '\\"'),
    )
    subprocess.run(["osascript", "-e", script], check=False)


# ── Standalone entry point ────────────────────────────────────────────────────

def run():
    from config import load as load_config
    from otp_service import OTPService

    cfg      = load_config()
    accounts = cfg.get("accounts", [])

    if not accounts:
        print("ERROR: No accounts configured. Open Settings or edit config.json.")
        return

    seen_uids    = load_seen_uids()
    refresh_mins = cfg.get("idle_refresh_minutes", 20)

    def on_otp(code, app_name, subject):
        print("[{}] OTP {} from {}  — \"{}\"".format(
            datetime.now().strftime("%H:%M:%S"), code, app_name, subject))
        copy_to_clipboard(code)
        notify("OTP for {}".format(app_name),
               "{} copied to clipboard".format(code))
        save_seen_uids(seen_uids)

    print("OTP Watcher — CLI mode")
    print("Accounts : {}".format(", ".join(a["email"] for a in accounts)))
    print("Refresh  : every {} minutes".format(refresh_mins))
    print("Press Ctrl+C to stop.\n")

    services = []
    for acc in accounts:
        svc = OTPService(
            email_addr           = acc["email"],
            app_password         = acc["app_password"],
            seen_uids            = seen_uids,
            on_otp               = on_otp,
            idle_refresh_minutes = refresh_mins,
        )
        svc.start()
        services.append(svc)

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("\nStopping...")
        for svc in services:
            svc.stop()
        print("Stopped.")


if __name__ == "__main__":
    run()
