"""
TurboSEO CLI

Command-line interface for TurboSEO content analysis.
"""

import json
from pathlib import Path

import click
from rich.console import Console
from rich.panel import Panel
from rich.prompt import Confirm, Prompt
from rich.table import Table

import turboseo
from turboseo.analyzers.content_scrubber import scrub_content
from turboseo.analyzers.keywords import analyze_keywords
from turboseo.analyzers.readability import analyze_readability
from turboseo.analyzers.seo_score import analyze_seo
from turboseo.analyzers.writing_standards import analyze_writing_standards
from turboseo.config import (
    ProjectConfig,
    add_project,
    create_gitignore_entry,
    find_project_root,
    get_config_dir,
    list_projects,
    load_config,
    remove_project,
    save_config,
)

console = Console()


@click.group()
@click.version_option(version=turboseo.__version__, prog_name="turboseo")
def cli():
    """TurboSEO - SEO content toolkit that writes human, not AI."""
    pass


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--strict", is_flag=True, help="Use stricter thresholds")
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def check(file: str, strict: bool, output_json: bool):
    """Check content for AI writing patterns."""
    content = Path(file).read_text()
    result = analyze_writing_standards(content, strict=strict)

    if output_json:
        console.print(json.dumps(result.model_dump(), indent=2))
        return

    # Score and grade panel
    grade_colors = {"A": "green", "B": "blue", "C": "yellow", "D": "orange1", "F": "red"}
    grade_color = grade_colors.get(result.grade, "white")

    console.print(
        Panel(
            f"[bold {grade_color}]Grade: {result.grade}[/] | "
            f"Score: {result.score}/100 | "
            f"Words: {result.word_count}",
            title="Human Writing Check",
        )
    )

    if not result.issues:
        console.print("[green]No AI writing patterns detected.[/green]")
        return

    # Issues table
    table = Table(show_header=True, header_style="bold")
    table.add_column("Line", style="dim", width=6)
    table.add_column("Category", width=12)
    table.add_column("Issue", width=30)
    table.add_column("Suggestion", width=40)

    severity_colors = {"high": "red", "medium": "yellow", "low": "dim"}

    for issue in result.issues:
        color = severity_colors.get(issue.severity, "white")
        table.add_row(
            str(issue.line),
            f"[{color}]{issue.category}[/]",
            issue.text[:30],
            issue.suggestion[:40] if len(issue.suggestion) > 40 else issue.suggestion,
        )

    console.print(table)

    # Summary
    if result.summary:
        summary_parts = [f"{cat}: {count}" for cat, count in result.summary.items()]
        console.print(f"\n[dim]Summary: {', '.join(summary_parts)}[/dim]")


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--keyword", "-k", help="Primary keyword")
@click.option("--secondary", "-s", multiple=True, help="Secondary keywords")
@click.option("--title", help="Meta title")
@click.option("--description", help="Meta description")
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def analyze(
    file: str,
    keyword: str | None,
    secondary: tuple,
    title: str | None,
    description: str | None,
    output_json: bool,
):
    """Full SEO analysis of content."""
    content = Path(file).read_text()
    result = analyze_seo(
        content,
        primary_keyword=keyword,
        secondary_keywords=list(secondary) if secondary else None,
        meta_title=title,
        meta_description=description,
    )

    if output_json:
        console.print(json.dumps(result.model_dump(), indent=2))
        return

    # Grade colors
    grade_colors = {"A": "green", "B": "blue", "C": "yellow", "D": "orange1", "F": "red"}
    grade_color = grade_colors.get(result.grade, "white")

    # Header panel
    ready_indicator = "[green]✓ Ready[/]" if result.publishing_ready else "[red]✗ Not Ready[/]"
    console.print(
        Panel(
            f"[bold {grade_color}]Grade: {result.grade}[/] | "
            f"Score: {result.overall_score}/100 | "
            f"Publishing: {ready_indicator}",
            title="SEO Analysis",
        )
    )

    # Category scores table
    cat_table = Table(show_header=True, header_style="bold", title="Category Breakdown")
    cat_table.add_column("Category", width=20)
    cat_table.add_column("Score", width=10)
    cat_table.add_column("Weight", width=10)
    cat_table.add_column("Weighted", width=10)

    category_order = ["human_writing", "keywords", "content", "readability", "meta", "structure"]
    category_labels = {
        "human_writing": "Human Writing",
        "keywords": "Keywords",
        "content": "Content",
        "readability": "Readability",
        "meta": "Meta Tags",
        "structure": "Structure",
    }

    for cat_key in category_order:
        if cat_key in result.categories:
            cat = result.categories[cat_key]
            score_color = "green" if cat.score >= 80 else "yellow" if cat.score >= 60 else "red"
            cat_table.add_row(
                category_labels.get(cat_key, cat_key),
                f"[{score_color}]{cat.score}[/]",
                f"{cat.weight:.0%}",
                f"{cat.weighted_score:.1f}",
            )

    console.print(cat_table)

    # Structure info
    console.print(
        f"\n[dim]Content: {result.word_count} words | "
        f"H1: {result.h1_count} | H2: {result.h2_count} | H3: {result.h3_count}[/dim]"
    )

    # Critical issues
    if result.critical_issues:
        console.print("\n[bold red]Critical Issues:[/bold red]")
        for issue in result.critical_issues:
            console.print(f"  [red]✗[/red] {issue}")

    # Warnings
    if result.warnings:
        console.print("\n[bold yellow]Warnings:[/bold yellow]")
        for warning in result.warnings:
            console.print(f"  [yellow]![/yellow] {warning}")

    # Suggestions (limit to top 5)
    if result.suggestions:
        console.print("\n[bold]Suggestions:[/bold]")
        for suggestion in result.suggestions[:5]:
            console.print(f"  [dim]•[/dim] {suggestion}")
        if len(result.suggestions) > 5:
            console.print(f"  [dim]... and {len(result.suggestions) - 5} more[/dim]")


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def readability(file: str, output_json: bool):
    """Analyze content readability."""
    content = Path(file).read_text()
    result = analyze_readability(content)

    if output_json:
        console.print(json.dumps(result.model_dump(), indent=2))
        return

    # Score and grade panel
    grade_colors = {"A": "green", "B": "blue", "C": "yellow", "D": "orange1", "F": "red"}
    grade_color = grade_colors.get(result.grade, "white")
    status_colors = {"excellent": "green", "good": "blue", "needs_improvement": "yellow", "poor": "red"}
    status_color = status_colors.get(result.status, "white")

    console.print(
        Panel(
            f"[bold {grade_color}]Grade: {result.grade}[/] | "
            f"Score: {result.score}/100 | "
            f"Status: [{status_color}]{result.status.replace('_', ' ').title()}[/]",
            title="Readability Analysis",
        )
    )

    # Metrics table
    metrics_table = Table(show_header=True, header_style="bold", title="Core Metrics")
    metrics_table.add_column("Metric", width=25)
    metrics_table.add_column("Value", width=10)
    metrics_table.add_column("Target", width=15)

    # Color code Flesch Reading Ease
    fre = result.flesch_reading_ease
    fre_color = "green" if 60 <= fre <= 70 else "yellow" if 50 <= fre <= 80 else "red"
    metrics_table.add_row("Flesch Reading Ease", f"[{fre_color}]{fre}[/]", "60-70")

    # Color code grade level
    gl = result.flesch_kincaid_grade
    gl_color = "green" if 8 <= gl <= 10 else "yellow" if 6 <= gl <= 12 else "red"
    metrics_table.add_row("Flesch-Kincaid Grade", f"[{gl_color}]{gl}[/]", "8-10")

    metrics_table.add_row("Gunning Fog Index", str(result.gunning_fog), "-")
    metrics_table.add_row("SMOG Index", str(result.smog_index), "-")

    console.print(metrics_table)

    # Structure table
    struct_table = Table(show_header=True, header_style="bold", title="Structure")
    struct_table.add_column("Metric", width=25)
    struct_table.add_column("Value", width=10)
    struct_table.add_column("Target", width=15)

    asl = result.avg_sentence_length
    asl_color = "green" if asl <= 20 else "yellow" if asl <= 25 else "red"
    struct_table.add_row("Avg Sentence Length", f"[{asl_color}]{asl} words[/]", "15-20 words")

    struct_table.add_row("Avg Paragraph Length", f"{result.avg_paragraph_length} sentences", "2-4 sentences")
    struct_table.add_row("Total Sentences", str(result.sentence_count), "-")
    struct_table.add_row("Total Words", str(result.word_count), "-")

    if result.very_long_sentence_count > 0:
        struct_table.add_row(
            "Very Long Sentences (>35w)",
            f"[red]{result.very_long_sentence_count}[/]",
            "0"
        )
    elif result.long_sentence_count > 0:
        struct_table.add_row(
            "Long Sentences (>25w)",
            f"[yellow]{result.long_sentence_count}[/]",
            "Few"
        )

    console.print(struct_table)

    # Complexity table
    if result.passive_voice_count > 0 or result.transition_word_count > 0:
        complex_table = Table(show_header=True, header_style="bold", title="Complexity")
        complex_table.add_column("Metric", width=25)
        complex_table.add_column("Value", width=15)
        complex_table.add_column("Target", width=15)

        pv_pct = result.passive_voice_ratio * 100
        pv_color = "green" if pv_pct < 15 else "yellow" if pv_pct <= 20 else "red"
        complex_table.add_row(
            "Passive Voice",
            f"[{pv_color}]{pv_pct:.0f}% ({result.passive_voice_count})[/]",
            "<20%"
        )

        complex_table.add_row(
            "Complex Words (3+ syl)",
            f"{result.complex_word_ratio * 100:.0f}%",
            "-"
        )
        complex_table.add_row("Transition Words", str(result.transition_word_count), "Several")

        console.print(complex_table)

    # Recommendations
    if result.recommendations:
        console.print("\n[bold]Recommendations:[/bold]")
        for rec in result.recommendations:
            console.print(f"  [yellow]•[/yellow] {rec}")


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--keyword", "-k", required=True, help="Primary keyword")
@click.option("--secondary", "-s", multiple=True, help="Secondary keywords")
@click.option("--target-density", "-d", default=1.5, help="Target density %")
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def keywords(
    file: str, keyword: str, secondary: tuple, target_density: float, output_json: bool
):
    """Analyze keyword usage."""
    content = Path(file).read_text()
    result = analyze_keywords(
        content,
        primary_keyword=keyword,
        secondary_keywords=list(secondary) if secondary else None,
        target_density=target_density,
    )

    if output_json:
        console.print(json.dumps(result.model_dump(), indent=2))
        return

    # Status colors
    status_colors = {
        "optimal": "green",
        "slightly_low": "yellow",
        "slightly_high": "yellow",
        "too_low": "red",
        "too_high": "red",
    }
    risk_colors = {"none": "green", "low": "yellow", "medium": "orange1", "high": "red"}

    # Header panel
    p = result.primary
    status_color = status_colors.get(p.status, "white")
    risk_color = risk_colors.get(result.stuffing_risk.level, "white")

    console.print(
        Panel(
            f"[bold]Keyword:[/bold] {p.keyword} | "
            f"Density: [{status_color}]{p.density:.1f}%[/] (target: {p.target_density}%) | "
            f"Status: [{status_color}]{p.status.replace('_', ' ').title()}[/] | "
            f"Stuffing Risk: [{risk_color}]{result.stuffing_risk.level.title()}[/]",
            title="Keyword Analysis",
        )
    )

    # Placements table
    pl = p.placements
    place_table = Table(show_header=True, header_style="bold", title="Critical Placements")
    place_table.add_column("Location", width=20)
    place_table.add_column("Status", width=15)

    place_table.add_row(
        "H1 (Title)",
        "[green]✓ Found[/]" if pl.in_h1 else "[red]✗ Missing[/]"
    )
    place_table.add_row(
        "First 100 Words",
        "[green]✓ Found[/]" if pl.in_first_100_words else "[red]✗ Missing[/]"
    )
    place_table.add_row(
        "Conclusion",
        "[green]✓ Found[/]" if pl.in_conclusion else "[red]✗ Missing[/]"
    )
    if pl.h2_count > 0:
        h2_status = f"{pl.h2_with_keyword}/{pl.h2_count} H2s"
        h2_color = "green" if pl.h2_with_keyword >= 2 else "yellow" if pl.h2_with_keyword >= 1 else "red"
        place_table.add_row("H2 Headings", f"[{h2_color}]{h2_status}[/]")

    console.print(place_table)

    # Distribution table (if there are sections)
    if result.distribution:
        dist_table = Table(show_header=True, header_style="bold", title="Section Distribution")
        dist_table.add_column("Section", width=25)
        dist_table.add_column("Words", width=8)
        dist_table.add_column("Count", width=8)
        dist_table.add_column("Density", width=10)

        for section in result.distribution:
            density_color = "green" if section.density <= 3 else "yellow" if section.density <= 5 else "red"
            dist_table.add_row(
                section.section_name[:25],
                str(section.word_count),
                str(section.keyword_count),
                f"[{density_color}]{section.density:.1f}%[/]"
            )

        console.print(dist_table)

    # Secondary keywords (if any)
    if result.secondary:
        sec_table = Table(show_header=True, header_style="bold", title="Secondary Keywords")
        sec_table.add_column("Keyword", width=20)
        sec_table.add_column("Count", width=8)
        sec_table.add_column("Density", width=10)
        sec_table.add_column("Status", width=15)

        for s in result.secondary:
            s_color = status_colors.get(s.status, "white")
            sec_table.add_row(
                s.keyword,
                str(s.exact_matches),
                f"{s.density:.1f}%",
                f"[{s_color}]{s.status.replace('_', ' ').title()}[/]"
            )

        console.print(sec_table)

    # Stuffing warnings
    if result.stuffing_risk.warnings:
        console.print("\n[bold red]Stuffing Warnings:[/bold red]")
        for warning in result.stuffing_risk.warnings:
            console.print(f"  [red]⚠[/red] {warning}")

    # Recommendations
    if result.recommendations:
        console.print("\n[bold]Recommendations:[/bold]")
        for rec in result.recommendations:
            console.print(f"  [yellow]•[/yellow] {rec}")


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--output", "-o", type=click.Path(), help="Output file (default: print to stdout)")
@click.option("--no-watermarks", is_flag=True, help="Skip watermark removal")
@click.option("--no-em-dash", is_flag=True, help="Skip em-dash replacement")
@click.option("--json", "output_json", is_flag=True, help="Output stats as JSON (not scrubbed content)")
def scrub(file: str, output: str | None, no_watermarks: bool, no_em_dash: bool, output_json: bool):
    """Scrub content of AI watermarks and normalize em-dashes."""
    content = Path(file).read_text()
    result = scrub_content(
        content,
        remove_watermarks=not no_watermarks,
        replace_em_dashes=not no_em_dash,
    )

    if output_json:
        # Output stats only as JSON
        stats = result.model_dump()
        del stats["scrubbed_content"]  # Don't include full content in stats
        console.print(json.dumps(stats, indent=2))
        return

    # If output file specified, write scrubbed content there
    if output:
        Path(output).write_text(result.scrubbed_content)
        console.print(f"[green]Scrubbed content written to {output}[/green]")
    else:
        # Print scrubbed content to stdout
        console.print(result.scrubbed_content)
        return  # Don't show stats if outputting content to stdout

    # Show stats panel when writing to file
    changes_made = result.watermarks_removed > 0 or result.em_dashes_replaced > 0

    if changes_made:
        console.print(
            Panel(
                f"Watermarks removed: {result.watermarks_removed} | "
                f"Em-dashes replaced: {result.em_dashes_replaced} | "
                f"Length: {result.original_length} → {result.scrubbed_length} chars",
                title="Scrub Results",
            )
        )

        # Watermark types breakdown
        if result.watermark_types:
            console.print("\n[bold]Watermark Types Removed:[/bold]")
            for wtype, count in result.watermark_types.items():
                console.print(f"  • {wtype}: {count}")

        # Em-dash replacements (show first 5)
        if result.replacements:
            console.print("\n[bold]Em-Dash Replacements:[/bold]")
            for rep in result.replacements[:5]:
                console.print(f"  Line {rep.line}: {rep.replacement!r} ({rep.reason})")
            if len(result.replacements) > 5:
                console.print(f"  [dim]... and {len(result.replacements) - 5} more[/dim]")
    else:
        console.print("[green]No changes needed - content is clean.[/green]")


@cli.command()
@click.argument("file", type=click.Path(exists=True))
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def topics(file: str, output_json: bool):
    """Analyze content for topic clusters and LSI keywords."""
    try:
        from turboseo.analyzers.topic_clustering import analyze_topics
    except ImportError:
        console.print("[red]Topic clustering requires scikit-learn.[/red]")
        console.print("Install with: pip install turboseo[ml]")
        raise click.Abort()

    content = Path(file).read_text()
    result = analyze_topics(content)

    if output_json:
        console.print(json.dumps(result.model_dump(), indent=2))
        return

    # Header panel
    console.print(
        Panel(
            f"Sections: {result.section_count} | Clusters: {result.cluster_count}",
            title="Topic Clustering Analysis",
        )
    )

    if not result.clusters:
        console.print("[yellow]Not enough sections for clustering analysis.[/yellow]")
        if result.recommendations:
            console.print("\n[bold]Recommendations:[/bold]")
            for rec in result.recommendations:
                console.print(f"  [yellow]•[/yellow] {rec}")
        return

    # Clusters table
    cluster_table = Table(show_header=True, header_style="bold", title="Topic Clusters")
    cluster_table.add_column("Cluster", width=10)
    cluster_table.add_column("Top Terms", width=40)
    cluster_table.add_column("Sections", width=15)

    for cluster in result.clusters:
        terms = ", ".join(cluster.top_terms[:5])
        sections = ", ".join(str(i + 1) for i in cluster.section_indices)
        cluster_table.add_row(
            f"#{cluster.cluster_id + 1}",
            terms,
            f"[{sections}] ({cluster.section_count})",
        )

    console.print(cluster_table)

    # LSI Keywords
    if result.lsi_keywords.single_words or result.lsi_keywords.phrases:
        console.print("\n[bold]LSI Keywords:[/bold]")
        if result.lsi_keywords.single_words:
            words = ", ".join(result.lsi_keywords.single_words[:10])
            console.print(f"  Single words: {words}")
        if result.lsi_keywords.phrases:
            phrases = ", ".join(result.lsi_keywords.phrases[:5])
            console.print(f"  Phrases: {phrases}")

    # Recommendations
    if result.recommendations:
        console.print("\n[bold]Recommendations:[/bold]")
        for rec in result.recommendations:
            console.print(f"  [yellow]•[/yellow] {rec}")


@cli.command()
@click.option("--name", "-n", help="Project name")
@click.option("--url", "-u", help="Project website URL to crawl for context")
@click.option("--description", "-d", help="Project description")
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompts")
def init(name: str | None, url: str | None, description: str | None, yes: bool):
    """Initialize TurboSEO for this project."""
    project_path = Path.cwd()
    config_dir = get_config_dir(project_path)

    # Check if already initialized
    if config_dir.exists():
        if not yes:
            overwrite = Confirm.ask(
                "[yellow]TurboSEO already initialized in this directory. Overwrite?[/]",
                default=False,
            )
            if not overwrite:
                console.print("[dim]Cancelled.[/dim]")
                return
        console.print("[dim]Reinitializing...[/dim]")

    # Gather info interactively if not provided
    if not name:
        default_name = project_path.name
        name = Prompt.ask("Project name", default=default_name)

    if not description:
        description = Prompt.ask("Description (optional)", default="")

    if not url and not yes:
        url = Prompt.ask("Website URL (optional, for context)", default="")

    # Create config
    config = ProjectConfig(
        name=name,
        description=description or "",
        url=url or "",
    )

    # Crawl URL for context if provided
    if url:
        console.print(f"[dim]Fetching context from {url}...[/dim]")
        context = _fetch_url_context(url)
        if context:
            config.context = context
            console.print("[green]Context extracted from URL.[/green]")
        else:
            console.print("[yellow]Could not fetch URL context.[/yellow]")

    # Save config
    config_file = save_config(config, project_path)
    console.print(f"[green]Created {config_file}[/green]")

    # Add to .gitignore
    if create_gitignore_entry(project_path):
        console.print("[green]Added .turboseo/ to .gitignore[/green]")

    # Register in global projects
    add_project(
        name=name,
        path=project_path,
        url=url or "",
        description=description or "",
    )
    console.print("[green]Registered in global projects list.[/green]")

    # Show summary
    console.print(
        Panel(
            f"[bold]Project:[/bold] {name}\n"
            f"[bold]Config:[/bold] {config_dir}/\n"
            f"[bold]URL:[/bold] {url or '(none)'}\n"
            f"\n[dim]Run 'turboseo config' to view/edit settings.[/dim]",
            title="TurboSEO Initialized",
        )
    )


def _fetch_url_context(url: str) -> str | None:
    """Fetch and extract context from a URL."""
    try:
        from turboseo.analyzers.content_fetcher import fetch_url, parse_html

        # Fetch the page
        html = fetch_url(url)
        if not html:
            return None

        content = parse_html(html)
        if not content:
            return None

        # Build context summary
        lines = []
        lines.append(f"# Context from {url}")
        lines.append("")

        if content.title:
            lines.append(f"**Title:** {content.title}")
        if content.meta_description:
            lines.append(f"**Description:** {content.meta_description}")

        lines.append("")
        lines.append("## Content Summary")
        lines.append("")

        # Get first ~500 words of content
        words = content.body_text.split()[:500]
        lines.append(" ".join(words))
        if len(content.body_text.split()) > 500:
            lines.append("...")

        return "\n".join(lines)

    except Exception:
        return None


@cli.command()
@click.argument("key", required=False)
@click.argument("value", required=False)
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def config(key: str | None, value: str | None, output_json: bool):
    """View or modify project configuration.

    Without arguments, shows current config.
    With KEY, shows that specific value.
    With KEY VALUE, sets the value.

    Examples:
        turboseo config
        turboseo config thresholds.max_keyword_density
        turboseo config thresholds.max_keyword_density 3.0
        turboseo config keywords.primary '["seo", "content"]'
    """
    project_root = find_project_root()

    if project_root is None:
        console.print("[red]No TurboSEO project found.[/red]")
        console.print("Run 'turboseo init' to initialize.")
        raise click.Abort()

    cfg = load_config(project_root)
    if cfg is None:
        console.print("[red]Could not load config.[/red]")
        raise click.Abort()

    # No args - show full config
    if key is None:
        if output_json:
            console.print(json.dumps(cfg.model_dump(exclude={"context"}), indent=2))
        else:
            _display_config(cfg)
        return

    # Get nested value
    if value is None:
        val = _get_nested(cfg.model_dump(), key)
        if val is None:
            console.print(f"[red]Key not found: {key}[/red]")
            raise click.Abort()
        if output_json or isinstance(val, (dict, list)):
            console.print(json.dumps(val, indent=2))
        else:
            console.print(str(val))
        return

    # Set value
    try:
        # Parse JSON values
        try:
            parsed_value = json.loads(value)
        except json.JSONDecodeError:
            # Try as number
            try:
                parsed_value = float(value) if "." in value else int(value)
            except ValueError:
                # Keep as string
                parsed_value = value

        data = cfg.model_dump()
        _set_nested(data, key, parsed_value)
        cfg = ProjectConfig(**data)
        save_config(cfg, project_root)
        console.print(f"[green]Set {key} = {parsed_value}[/green]")

    except Exception as e:
        console.print(f"[red]Error setting value: {e}[/red]")
        raise click.Abort()


def _display_config(cfg: ProjectConfig) -> None:
    """Display config in a nice format."""
    console.print(
        Panel(
            f"[bold]Name:[/bold] {cfg.name}\n"
            f"[bold]Description:[/bold] {cfg.description or '(none)'}\n"
            f"[bold]URL:[/bold] {cfg.url or '(none)'}",
            title="Project",
        )
    )

    # Thresholds table
    t_table = Table(show_header=True, header_style="bold", title="Thresholds")
    t_table.add_column("Setting", width=30)
    t_table.add_column("Value", width=15)

    t = cfg.thresholds
    t_table.add_row("Min Readability Score", str(t.min_readability_score))
    t_table.add_row("Target Flesch Range", f"{t.target_flesch_min}-{t.target_flesch_max}")
    t_table.add_row("Max Sentence Length", str(t.max_sentence_length))
    t_table.add_row("Target Keyword Density", f"{t.target_keyword_density}%")
    t_table.add_row("Max Keyword Density", f"{t.max_keyword_density}%")
    t_table.add_row("Min Transition Density", f"{t.min_transition_density}/100w")
    t_table.add_row("Word Count Range", f"{t.min_word_count}-{t.max_word_count}")
    t_table.add_row("Strict Mode", str(t.strict_mode))
    console.print(t_table)

    # Keywords
    if cfg.keywords.primary or cfg.keywords.secondary or cfg.keywords.avoid:
        k_table = Table(show_header=True, header_style="bold", title="Keywords")
        k_table.add_column("Type", width=15)
        k_table.add_column("Keywords", width=40)

        if cfg.keywords.primary:
            k_table.add_row("Primary", ", ".join(cfg.keywords.primary))
        if cfg.keywords.secondary:
            k_table.add_row("Secondary", ", ".join(cfg.keywords.secondary))
        if cfg.keywords.avoid:
            k_table.add_row("Avoid", ", ".join(cfg.keywords.avoid))

        console.print(k_table)

    # Content settings
    c_table = Table(show_header=True, header_style="bold", title="Content Settings")
    c_table.add_column("Setting", width=20)
    c_table.add_column("Value", width=30)

    c_table.add_row("Default Type", cfg.content.default_type)
    c_table.add_row("Target Audience", cfg.content.target_audience)
    c_table.add_row("Writing Style", cfg.content.writing_style)
    c_table.add_row("Tone", cfg.content.tone)
    console.print(c_table)

    # Context hint
    if cfg.context:
        console.print(f"\n[dim]Context: {len(cfg.context)} chars loaded[/dim]")


def _get_nested(data: dict, key: str):
    """Get a nested value using dot notation."""
    parts = key.split(".")
    current = data
    for part in parts:
        if isinstance(current, dict) and part in current:
            current = current[part]
        else:
            return None
    return current


def _set_nested(data: dict, key: str, value) -> None:
    """Set a nested value using dot notation."""
    parts = key.split(".")
    current = data
    for part in parts[:-1]:
        if part not in current:
            current[part] = {}
        current = current[part]
    current[parts[-1]] = value


@cli.command()
@click.argument("action", required=False, type=click.Choice(["list", "add", "remove"]))
@click.argument("name_or_path", required=False)
@click.option("--json", "output_json", is_flag=True, help="Output as JSON")
def projects(action: str | None, name_or_path: str | None, output_json: bool):
    """Manage registered TurboSEO projects.

    Actions:
        list (default) - Show all registered projects
        add - Register current directory as a project
        remove NAME - Remove a project from the registry
    """
    if action is None:
        action = "list"

    if action == "list":
        all_projects = list_projects()

        if output_json:
            console.print(json.dumps([p.model_dump() for p in all_projects], indent=2))
            return

        if not all_projects:
            console.print("[dim]No projects registered.[/dim]")
            console.print("Run 'turboseo init' in a project directory to register it.")
            return

        table = Table(show_header=True, header_style="bold", title="TurboSEO Projects")
        table.add_column("Name", width=20)
        table.add_column("Path", width=40)
        table.add_column("URL", width=25)

        for p in all_projects:
            table.add_row(p.name, p.path, p.url or "[dim]-[/dim]")

        console.print(table)

    elif action == "add":
        # Register current directory
        project_root = find_project_root()
        if project_root is None:
            console.print("[red]No TurboSEO config found in this directory.[/red]")
            console.print("Run 'turboseo init' first.")
            raise click.Abort()

        cfg = load_config(project_root)
        if cfg:
            add_project(
                name=cfg.name,
                path=project_root,
                url=cfg.url,
                description=cfg.description,
            )
            console.print(f"[green]Registered project: {cfg.name}[/green]")
        else:
            console.print("[red]Could not load config.[/red]")

    elif action == "remove":
        if not name_or_path:
            console.print("[red]Please specify project name to remove.[/red]")
            raise click.Abort()

        if remove_project(name_or_path):
            console.print(f"[green]Removed project: {name_or_path}[/green]")
        else:
            console.print(f"[red]Project not found: {name_or_path}[/red]")


@cli.command()
@click.option("--json", "output_json", is_flag=True, help="Output context as JSON")
def context(output_json: bool):
    """Show project context (for Claude/AI assistants)."""
    project_root = find_project_root()

    if project_root is None:
        console.print("[red]No TurboSEO project found.[/red]")
        raise click.Abort()

    cfg = load_config(project_root)
    if cfg is None:
        console.print("[red]Could not load config.[/red]")
        raise click.Abort()

    # Build context for AI
    context_data = {
        "project": {
            "name": cfg.name,
            "description": cfg.description,
            "url": cfg.url,
        },
        "content_guidelines": {
            "target_audience": cfg.content.target_audience,
            "writing_style": cfg.content.writing_style,
            "tone": cfg.content.tone,
            "default_type": cfg.content.default_type,
        },
        "keywords": {
            "primary": cfg.keywords.primary,
            "secondary": cfg.keywords.secondary,
            "avoid": cfg.keywords.avoid,
        },
        "thresholds": cfg.thresholds.model_dump(),
        "context": cfg.context,
    }

    if output_json:
        console.print(json.dumps(context_data, indent=2))
        return

    # Display for humans
    console.print(Panel(f"[bold]{cfg.name}[/bold]\n{cfg.description}", title="Project Context"))

    if cfg.context:
        console.print("\n[bold]Crawled Context:[/bold]")
        # Show first 500 chars
        preview = cfg.context[:500]
        if len(cfg.context) > 500:
            preview += "..."
        console.print(f"[dim]{preview}[/dim]")

    console.print("\n[dim]Use --json for full context data.[/dim]")


if __name__ == "__main__":
    cli()
