"""MinIO / S3-compatible object storage.

Provides upload and presigned URL generation for converted DOCX files.
"""
from __future__ import annotations

import boto3
import structlog
from botocore.exceptions import ClientError

from config import settings
from core.exceptions import StorageError

log = structlog.get_logger()

# Pack credit values — used by payment service to resolve pack → credit count
PACK_CREDITS: dict[str, int] = {
    'starter': 5,
    'studio':  20,
    'agency':  60,
}


def _s3_client():
    return boto3.client(
        's3',
        endpoint_url=settings.s3_endpoint_url,
        region_name=settings.s3_region,
        aws_access_key_id=settings.aws_access_key_id,
        aws_secret_access_key=settings.aws_secret_access_key,
    )


def upload_docx(object_key: str, docx_bytes: bytes) -> str:
    """Upload a DOCX file to MinIO and return a presigned download URL.

    Args:
        object_key: S3 object key, e.g. 'conversions/<session_id>.docx'
        docx_bytes: Raw DOCX bytes.

    Returns:
        Presigned URL valid for settings.s3_presign_expiry_seconds.

    Raises:
        StorageError: If upload or presign fails.
    """
    client = _s3_client()
    try:
        client.put_object(
            Bucket=settings.s3_bucket,
            Key=object_key,
            Body=docx_bytes,
            ContentType='application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        )
        log.info('docx_uploaded', key=object_key, size_bytes=len(docx_bytes))
    except ClientError as e:
        log.error('docx_upload_failed', key=object_key, error=str(e))
        raise StorageError(f'Upload failed: {e}')

    try:
        url = client.generate_presigned_url(
            'get_object',
            Params={'Bucket': settings.s3_bucket, 'Key': object_key},
            ExpiresIn=settings.s3_presign_expiry_seconds,
        )
        return url
    except ClientError as e:
        log.error('docx_presign_failed', key=object_key, error=str(e))
        raise StorageError(f'Presign failed: {e}')


def storage_available() -> bool:
    """Return True if MinIO/S3 is reachable and the bucket exists."""
    try:
        client = _s3_client()
        client.head_bucket(Bucket=settings.s3_bucket)
        return True
    except Exception:
        return False
