from pathlib import Path
from typing import Optional

import typer

from cli.commands.flag_utils import validate_output_mode, validate_uuid
from cli.commands.knowledge.synthesis.get.presenter import present_synthesis_details
from cli.infrastructure.error_display import display_error_record
from cli.infrastructure.command import async_command, authenticated_client
from cli.infrastructure.output import OutputService


def knowledge_synthesis_get_command(
    synthesis_id: str = typer.Argument(
        ...,
        help="Synthesis UUID",
    ),
    output: str = typer.Option("console", "-o", help="Output: console or file"),
    output_file: Optional[str] = typer.Option(
        None,
        "-O",
        "--output-file",
        help="Save synthesis content to file",
    ),
) -> None:
    """Get synthesis details.

    Returns the full synthesis details including content (if completed),
    status, staleness information, and source tracking.
    """
    validate_uuid(synthesis_id, "synthesis")
    validate_output_mode(output, output_file, ("console", "file"))
    _execute_get(synthesis_id, output, output_file)


@async_command
async def _execute_get(
    synthesis_id: str,
    output_mode: str,
    output_file: Optional[str],
) -> None:
    """Execute synthesis get."""
    async with authenticated_client() as (_config, client):
        response = await client.get_synthesis(synthesis_id)

    if output_mode == "file":
        _write_synthesis_file(response.synthesis_content, output_file)
        return

    present_synthesis_details(response)


def _write_synthesis_file(content: str | None, output_file: Optional[str]) -> None:
    if not content:
        display_error_record(
            {
                "Type": "usage_error",
                "Message": "Synthesis content is not available yet; wait for the synthesis to complete before saving.",
                "Hint": "Run `alloy knowledge synthesis get --help`",
            }
        )
        raise typer.Exit(code=1)

    if output_file is None:
        raise typer.BadParameter("--output-file/-O required with --output file")

    file_path = Path(output_file).expanduser().resolve()
    file_path.parent.mkdir(parents=True, exist_ok=True)
    file_path.write_text(content, encoding="utf-8")

    OutputService.get().result(
        action="write",
        resource="synthesis",
        status="success",
        identifier=None,
        name=file_path.name,
        extra_fields={
            "Destination": str(file_path),
            "Characters": len(content),
        },
    )
