"""Schema create command implementation."""

from pathlib import Path
from typing import Optional

import typer

from cli.commands.flag_utils import (
    require_one_of,
    validate_schema_format,
    validate_scope,
)
from cli.commands.schemas.create.presenter import present_schema_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.schemas import CreateSchemaRequest
from alloy_runtime_types.enums.ownership_scope import OwnershipScope


def schemas_create_command(
    name: str = typer.Option(
        ...,
        "-n",
        "--name",
        help="Schema name",
    ),
    schema_format: str = typer.Option(
        ...,
        "--schema-format",
        help="Format: json_schema or regex",
    ),
    definition: Optional[str] = typer.Option(
        None,
        "-D",
        "--definition",
        help="Schema definition (or @file)",
    ),
    definition_file: Optional[Path] = typer.Option(
        None,
        "-f",
        "--file",
        help="Read definition from file",
        exists=True,
        readable=True,
    ),
    description: Optional[str] = typer.Option(
        None,
        "-d",
        "--description",
        help="Schema description",
    ),
    scope: Optional[str] = typer.Option(
        None,
        "--scope",
        help="Scope: user, organization, global",
    ),
) -> None:
    """Create a new schema.

    Examples:
        alloy schemas create -n user-profile --schema-format json_schema -D '{"type": "object"}'
        alloy schemas create -n api-response --schema-format json_schema -f schema.json
        alloy schemas create -n email-pattern --schema-format regex -D '^[a-z]+@.*$'
    """
    require_one_of(("--definition", definition), ("--file", definition_file))

    _execute_create_from_flags(
        name=name,
        schema_format=schema_format,
        definition=definition,
        definition_file=definition_file,
        description=description,
        scope=scope,
    )


@async_command
async def _execute_create(request: CreateSchemaRequest) -> None:
    """Execute the schema creation."""
    async with authenticated_client() as (_config, client):
        response = await client.create_schema(request)

    present_schema_create_success(response)


def _execute_create_from_flags(
    name: str,
    schema_format: str,
    definition: Optional[str],
    definition_file: Optional[Path],
    description: Optional[str],
    scope: Optional[str],
) -> None:
    """Build and execute schema creation."""
    try:
        definition = resolve_content(definition)
    except FileContentError as e:
        raise typer.BadParameter(str(e))

    format_enum = validate_schema_format(schema_format)

    if definition_file:
        schema_definition = definition_file.read_text()
    else:
        schema_definition = definition or ""

    if not schema_definition.strip():
        raise typer.BadParameter("Schema definition cannot be empty")

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

    request = CreateSchemaRequest(
        name=name,
        schema_format=format_enum,
        schema_definition=schema_definition,
        description=description,
        scope=ownership_scope,
    )

    _execute_create(request)
