"""Async S3 client wrapper for DigitalOcean Spaces (S3-compatible) operations."""

import os
from contextlib import asynccontextmanager

import aioboto3

_REQUIRED_ENV_VARS = (
    "DO_SPACES_ENDPOINT",
    "DO_SPACES_BUCKET",
    "DO_SPACES_KEY",
    "DO_SPACES_SECRET",
    "DO_SPACES_REGION",
)


def s3_configured() -> bool:
    """Return True if all required S3 environment variables are set."""
    return all(os.environ.get(v) for v in _REQUIRED_ENV_VARS)


@asynccontextmanager
async def get_s3_client():
    """Async context manager yielding an aioboto3 S3 client."""
    session = aioboto3.Session(
        aws_access_key_id=os.environ["DO_SPACES_KEY"],
        aws_secret_access_key=os.environ["DO_SPACES_SECRET"],
        region_name=os.environ["DO_SPACES_REGION"],
    )
    async with session.client(
        "s3",
        endpoint_url=os.environ["DO_SPACES_ENDPOINT"],
    ) as client:
        yield client


async def upload_file(s3_key: str, file_body: bytes, content_type: str) -> None:
    """Upload bytes to S3 at the given key."""
    async with get_s3_client() as client:
        await client.put_object(
            Bucket=os.environ["DO_SPACES_BUCKET"],
            Key=s3_key,
            Body=file_body,
            ContentType=content_type,
        )


async def delete_file(s3_key: str) -> None:
    """Delete an object from S3."""
    async with get_s3_client() as client:
        await client.delete_object(
            Bucket=os.environ["DO_SPACES_BUCKET"],
            Key=s3_key,
        )


async def generate_presigned_url(s3_key: str, expires_in: int = 900) -> str:
    """Generate a pre-signed download URL for an S3 object.

    Args:
        s3_key: The S3 object key.
        expires_in: Expiry duration in seconds (default: 900 = 15 minutes).

    Returns:
        A pre-signed URL string.
    """
    async with get_s3_client() as client:
        return client.generate_presigned_url(
            "get_object",
            Params={
                "Bucket": os.environ["DO_SPACES_BUCKET"],
                "Key": s3_key,
            },
            ExpiresIn=expires_in,
        )
