"""
Administrative commands for user and credit management
"""

import json
import os
from datetime import datetime

import click
import httpx

from ai_lls_lib.cli.aws_client import AWSClient

ENV_VAR_MAP = {
    "staging": {
        "api_key": "STAGING_LLS_API_KEY",
        "subdomain": "STAGING_API_SUBDOMAIN",
        "hosted_zone": "STAGING_HOSTED_ZONE_NAME",
    },
    "prod": {
        "api_key": "PROD_LLS_API_KEY",
        "subdomain": "PROD_API_SUBDOMAIN",
        "hosted_zone": "PROD_HOSTED_ZONE_NAME",
    },
}


def _resolve_user_from_env(env: str) -> str:
    """Resolve user_id by calling the API with env-specific credentials."""
    var_names = ENV_VAR_MAP[env]

    api_key = os.environ.get(var_names["api_key"])
    subdomain = os.environ.get(var_names["subdomain"])
    hosted_zone = os.environ.get(var_names["hosted_zone"])

    missing = [name for key, name in var_names.items() if not os.environ.get(name)]
    if missing:
        raise click.ClickException(
            f"Missing environment variables for --env {env}: {', '.join(missing)}"
        )

    assert api_key is not None
    assert subdomain is not None
    assert hosted_zone is not None

    base_url = f"https://{subdomain}.{hosted_zone}"
    resp = httpx.get(
        f"{base_url}/user",
        headers={"X-LLS-Key": api_key},
        timeout=10,
    )
    resp.raise_for_status()
    user_id = resp.json().get("user_id")
    if not user_id:
        raise click.ClickException(f"Could not resolve user_id from {base_url}/user")
    return str(user_id)


@click.group(name="admin")
def admin_group():
    """Administrative commands"""
    pass


@admin_group.command(name="user-credits")
@click.argument("user_id", required=False, default=None)
@click.option(
    "--env",
    "env_name",
    type=click.Choice(["staging", "prod"]),
    help="Resolve user from environment (staging or prod)",
)
@click.option("--add", type=int, help="Add credits")
@click.option("--set", "set_credits", type=int, help="Set credits to specific value")
@click.option("--stack", default="landline-api", help="CloudFormation stack name")
@click.option("--profile", help="AWS profile")
@click.option("--region", help="AWS region")
def user_credits(user_id, env_name, add, set_credits, stack, profile, region):
    """Manage user credits.

    USER_ID is required unless --env is provided, which auto-resolves
    the user from environment variables.
    """
    if not user_id and not env_name:
        raise click.UsageError("Provide USER_ID or use --env to resolve it automatically.")

    if env_name:
        resolved = _resolve_user_from_env(env_name)
        if user_id and user_id != resolved:
            click.echo(
                f"Warning: USER_ID '{user_id}' overridden by --env {env_name} "
                f"(resolved to '{resolved}')",
                err=True,
            )
        user_id = resolved

    aws = AWSClient(region=region, profile=profile)
    credits_table = aws.get_table_name(stack, "CreditsTable")

    try:
        table = aws.dynamodb.Table(credits_table)

        # Get current credits
        response = table.get_item(Key={"user_id": user_id})
        current = response.get("Item", {}).get("credits", 0)

        click.echo(f"User {user_id} - Current credits: {current}")

        if add:
            new_credits = current + add
            table.update_item(
                Key={"user_id": user_id},
                UpdateExpression="SET credits = :val, updated_at = :now",
                ExpressionAttributeValues={
                    ":val": new_credits,
                    ":now": datetime.utcnow().isoformat(),
                },
            )
            click.echo(f"Added {add} credits. New balance: {new_credits}")

        elif set_credits is not None:
            table.update_item(
                Key={"user_id": user_id},
                UpdateExpression="SET credits = :val, updated_at = :now",
                ExpressionAttributeValues={
                    ":val": set_credits,
                    ":now": datetime.utcnow().isoformat(),
                },
            )
            click.echo(f"Set credits to {set_credits}")

    except Exception as e:
        click.echo(f"Error managing credits: {e}", err=True)


@admin_group.command(name="api-keys")
@click.option("--user", help="Filter by user ID")
@click.option("--stack", default="landline-api", help="CloudFormation stack name")
@click.option("--profile", help="AWS profile")
@click.option("--region", help="AWS region")
def list_api_keys(user, stack, profile, region):
    """List API keys"""
    aws = AWSClient(region=region, profile=profile)
    keys_table = aws.get_table_name(stack, "ApiKeysTable")

    try:
        if user:
            # Query by user using GSI
            table = aws.dynamodb.Table(keys_table)
            response = table.query(
                IndexName="gsi_user",
                KeyConditionExpression="user_id = :uid",
                ExpressionAttributeValues={":uid": user},
            )
            items = response.get("Items", [])
        else:
            # Scan all
            items = aws.scan_table(keys_table)

        if not items:
            click.echo("No API keys found")
            return

        click.echo(f"\nAPI Keys ({len(items)} total):")
        click.echo("=" * 60)

        for item in items:
            click.echo(f"Key ID: {item.get('api_key_id', 'N/A')}")
            click.echo(f"User: {item.get('user_id', 'N/A')}")
            click.echo(f"Created: {item.get('created_at', 'N/A')}")
            click.echo(f"Last Used: {item.get('last_used', 'Never')}")
            click.echo("-" * 60)

    except Exception as e:
        click.echo(f"Error listing API keys: {e}", err=True)


@admin_group.command(name="queue-stats")
@click.option("--stack", default="landline-api", help="CloudFormation stack name")
@click.option("--profile", help="AWS profile")
@click.option("--region", help="AWS region")
def queue_stats(stack, profile, region):
    """Show SQS queue statistics"""
    aws = AWSClient(region=region, profile=profile)

    try:
        # Get queue URLs from stack
        aws.get_stack_outputs(stack)

        # Find queue URLs or construct them
        queue_name = f"{stack}-bulk-processing"
        dlq_name = f"{stack}-bulk-processing-dlq"

        # Get queue attributes
        queues = [("Processing Queue", queue_name), ("Dead Letter Queue", dlq_name)]

        for display_name, queue in queues:
            try:
                response = aws.sqs.get_queue_url(QueueName=queue)
                queue_url = response["QueueUrl"]

                attrs = aws.sqs.get_queue_attributes(QueueUrl=queue_url, AttributeNames=["All"])[
                    "Attributes"
                ]

                click.echo(f"\n{display_name}:")
                click.echo(f"  Messages Available: {attrs.get('ApproximateNumberOfMessages', 0)}")
                click.echo(
                    f"  Messages In Flight: {attrs.get('ApproximateNumberOfMessagesNotVisible', 0)}"
                )
                click.echo(
                    f"  Messages Delayed: {attrs.get('ApproximateNumberOfMessagesDelayed', 0)}"
                )

            except aws.sqs.exceptions.QueueDoesNotExist:
                click.echo(f"\n{display_name}: Not found")

    except Exception as e:
        click.echo(f"Error getting queue stats: {e}", err=True)


@admin_group.command(name="secrets")
@click.option("--stack", default="landline-api", help="CloudFormation stack name")
@click.option("--show", is_flag=True, help="Show secret values (CAREFUL!)")
@click.option("--profile", help="AWS profile")
@click.option("--region", help="AWS region")
def manage_secrets(stack, show, profile, region):
    """Manage secrets"""
    aws = AWSClient(region=region, profile=profile)
    secret_name = f"{stack}-secrets"

    try:
        response = aws.secretsmanager.describe_secret(SecretId=secret_name)
        click.echo(f"\nSecret: {secret_name}")
        click.echo(f"ARN: {response['ARN']}")
        click.echo(f"Last Updated: {response.get('LastChangedDate', 'N/A')}")

        if show and click.confirm("Show secret values? This will display sensitive data!"):
            secret_value = aws.secretsmanager.get_secret_value(SecretId=secret_name)
            secrets = json.loads(secret_value["SecretString"])

            click.echo("\nSecret Values:")
            for key, value in secrets.items():
                # Mask most of the value
                masked = (
                    value[:4] + "*" * (len(value) - 8) + value[-4:]
                    if len(value) > 8
                    else "*" * len(value)
                )
                click.echo(f"  {key}: {masked}")

    except aws.secretsmanager.exceptions.ResourceNotFoundException:
        click.echo(f"Secret '{secret_name}' not found")
    except Exception as e:
        click.echo(f"Error managing secrets: {e}", err=True)
