"""
Cloudflare R2 storage service for NOMAZRA.
Organizes files into: nomazra/{user_id}/{category}/filename
Categories: profile, documents, chat_files, voice
"""
import os
import uuid
import mimetypes
import hashlib
import logging
from django.conf import settings

logger = logging.getLogger(__name__)

# Allowed MIME types — whitelisted, no executables
ALLOWED_MIME_TYPES = {
    # Documents
    'application/pdf', 'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'text/plain', 'text/csv',
    # Images
    'image/jpeg', 'image/png', 'image/webp', 'image/gif',
    # Audio
    'audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/mp4', 'audio/webm',
}

MAX_FILE_SIZE = 20 * 1024 * 1024  # 20MB


def _get_s3_client():
    import boto3
    return boto3.client(
        's3',
        endpoint_url=settings.R2_ENDPOINT_URL,
        aws_access_key_id=settings.R2_ACCESS_KEY_ID,
        aws_secret_access_key=settings.R2_SECRET_ACCESS_KEY,
        region_name='auto',
    )


def _get_bucket():
    return getattr(settings, 'R2_BUCKET_NAME', 'kelthos-storage')


def validate_upload(file_obj):
    """Validate file before upload — returns (ok, error_msg)."""
    if file_obj.size > MAX_FILE_SIZE:
        return False, f'File too large. Max {MAX_FILE_SIZE // (1024*1024)}MB.'

    mime = mimetypes.guess_type(file_obj.name)[0] or ''
    if mime not in ALLOWED_MIME_TYPES:
        return False, f'File type not allowed: {mime}'

    return True, ''


def upload_file(user_id, category, file_obj):
    """
    Upload a file to R2 under nomazra/{user_id}/{category}/
    Returns the full R2 key (path).
    """
    valid, err = validate_upload(file_obj)
    if not valid:
        raise ValueError(err)

    ext = os.path.splitext(file_obj.name)[1].lower()
    safe_name = f"{uuid.uuid4().hex}{ext}"
    key = f"nomazra/{user_id}/{category}/{safe_name}"

    client = _get_s3_client()
    mime = mimetypes.guess_type(file_obj.name)[0] or 'application/octet-stream'

    client.upload_fileobj(
        file_obj,
        _get_bucket(),
        key,
        ExtraArgs={
            'ContentType': mime,
            'ContentDisposition': f'inline; filename="{file_obj.name}"',
        },
    )

    logger.info("Uploaded %s to R2 key: %s", file_obj.name, key)
    return key


def upload_bytes(user_id, category, data, filename):
    """Upload raw bytes to R2."""
    import io
    ext = os.path.splitext(filename)[1].lower()
    safe_name = f"{uuid.uuid4().hex}{ext}"
    key = f"nomazra/{user_id}/{category}/{safe_name}"

    client = _get_s3_client()
    mime = mimetypes.guess_type(filename)[0] or 'application/octet-stream'

    client.upload_fileobj(
        io.BytesIO(data),
        _get_bucket(),
        key,
        ExtraArgs={'ContentType': mime},
    )
    return key


def get_presigned_url(key, expires_in=3600):
    """Generate a presigned GET URL for a file in R2."""
    client = _get_s3_client()
    return client.generate_presigned_url(
        'get_object',
        Params={'Bucket': _get_bucket(), 'Key': key},
        ExpiresIn=expires_in,
    )


def delete_file(key):
    """Delete a file from R2."""
    client = _get_s3_client()
    client.delete_object(Bucket=_get_bucket(), Key=key)
    logger.info("Deleted R2 key: %s", key)


def list_user_files(user_id, category=None):
    """List files for a user, optionally filtered by category."""
    prefix = f"nomazra/{user_id}/"
    if category:
        prefix = f"nomazra/{user_id}/{category}/"

    client = _get_s3_client()
    resp = client.list_objects_v2(Bucket=_get_bucket(), Prefix=prefix)
    return [obj['Key'] for obj in resp.get('Contents', [])]
