"""
fit command — Find My Fit job market search.

Entry points:
  skilark fit <query>              — semantic search
  skilark fit --resume <path>      — resume upload
  skilark fit <query> --detail     — verbose output

The rendering logic is extracted into ``run_fit()`` so tests can call it
directly with a mock client without touching ConfigStore or performing
network I/O.
"""

from pathlib import Path

import httpx
from rich.console import Console
from rich.markup import escape

from skilark_cli.client import SkilarkClient
from skilark_cli.config_store import ConfigStore
from skilark_cli.display import render_fit_compact, render_fit_detail

console = Console()

_MAX_RESUME_BYTES = 5 * 1024 * 1024  # 5 MB
_PDF_MAGIC = b"%PDF-"

_USAGE = """\
Usage: skilark fit <query>
       skilark fit --resume <path.pdf>

Options:
  --resume <path>  Upload a PDF resume for personalized analysis
  --detail         Show full breakdown (seniority, remote, all positions)

Examples:
  skilark fit senior backend engineer with Go
  skilark fit --resume ~/resume.pdf
  skilark fit data engineer --detail
"""


def dispatch(fit_args: list[str]) -> None:
    """Entry point called from main.py for ``skilark fit``.

    Handles config loading, client setup, and flag parsing, then delegates
    to ``run_fit()``.  Exits early with a friendly message if the user has
    not yet completed onboarding.

    Args:
        fit_args: Remaining argv after the ``fit`` token.  Recognises the
                  ``--resume <path>``, and ``--detail`` flags.
    """
    config_store = ConfigStore()

    if config_store.is_first_run():
        console.print("[dim]Run 'skilark today' first to get started.[/dim]")
        return

    # Strip --detail before further parsing
    detail = "--detail" in fit_args
    args = [a for a in fit_args if a != "--detail"]

    resume_path: str | None = None
    query: str | None = None

    if "--resume" in args:
        idx = args.index("--resume")
        if idx + 1 < len(args):
            resume_path = args[idx + 1]
        else:
            console.print("[red]--resume requires a file path[/red]")
            return
    else:
        if args:
            query = " ".join(args)

    if not query and not resume_path:
        console.print(_USAGE)
        return

    config = config_store.load()
    client = SkilarkClient(base_url=config["api_url"], user_id=config.get("user_id"))

    run_fit(client, query=query, resume_path=resume_path, detail=detail)


def run_fit(
    client: SkilarkClient,
    *,
    query: str | None,
    resume_path: str | None,
    detail: bool,
) -> None:
    """Fetch and render Find My Fit results.

    Separated from ``dispatch()`` so tests can inject a mock client and verify
    output without touching the filesystem or network.

    Args:
        client:      SkilarkClient instance (or mock in tests).
        query:       Free-text search query (mutually exclusive with resume_path).
        resume_path: Local path to a PDF resume file (mutually exclusive with query).
        detail:      When True, renders the full breakdown via render_fit_detail;
                     otherwise uses the compact summary via render_fit_compact.
    """
    # Validate resume file before hitting the network
    if resume_path:
        path = Path(resume_path)
        if not path.exists():
            console.print(f"[red]File not found: {escape(resume_path)}[/red]")
            return
        if path.suffix.lower() != ".pdf":
            console.print("[red]Only PDF files are supported. Please provide a .pdf file.[/red]")
            return
        if path.stat().st_size > _MAX_RESUME_BYTES:
            console.print("[red]Resume file exceeds the 5 MB limit. Please upload a smaller file.[/red]")
            return
        with path.open("rb") as _f:
            magic = _f.read(5)
        if magic != _PDF_MAGIC:
            console.print("[red]File does not appear to be a valid PDF (missing PDF header).[/red]")
            return

    try:
        with console.status("[bold]Finding your fit...[/bold]"):
            if resume_path:
                data = client.find_my_fit_resume(resume_path)
            else:
                data = client.find_my_fit(query)
    except httpx.HTTPStatusError as exc:
        if exc.response.status_code == 503:
            console.print("[red]Find My Fit is temporarily unavailable. Try again later.[/red]")
        else:
            console.print(
                f"[red]Search failed (HTTP {exc.response.status_code}). Try again later.[/red]"
            )
        return
    except Exception:
        console.print("[red]Search failed. Check your connection and try again.[/red]")
        return

    if detail:
        render_fit_detail(console, data)
    else:
        render_fit_compact(console, data)
