"""CLI entry point — filter Gmail messages by sender."""

import argparse
import os
import time

from mail_connector import GmailConnector


def _format_size(size_bytes: int) -> str:
    """Format byte size as human-readable string."""
    if size_bytes < 1024:
        return f"{size_bytes} o"
    return f"{size_bytes / 1024:.0f} Ko"


def _print_messages(
    gmail: GmailConnector, messages: list[dict], download_dir: str | None = None
) -> None:
    """Print subject and date for each message, optionally downloading attachments."""
    for stub in messages:
        msg_id = stub["id"]
        msg = gmail.get_message(msg_id)
        headers = {h["name"]: h["value"] for h in msg["payload"].get("headers", [])}
        subject = headers.get("Subject", "(no subject)")
        date = headers.get("Date", "")

        attachments = gmail.list_attachments(msg_id) if download_dir else []
        if not attachments:
            print(f"[{date}] {subject}")
            continue

        downloaded = []
        for att in attachments:
            data = gmail.download_attachment(msg_id, att["attachmentId"])
            filepath = os.path.join(download_dir, att["filename"])
            with open(filepath, "wb") as f:
                f.write(data)
            downloaded.append(f"{att['filename']} ({_format_size(len(data))})")

        print(f"[{date}] {subject} → {', '.join(downloaded)}")


def main(argv: list[str] | None = None) -> None:
    """List messages from a specific sender."""
    parser = argparse.ArgumentParser(description="List Gmail messages from a specific sender.")
    parser.add_argument("sender", help="Sender email address to filter by")
    parser.add_argument("-n", "--max-results", type=int, default=10, help="Max messages to return (default: 10)")
    parser.add_argument("-w", "--watch", action="store_true", help="Watch for new messages continuously")
    parser.add_argument("-i", "--interval", type=int, default=60, help="Polling interval in seconds (default: 60)")
    parser.add_argument("-d", "--download-dir", help="Download attachments to this directory")
    args = parser.parse_args(argv)

    if args.download_dir:
        os.makedirs(args.download_dir, exist_ok=True)

    gmail = GmailConnector()
    query = f"from:{args.sender}"

    if not args.watch:
        messages = gmail.list_messages(query=query, max_results=args.max_results)
        if not messages:
            print(f"No messages from {args.sender}")
            return
        _print_messages(gmail, messages, args.download_dir)
        return

    # Watch mode: poll for new messages
    seen: set[str] = set()

    # Seed with existing message IDs
    existing = gmail.list_messages(query=query, max_results=args.max_results)
    for stub in existing:
        seen.add(stub["id"])
    print(f"Watching for new messages from {args.sender} (every {args.interval}s, Ctrl+C to stop)", flush=True)

    while True:
        time.sleep(args.interval)
        messages = gmail.list_messages(query=query, max_results=args.max_results)
        new = [m for m in messages if m["id"] not in seen]
        if new:
            _print_messages(gmail, new, args.download_dir)
            for m in new:
                seen.add(m["id"])


if __name__ == "__main__":
    main()
