import os
from contextlib import asynccontextmanager
from typing import AsyncIterator

import aioboto3
from botocore.exceptions import ClientError

MINIO_ENDPOINT: str = os.getenv("MINIO_ENDPOINT", "http://minio:9000")
MINIO_ACCESS_KEY: str = os.getenv("MINIO_ACCESS_KEY", "minioadmin")
MINIO_SECRET_KEY: str = os.getenv("MINIO_SECRET_KEY", "minioadminpassword")
MINIO_BUCKET: str = os.getenv("MINIO_BUCKET", "tickets-media")

_session = aioboto3.Session()


@asynccontextmanager
async def _s3_client() -> AsyncIterator:
    async with _session.client(
        "s3",
        endpoint_url=MINIO_ENDPOINT,
        aws_access_key_id=MINIO_ACCESS_KEY,
        aws_secret_access_key=MINIO_SECRET_KEY,
        region_name="us-east-1",  # MinIO не требует региона, но boto3 обязывает передать
    ) as client:
        yield client


async def ensure_bucket_exists() -> None:
    """Создаёт бакет при старте воркера, если он ещё не существует."""
    async with _s3_client() as client:
        try:
            await client.head_bucket(Bucket=MINIO_BUCKET)
        except ClientError as exc:
            error_code = exc.response["Error"]["Code"]
            if error_code in ("404", "NoSuchBucket"):
                await client.create_bucket(Bucket=MINIO_BUCKET)
            else:
                raise


async def upload_pdf(object_name: str, pdf_bytes: bytes) -> str:
    """Загружает PDF в MinIO и возвращает публичный URL объекта."""
    async with _s3_client() as client:
        await client.put_object(
            Bucket=MINIO_BUCKET,
            Key=object_name,
            Body=pdf_bytes,
            ContentType="application/pdf",
        )
    return f"{MINIO_ENDPOINT}/{MINIO_BUCKET}/{object_name}"
