"""CLI interface for PPTX MCP."""

from __future__ import annotations

import json
import sys
from pathlib import Path

import click

from pptx_mcp.utils.logging import configure_logging, get_logger

logger = get_logger("cli")


@click.group()
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose logging.")
def main(verbose: bool) -> None:
    """PPTX MCP — PowerPoint generation and review via Model Context Protocol."""
    import logging

    configure_logging(level=logging.DEBUG if verbose else logging.INFO)


@main.command()
@click.option(
    "--transport",
    "-t",
    type=click.Choice(["stdio", "sse", "streamable-http"]),
    default="stdio",
    help="MCP transport protocol.",
)
def serve(transport: str) -> None:
    """Start the MCP server."""
    from pptx_mcp.server import mcp as mcp_server

    mcp_server.run(transport=transport)


@main.command()
@click.argument("definition_path", type=click.Path(exists=True))
@click.argument("output_path", type=click.Path())
@click.option("--brand", "-b", type=click.Path(exists=True), help="Brand config file path.")
@click.option("--preset", "-p", type=str, help="Brand preset name.")
def generate(
    definition_path: str,
    output_path: str,
    brand: str | None,
    preset: str | None,
) -> None:
    """Generate a PPTX from a JSON slide definition file.

    DEFINITION_PATH: Path to the JSON slide definition.
    OUTPUT_PATH: Where to save the generated .pptx file.
    """
    from pptx_mcp.brand.config import resolve_brand_config
    from pptx_mcp.engine.generator import DeckGenerator
    from pptx_mcp.models.slides import PresentationDefinition

    raw = Path(definition_path).read_text(encoding="utf-8")
    data = json.loads(raw)
    definition = PresentationDefinition.model_validate(data)

    brand_config = resolve_brand_config(path=brand, preset=preset)
    generator = DeckGenerator(brand=brand_config)
    result = generator.generate(definition, output_path)

    click.echo(f"Generated: {result} ({len(definition.slides)} slides)")


@main.command()
@click.argument("file_path", type=click.Path(exists=True))
@click.option("--output", "-o", type=click.Path(), help="Save parsed JSON to file.")
def read(file_path: str, output: str | None) -> None:
    """Parse a PPTX file and output its structure as JSON.

    FILE_PATH: Path to the .pptx file.
    """
    from pptx_mcp.engine.parser import parse_presentation

    definition = parse_presentation(file_path)
    json_str = definition.model_dump_json(indent=2)

    if output:
        Path(output).write_text(json_str, encoding="utf-8")
        click.echo(f"Parsed: {file_path} → {output}")
    else:
        click.echo(json_str)


@main.command()
@click.argument("file_path", type=click.Path(exists=True))
@click.option("--brand", "-b", type=click.Path(exists=True), help="Brand config file path.")
@click.option("--preset", "-p", type=str, help="Brand preset name.")
@click.option("--output", "-o", type=click.Path(), help="Save review JSON to file.")
def review(
    file_path: str,
    brand: str | None,
    preset: str | None,
    output: str | None,
) -> None:
    """Review a PPTX file and output design feedback.

    FILE_PATH: Path to the .pptx file.
    """
    from pptx_mcp.brand.config import resolve_brand_config
    from pptx_mcp.review.engine import ReviewEngine

    brand_config = resolve_brand_config(path=brand, preset=preset)
    engine = ReviewEngine(brand=brand_config)
    result = engine.review_file(file_path)

    json_str = result.model_dump_json(indent=2)

    if output:
        Path(output).write_text(json_str, encoding="utf-8")
        click.echo(f"Review saved: {output}")
    else:
        click.echo(f"\nReview: {file_path}")
        click.echo(f"Score: {result.overall_score}/10.0")
        click.echo(f"Issues: {result.total_issues}")
        click.echo(f"\n{result.summary}")

        if result.strengths:
            click.echo("\nStrengths:")
            for s in result.strengths:
                click.echo(f"  + {s}")

        if result.improvements:
            click.echo("\nImprovements:")
            for imp in result.improvements:
                click.echo(f"  - {imp}")

        if result.issues:
            click.echo(f"\nDetailed Issues ({len(result.issues)}):")
            for issue in result.issues:
                prefix = {
                    "error": "ERROR",
                    "warning": "WARN ",
                    "info": "INFO ",
                    "suggestion": "HINT ",
                }.get(issue.severity.value, "     ")
                slide_ref = f"[slide {issue.slide_index}]" if issue.slide_index is not None else "[deck]"
                click.echo(f"  {prefix} {slide_ref} {issue.message}")


@main.command()
@click.argument("topic")
@click.option("--slides", "-n", type=int, default=10, help="Number of slides.")
@click.option("--audience", "-a", type=str, default="executive", help="Target audience.")
@click.option("--points", type=str, help="Comma-separated key points.")
@click.option("--output", "-o", type=click.Path(), help="Save plan JSON to file.")
def plan(
    topic: str,
    slides: int,
    audience: str,
    points: str | None,
    output: str | None,
) -> None:
    """Generate a slide plan for a topic.

    TOPIC: The presentation topic or title.
    """
    from pptx_mcp.agents.planner import PlannerInput, SlidePlannerAgent

    key_points = [p.strip() for p in points.split(",")] if points else []
    planner = SlidePlannerAgent()
    result = planner.run(PlannerInput(
        topic=topic,
        audience=audience,
        num_slides=slides,
        key_points=key_points,
    ))

    json_str = result.model_dump_json(indent=2)

    if output:
        Path(output).write_text(json_str, encoding="utf-8")
        click.echo(f"Plan saved: {output} ({len(result.slides)} slides)")
    else:
        click.echo(json_str)


@main.command()
@click.argument("file_path", type=click.Path(exists=True))
@click.option("--output", "-o", type=click.Path(), help="Save improved version to a new file.")
@click.option("--brand", "-b", type=click.Path(exists=True), help="Brand config file path.")
@click.option("--preset", "-p", type=str, help="Brand preset name.")
def improve(
    file_path: str,
    output: str | None,
    brand: str | None,
    preset: str | None,
) -> None:
    """Review, iterate, and re-generate an improved version of a deck.

    FILE_PATH: Path to the .pptx file.
    """
    from pptx_mcp.agents.designer import DesignAgent, DesignerInput
    from pptx_mcp.agents.iterator import IterationAgent, IterationInput
    from pptx_mcp.brand.config import resolve_brand_config
    from pptx_mcp.engine.generator import DeckGenerator
    from pptx_mcp.engine.parser import parse_presentation
    from pptx_mcp.review.engine import ReviewEngine

    brand_config = resolve_brand_config(path=brand, preset=preset)

    click.echo(f"Parsing: {file_path}")
    definition = parse_presentation(file_path)

    click.echo("Reviewing...")
    reviewer = ReviewEngine(brand=brand_config)
    review_result = reviewer.review_definition(definition)
    click.echo(f"  Score: {review_result.overall_score}/10.0 ({review_result.total_issues} issues)")

    click.echo("Iterating fixes...")
    iterator = IterationAgent()
    iter_result = iterator.run(IterationInput(definition=definition, review=review_result))
    for fix in iter_result.fixes_applied:
        click.echo(f"  Fixed: {fix}")

    click.echo("Optimizing design...")
    designer = DesignAgent()
    design_result = designer.run(DesignerInput(
        definition=iter_result.definition,
        brand_config_path=brand,
        brand_preset=preset,
    ))
    for change in design_result.changes_made:
        click.echo(f"  Changed: {change}")

    out_path = output or file_path
    generator = DeckGenerator(brand=brand_config)
    result = generator.generate(design_result.definition, out_path)
    click.echo(f"\nSaved: {result}")


if __name__ == "__main__":
    main()
