"""alice summarize — Model-generated summary of file or stdin content."""

from __future__ import annotations

import sys

import click
from botocore.exceptions import ClientError
from rich.markdown import Markdown

from alice_cli import personality
from alice_cli.aws.bedrock_context import create_bedrock_context
from alice_cli.console import (
    err_console,
    print_banner,
    print_rule,
    print_success,
    spinner,
)
from alice_cli.constants import DEFAULT_MAX_TOKENS, get_memory_bucket
from alice_cli.errors import AliceCLIError
from alice_cli.locker import CloudLocker
from alice_cli.models import (
    DEFAULT_MODEL_ALIAS,
    SUMMARY_PROMPTS,
    SummaryLength,
    TokenUsage,
    model_help_text,
    resolve_model_id,
)
from alice_cli.session_record import build_session_record


@click.command("summarize")
@click.argument("file", required=False, type=click.Path(exists=True))
@click.option(
    "--length",
    "length",
    default="medium",
    type=click.Choice(["short", "medium", "detailed"], case_sensitive=False),
    help="Summary verbosity: short (2-3 sentences), medium (1-2 paragraphs), detailed (comprehensive). Default: medium.",  # noqa: E501
)
@click.option("--model-id", default=DEFAULT_MODEL_ALIAS, help=model_help_text())
@click.option(
    "-o",
    "--output",
    "output_path",
    default=None,
    type=click.Path(),
    help="Write raw summary text to a file",
)
@click.pass_context
def summarize_cmd(
    ctx: click.Context,
    file: str | None,
    length: str,
    model_id: str,
    output_path: str | None,
) -> None:
    """Summarize a file or stdin with a Bedrock model.

    \b
    Examples:
        alice summarize document.txt
        alice summarize document.txt --length short
        cat notes.md | alice summarize
        alice summarize report.pdf --output summary.txt
        alice summarize --model-id haiku document.txt
    """
    config = ctx.obj["config"]

    print_banner(personality.BANNER, config.quiet)

    # ── Read input content ────────────────────────────────────────────
    if file:
        try:
            with open(file, encoding="utf-8") as f:
                content = f.read()
        except Exception as exc:
            raise AliceCLIError(f"Could not read file: {exc}") from exc
    else:
        if sys.stdin.isatty():
            raise AliceCLIError(
                "No file provided and stdin is a terminal. Pipe content or pass a file path."
            )
        content = sys.stdin.read()

    if not content.strip():
        raise AliceCLIError("Input is empty — nothing to summarize.")

    # ── Build summarization prompt ────────────────────────────────────
    summary_length = SummaryLength(length.lower())
    prompt_template = SUMMARY_PROMPTS[summary_length]
    prompt_text = prompt_template.format(text=content)

    # ── Authenticate and build Bedrock client ─────────────────────────
    context = create_bedrock_context(config)
    username = context.username
    resolved_id = resolve_model_id(model_id, context.inference_profile_arns)
    client = context.client

    # ── Invoke Converse API ───────────────────────────────────────────
    with spinner(personality.status_invoking_model(model_id), config.quiet):
        try:
            response = client.converse(
                modelId=resolved_id,
                messages=[{"role": "user", "content": [{"text": prompt_text}]}],
                inferenceConfig={"maxTokens": DEFAULT_MAX_TOKENS},
            )
        except ClientError as exc:
            raise AliceCLIError(f"Bedrock API error: {exc}") from exc

    # ── Parse response ────────────────────────────────────────────────
    output_message = response.get("output", {}).get("message", {})
    content_blocks = output_message.get("content", [])
    text_parts = [block["text"] for block in content_blocks if "text" in block]
    summary_text = "\n".join(text_parts)

    usage = response.get("usage", {})
    input_tokens = usage.get("inputTokens", 0)
    output_tokens = usage.get("outputTokens", 0)

    # ── Display summary ───────────────────────────────────────────────
    print_success(personality.status_model_ready(model_id), config.quiet)
    print_rule(config.quiet)
    if summary_text.strip():
        err_console.print(Markdown(summary_text))
    else:
        err_console.print("[dim](empty response)[/dim]")
    print_rule(config.quiet)

    # ── Write to output file ──────────────────────────────────────────
    if output_path:
        try:
            with open(output_path, "w", encoding="utf-8") as f:
                f.write(summary_text)
            print_success(f"Summary written to {output_path}", config.quiet)
        except Exception as exc:
            raise AliceCLIError(f"Could not write output file: {exc}") from exc

    # ── Persist to Cloud Locker ───────────────────────────────────────
    locker = CloudLocker(
        config=config,
        username=username,
        bucket=get_memory_bucket(config.namespace, config.environment),
    )
    record = build_session_record(
        record_type="invoke",
        model=resolved_id,
        prompt=prompt_text,
        response=summary_text,
        tokens=TokenUsage(
            input=input_tokens,
            output=output_tokens,
            total=input_tokens + output_tokens,
        ),
        metadata={"command": "summarize", "length": length, "source": file or "stdin"},
    )
    try:
        locker.persist(record, "invoke")
        print_success("Session saved to Cloud Locker", config.quiet)
    except Exception as exc:
        err_console.print(f"[yellow]⚠ Could not save session: {exc}[/yellow]")
