# pylint: disable=import-outside-toplevel,too-many-positional-arguments
"""
Storage factory for creating storage instances from configuration.

Provides a simple way to instantiate storage backends based on
configuration without hard-coding implementation details.
"""
import os
from typing import Optional

from mini_videorag.core.storage import BaseObjectStorage
from mini_videorag.storage.s3_storage import S3Storage


class StorageFactory:
    """
    Factory for creating storage instances from configuration.

    Supports environment variable configuration for easy deployment
    across different environments (local, staging, production).

    Example:
        # From environment variables
        storage = StorageFactory.from_env()

        # From explicit config
        storage = StorageFactory.create(
            storage_type="minio",
            bucket_name="videos",
            endpoint_url="http://localhost:9000"
        )
    """

    @staticmethod
    def create(
        storage_type: str,
        bucket_name: str,
        endpoint_url: Optional[str] = None,
        region: str = "us-east-1",
        access_key: Optional[str] = None,
        secret_key: Optional[str] = None,
    ) -> BaseObjectStorage:
        """
        Create a storage instance.

        Args:
            storage_type: Type of storage ("s3", "minio" - both use S3Storage)
            bucket_name: Bucket name
            endpoint_url: Custom endpoint URL (required for MinIO)
            region: AWS region
            access_key: Access key ID
            secret_key: Secret access key

        Returns:
            Configured storage instance

        Raises:
            ValueError: If storage_type is not supported
        """
        storage_type = storage_type.lower()

        if storage_type in ["s3", "minio"]:
            storage = S3Storage(
                bucket_name=bucket_name,
                endpoint_url=endpoint_url,
                region=region,
                access_key=access_key,
                secret_key=secret_key,
            )

            if storage_type == "minio" and endpoint_url:
                import logging

                logger = logging.getLogger(__name__)
                try:
                    storage.create_bucket_if_not_exists()
                except Exception as e:  # pylint: disable=broad-exception-caught
                    logger.warning(f"Could not create bucket (may already exist): {e}")

            return storage

        raise ValueError(
            f"Unsupported storage type: {storage_type}. " f"Supported types: s3, minio"
        )

    @staticmethod
    def from_env() -> BaseObjectStorage:
        """
        Create a storage instance from environment variables.

        This is the recommended way to configure storage in production,
        as it follows 12-factor app principles.

        Returns:
            Configured storage instance

        Raises:
            ValueError: If required environment variables are missing
        """
        storage_type = os.getenv("STORAGE_TYPE", "s3")
        bucket_name = os.getenv("STORAGE_BUCKET_NAME")

        if not bucket_name:
            raise ValueError(
                "STORAGE_BUCKET_NAME environment variable is required. "
                "Example: export STORAGE_BUCKET_NAME=my-videos"
            )

        endpoint_url = os.getenv("STORAGE_ENDPOINT_URL")
        region = os.getenv("STORAGE_REGION", "us-east-1")
        access_key = os.getenv("STORAGE_ACCESS_KEY")
        secret_key = os.getenv("STORAGE_SECRET_KEY")

        import logging

        logger = logging.getLogger(__name__)
        if storage_type == "minio" and not endpoint_url:
            endpoint_url = "http://localhost:9000"
            logger.info(
                f"No STORAGE_ENDPOINT_URL provided for MinIO, using default: {endpoint_url}"
            )

        return StorageFactory.create(
            storage_type=storage_type,
            bucket_name=bucket_name,
            endpoint_url=endpoint_url,
            region=region,
            access_key=access_key,
            secret_key=secret_key,
        )
