"""File storage service for handling document uploads."""

import os
from pathlib import Path
from uuid import UUID

import structlog
from fastapi import UploadFile

logger = structlog.get_logger(__name__)


class FileStorageError(Exception):
    """Custom exception for file storage errors."""

    pass


async def save_uploaded_file(document_id: UUID, file: UploadFile) -> str:
    """Save uploaded file to storage directory.

    Creates directory structure: storage/{document_id}/{filename}

    Args:
        document_id: UUID of the document record.
        file: FastAPI UploadFile object.

    Returns:
        The full file path where the file was saved.

    Raises:
        FileStorageError: If file write fails.
    """
    try:
        # Create storage directory structure
        storage_base = Path("storage")
        document_dir = storage_base / str(document_id)
        document_dir.mkdir(parents=True, exist_ok=True)

        # Construct file path
        file_path = document_dir / file.filename
        full_path = str(file_path)

        # Write file in chunks to handle large files efficiently
        with open(full_path, "wb") as f:
            while chunk := await file.read(8192):  # 8KB chunks
                f.write(chunk)

        logger.info(
            "file_saved",
            document_id=str(document_id),
            filename=file.filename,
            file_path=full_path,
        )

        return full_path

    except OSError as e:
        logger.error(
            "file_save_failed",
            document_id=str(document_id),
            filename=file.filename,
            error=str(e),
        )
        raise FileStorageError(f"Failed to save file: {e}") from e
    except Exception as e:
        logger.error(
            "unexpected_file_save_error",
            document_id=str(document_id),
            filename=file.filename,
            error=str(e),
        )
        raise FileStorageError(f"Unexpected error saving file: {e}") from e
