"""S3 helpers for attachment upload/delete/pre-signed URL generation.

Configuration is read from environment variables at call time so that tests
and runtime can override without patching module-level state.

Required env vars:
  DO_SPACES_BUCKET      — S3/Spaces bucket name
  DO_SPACES_KEY         — Access key
  DO_SPACES_SECRET      — Secret key
  DO_SPACES_REGION      — Region (e.g. atl1)
  DO_SPACES_ENDPOINT    — Endpoint URL (e.g. https://atl1.digitaloceanspaces.com)

Optional:
  PEON_S3_PRESIGN_TTL   — presigned URL TTL in seconds (default 3600)
"""

from __future__ import annotations

import os


def get_s3_bucket() -> str | None:
    """Return the configured S3 bucket name, or None if not set."""
    return os.environ.get("DO_SPACES_BUCKET") or None


def _s3_kwargs() -> dict:
    kwargs: dict = {
        "aws_access_key_id": os.environ.get("DO_SPACES_KEY"),
        "aws_secret_access_key": os.environ.get("DO_SPACES_SECRET"),
        "region_name": os.environ.get("DO_SPACES_REGION", "us-east-1"),
    }
    endpoint = os.environ.get("DO_SPACES_ENDPOINT")
    if endpoint:
        kwargs["endpoint_url"] = endpoint
    return kwargs


def _presign_ttl() -> int:
    try:
        return int(os.environ.get("PEON_S3_PRESIGN_TTL", "3600"))
    except ValueError:
        return 3600


async def upload_fileobj(s3_key: str, data: bytes, content_type: str, bucket: str) -> None:
    """Upload raw bytes to S3 under *s3_key*."""
    import aioboto3

    session = aioboto3.Session()
    async with session.client("s3", **_s3_kwargs()) as s3:
        await s3.put_object(
            Bucket=bucket,
            Key=s3_key,
            Body=data,
            ContentType=content_type,
        )


async def delete_object(s3_key: str, bucket: str) -> None:
    """Delete an object from S3."""
    import aioboto3

    session = aioboto3.Session()
    async with session.client("s3", **_s3_kwargs()) as s3:
        await s3.delete_object(Bucket=bucket, Key=s3_key)


async def generate_presigned_url(s3_key: str, bucket: str) -> str:
    """Generate a pre-signed GET URL for *s3_key*."""
    import aioboto3

    session = aioboto3.Session()
    async with session.client("s3", **_s3_kwargs()) as s3:
        url: str = await s3.generate_presigned_url(
            "get_object",
            Params={"Bucket": bucket, "Key": s3_key},
            ExpiresIn=_presign_ttl(),
        )
    return url


async def generate_presigned_urls(s3_keys: list[str], bucket: str) -> list[str]:
    """Generate pre-signed GET URLs for multiple keys using a single S3 client."""
    import aioboto3

    session = aioboto3.Session()
    async with session.client("s3", **_s3_kwargs()) as s3:
        ttl = _presign_ttl()
        urls = []
        for key in s3_keys:
            url: str = await s3.generate_presigned_url(
                "get_object",
                Params={"Bucket": bucket, "Key": key},
                ExpiresIn=ttl,
            )
            urls.append(url)
    return urls
