"""Review CLI command — paginated, numbered list for rapid operator review.

Interactive mode: displays drafted leads with tags, subjects, and previews.
Operator issues quick commands against page-relative numbers.
"""

import typer
from typing import Optional

from state.backlog import (
    get_drafted_leads,
    burn_lead,
    pause_lead,
    clear_draft,
    approve_lead,
    increment_regen_count,
    get_lead,
)
from capabilities.drafting import draft_touch, _compute_signal_tier
from integrations.ctsos import FILING_SERVICE_DOMAINS


def _get_tag(lead: dict) -> str:
    """Get display tag from lead's draft_scenario or temporal_category + milestone."""
    scenario = lead.get("draft_scenario", "")
    if scenario:
        if scenario.startswith("milestone_"):
            yr = scenario.replace("milestone_", "").replace("yr", "")
            return f"{yr}-YR"
        elif scenario == "new_filing":
            return "FRESH"
        elif scenario == "recent_operating":
            return "RECENT"
        elif scenario == "established_business":
            return "EST"

    temporal = lead.get("temporal_category", "")
    if temporal == "fresh":
        return "FRESH"
    elif temporal == "recent":
        return "RECENT"
    elif temporal == "historical":
        milestone = lead.get("milestone_year")
        if milestone:
            return f"{milestone}-YR"
        return "EST"

    return "EST"


def _preview(body: str, max_len: int = 120) -> str:
    """Get first max_len characters of body, with ... if truncated."""
    if not body:
        return ""
    clean = body.strip().replace("\n", " ")
    if len(clean) > max_len:
        return clean[:max_len] + "..."
    return clean


def _is_outside_sales(lead: dict) -> bool:
    """Check if lead has no usable email and needs outside sales routing."""
    if lead.get("email_is_filing_service", False):
        phone = lead.get("phone", "") or lead.get("domain_phone", "") or lead.get("brave_phone", "")
        return not bool(phone)
    return False


def _render_page(leads: list, page: int, page_size: int) -> None:
    """Render a page of drafted leads."""
    total = len(leads)
    total_pages = max(1, (total + page_size - 1) // page_size)
    start = page * page_size
    end = min(start + page_size, total)
    page_leads = leads[start:end]

    print(f"\n=== Draft Review (Page {page + 1}/{total_pages}) — {total} drafted leads ===")
    print(f"Showing {start + 1}-{end}\n")

    for i, lead in enumerate(page_leads, 1):
        tag = _get_tag(lead)
        subject = lead.get("draft_subject", "")
        body = lead.get("draft_body", "")
        preview = _preview(body)
        approved = "✓ " if lead.get("reviewed_at") else ""

        stars, _ = _compute_signal_tier(lead)
        outside = "⚠ OUTSIDE SALES  " if _is_outside_sales(lead) else ""

        print(f" #{i:2d}  [{tag}] {stars}  {outside}{approved}{subject}")
        print(f"      \"{preview}\"")
        print()

    print("--- Commands: burn #N [reason] | pause #N | delete #N | regen #N | approve #N | next | prev | quit ---\n")


def _parse_command(cmd_input: str) -> tuple:
    """Parse command input into (command, number, reason).

    Returns:
        Tuple of (command_str, number_or_None, reason_str)
    """
    parts = cmd_input.strip().split(None, 2)
    if not parts:
        return ("", None, "")

    command = parts[0].lower()
    number = None
    reason = parts[2] if len(parts) > 2 else ""

    if len(parts) > 1:
        num_str = parts[1].lstrip("#")
        try:
            number = int(num_str)
        except ValueError:
            pass

    return (command, number, reason)


def _run_review(leads: list, page_size: int) -> None:
    """Interactive review loop."""
    page = 0
    total_pages = max(1, (len(leads) + page_size - 1) // page_size)

    while True:
        _render_page(leads, page, page_size)

        try:
            cmd_input = input(">>> ")
        except (EOFError, KeyboardInterrupt):
            print("\nExiting review.")
            return

        command, number, reason = _parse_command(cmd_input)

        if command in ("quit", "q"):
            print("Exiting review.")
            return

        if command == "next":
            if page < total_pages - 1:
                page += 1
            else:
                print("Already on last page.")
            continue

        if command == "prev":
            if page > 0:
                page -= 1
            else:
                print("Already on first page.")
            continue

        if command in ("burn", "pause", "delete", "regen", "approve"):
            if number is None:
                print(f"Usage: {command} #N [reason]" if command in ("burn", "pause") else f"Usage: {command} #N")
                continue

            start = page * page_size
            end = min(start + page_size, len(leads))
            if number < 1 or number > (end - start):
                print(f"No lead #{number} on this page (showing {start + 1}-{end}).")
                continue

            lead = leads[start + number - 1]
            lead_id = lead["id"]

            if command == "burn":
                try:
                    burn_lead(lead_id, reason=reason)
                    leads.pop(start + number - 1)
                    total_pages = max(1, (len(leads) + page_size - 1) // page_size)
                    if page >= total_pages:
                        page = total_pages - 1
                    print(f"BURNED: {lead['name']}")
                except Exception as e:
                    print(f"Error: {e}")

            elif command == "pause":
                try:
                    pause_lead(lead_id, reason=reason)
                    leads.pop(start + number - 1)
                    total_pages = max(1, (len(leads) + page_size - 1) // page_size)
                    if page >= total_pages:
                        page = total_pages - 1
                    print(f"PAUSED: {lead['name']}")
                except Exception as e:
                    print(f"Error: {e}")

            elif command == "delete":
                try:
                    clear_draft(lead_id)
                    leads.pop(start + number - 1)
                    total_pages = max(1, (len(leads) + page_size - 1) // page_size)
                    if page >= total_pages:
                        page = total_pages - 1
                    print(f"DELETED draft: {lead['name']}")
                except Exception as e:
                    print(f"Error: {e}")

            elif command == "regen":
                try:
                    clear_draft(lead_id)
                    regen_count = increment_regen_count(lead_id)
                    print(f"Regenerating #{number}... (regen count: {regen_count})")
                    result = draft_touch(lead_id)
                    lead["draft_subject"] = result["subject"]
                    lead["draft_body"] = result["body"]
                    lead["draft_anchor"] = result["anchor"]
                    lead["draft_status"] = "drafted"
                    lead["reviewed_at"] = ""
                    tag = _get_tag(lead)
                    preview = _preview(result["body"])
                    print(f"Regenerated #{number}:")
                    print(f"  [{tag}] {result['subject']}")
                    print(f"  \"{preview}\"")
                except Exception as e:
                    print(f"Error: {e}")

            elif command == "approve":
                try:
                    if lead.get("email_is_filing_service", False):
                        phone = lead.get("phone", "") or lead.get("domain_phone", "") or lead.get("brave_phone", "")
                        if not phone:
                            print(f"REJECTED: {lead['name']} — no usable email (filing service address) and no phone. Route to outside sales or enrich with a real email first.")
                            continue

                    approve_lead(lead_id)
                    lead["reviewed_at"] = "just now"
                    print(f"APPROVED: {lead['name']}")
                except Exception as e:
                    print(f"Error: {e}")

            continue

        if cmd_input.strip():
            print(f"Unknown command: '{command}'. Use: burn, pause, delete, regen, approve, next, prev, quit")


def _filter_strong_only(leads: list) -> list:
    """Filter leads to only those with ★★+ signal tier."""
    return [
        lead for lead in leads
        if _compute_signal_tier(lead)[1] in ("Strong", "Good")
    ]


def review_command(
    category: Optional[str] = typer.Option(None, "--category", "-c", help="Filter by temporal category: fresh, recent, historical"),
    page_size: int = typer.Option(25, "--page-size", "-p", help="Leads per page"),
    strong_only: bool = typer.Option(False, "--strong-only", help="Show only ★★+ leads"),
):
    """Interactive review of drafted emails.

    Displays a numbered list of drafted leads. Use quick commands
    to burn, pause, delete, regen, or approve leads by number.
    """
    leads = get_drafted_leads(category=category)

    if strong_only:
        leads = _filter_strong_only(leads)

    if not leads:
        filter_msg = []
        if category:
            filter_msg.append(f"category: {category}")
        if strong_only:
            filter_msg.append("★★+ only")
        filter_str = f" ({', '.join(filter_msg)})" if filter_msg else ""
        print(f"No drafted leads found{filter_str}.")
        return

    label = "★★+ " if strong_only else ""
    print(f"Found {len(leads)} {label}drafted leads.")
    _run_review(leads, page_size)
