"""DynamoDB-backed API key storage and validation."""

from __future__ import annotations

import hashlib
import secrets
from typing import Any

import boto3
from botocore.exceptions import ClientError

from cube_cloud.config import settings


def _get_table():
    dynamodb = boto3.resource("dynamodb", region_name=settings.aws_region)
    return dynamodb.Table(settings.dynamodb_table)


def hash_key(raw_key: str) -> str:
    """SHA-256 hash of an API key for storage."""
    return hashlib.sha256(raw_key.encode()).hexdigest()


def generate_key() -> str:
    """Generate a new API key (prefix + random token)."""
    return f"cmcp_{secrets.token_urlsafe(32)}"


async def validate_key(raw_key: str) -> dict[str, Any] | None:
    """Validate an API key. Returns the item dict if valid, None otherwise.

    Item schema: {key_hash, profile, description, created_at, enabled}
    """
    key_hash = hash_key(raw_key)
    table = _get_table()
    try:
        resp = table.get_item(Key={"key_hash": key_hash})
    except ClientError:
        return None

    item = resp.get("Item")
    if not item:
        return None

    if not item.get("enabled", True):
        return None

    return item


def create_key(profile: str, description: str = "") -> tuple[str, str]:
    """Create a new API key. Returns (raw_key, key_hash)."""
    from datetime import datetime, timezone

    raw_key = generate_key()
    key_hash_val = hash_key(raw_key)
    table = _get_table()
    table.put_item(Item={
        "key_hash": key_hash_val,
        "profile": profile,
        "description": description,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "enabled": True,
    })
    return raw_key, key_hash_val


def revoke_key(key_hash_val: str) -> bool:
    """Disable an API key."""
    table = _get_table()
    try:
        table.update_item(
            Key={"key_hash": key_hash_val},
            UpdateExpression="SET enabled = :v",
            ExpressionAttributeValues={":v": False},
        )
        return True
    except ClientError:
        return False
