"""Template create command implementation."""

from pathlib import Path
from typing import Optional

import typer

from cli.commands.flag_utils import (
    parse_tags_required,
    require_one_of,
    validate_scope,
    validate_template_content_type,
    validate_visibility,
)
from cli.commands.templates.create.presenter import present_template_create_success
from cli.infrastructure.command import async_command, authenticated_client
from cli.infrastructure.file_content import FileContentError, resolve_content
from alloy_runtime_types.dtos.templates import CreateTemplateRequest
from alloy_runtime_types.enums.ownership_scope import OwnershipScope
from alloy_runtime_types.enums.template_enums import TemplateVisibility


def templates_create_command(
    name: str = typer.Option(
        ...,
        "-n",
        "--name",
        help="Template name",
    ),
    content_type: str = typer.Option(
        ...,
        "--type",
        help="Type: system_instruction, user_message, fragment",
    ),
    visibility: Optional[str] = typer.Option(
        None,
        "-V",
        "--visibility",
        help="Visibility: organization (default), private, public",
    ),
    tags: str = typer.Option(
        ...,
        "-t",
        "--tags",
        help="Comma-separated tags",
    ),
    content_file: Optional[Path] = typer.Option(
        None,
        "-f",
        "--file",
        help="Read content from file",
        exists=True,
        readable=True,
    ),
    content: Optional[str] = typer.Option(
        None,
        "-c",
        "--content",
        help="Inline content (or @file)",
    ),
    description: Optional[str] = typer.Option(
        None,
        "-d",
        "--description",
        help="Template description",
    ),
    upsert: bool = typer.Option(
        False,
        "--upsert",
        help="Return existing if name exists",
    ),
    scope: Optional[str] = typer.Option(
        None,
        "--scope",
        help="Ownership scope: organization (default), user, global",
    ),
    escape_jinja: bool = typer.Option(
        False,
        "--escape-jinja",
        help="Escape Jinja syntax as literals",
    ),
) -> None:
    """Create a new template.

    Examples:
        alloy templates create -n my-template --type system_instruction -f template.jinja2 -t "email"
        alloy templates create -n greeting --type fragment -c "Hello, {{ name }}!" -t "greeting"
        alloy templates create -n personal.draft --type fragment -V private -f header.jinja2 -d "Private draft" -t "email,header"
    """
    require_one_of(("--file", content_file), ("--content", content))

    _execute_create_from_flags(
        name=name,
        content_type=content_type,
        visibility=visibility,
        content_file=content_file,
        content=content,
        description=description,
        tags=tags,
        upsert=upsert,
        scope=scope,
        escape_jinja=escape_jinja,
    )


@async_command
async def _execute_create(request: CreateTemplateRequest) -> None:
    """Execute the template creation with the given request."""
    async with authenticated_client() as (_config, client):
        response = await client.create_template(request)

    present_template_create_success(response)


def _execute_create_from_flags(
    name: str,
    content_type: str,
    visibility: Optional[str],
    content_file: Optional[Path],
    content: Optional[str],
    description: Optional[str],
    tags: str,
    upsert: bool,
    scope: Optional[str] = None,
    escape_jinja: bool = False,
) -> None:
    """Build and execute template creation from command flags."""
    # Resolve @file references in content
    try:
        content = resolve_content(content)
    except FileContentError as e:
        raise typer.BadParameter(str(e))

    # Validate enums
    content_type_enum = validate_template_content_type(content_type)
    visibility_enum = (
        validate_visibility(visibility)
        if visibility is not None
        else TemplateVisibility.ORGANIZATION
    )

    # Get content from file or inline
    if content_file:
        template_content = content_file.read_text()
    else:
        template_content = content or ""

    if not template_content.strip():
        raise typer.BadParameter("Template content cannot be empty")

    # Parse tags
    tag_paths = parse_tags_required(tags)

    ownership_scope = OwnershipScope.ORGANIZATION
    if scope:
        ownership_scope = validate_scope(scope)

    # Build request
    request = CreateTemplateRequest(
        name=name,
        content_type=content_type_enum,
        visibility=visibility_enum,
        initial_content=template_content,
        tag_paths=tag_paths,
        description=description,
        upsert=upsert,
        scope=ownership_scope,
        escape_jinja=escape_jinja,
    )

    _execute_create(request)
