# middleware/frontend_type.py
"""
Frontend Type Detection Middleware

Sets request.state.frontend_type for all requests using centralized FrontendDetector.

This middleware replaces the old ContextMiddleware and provides a unified way to
detect which frontend (ADMIN, STORE, STOREFRONT, PLATFORM) is being accessed.

MUST run AFTER StoreContextMiddleware to have access to store context.
MUST run BEFORE LanguageMiddleware (which needs frontend_type).

Sets:
    request.state.frontend_type: FrontendType enum value
"""

import logging

from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware

from app.core.frontend_detector import FrontendDetector
from app.modules.enums import FrontendType

logger = logging.getLogger(__name__)


class FrontendTypeMiddleware(BaseHTTPMiddleware):
    """
    Middleware to detect and inject frontend type into request state.

    Uses FrontendDetector for centralized, consistent detection across the app.

    Runs AFTER StoreContextMiddleware in request chain.
    Depends on:
        request.state.store (optional, set by StoreContextMiddleware)
        request.state.clean_path (optional, set by StoreContextMiddleware)

    Sets:
        request.state.frontend_type: FrontendType enum value
    """

    async def dispatch(self, request: Request, call_next):
        """Detect frontend type and inject into request state."""
        host = request.headers.get("host", "")
        # Use platform_clean_path (platform prefix stripped, store prefix retained)
        # so FrontendDetector can distinguish /store/ from /storefront/.
        # Do NOT use clean_path here — it has the store prefix stripped too,
        # which makes /store/X/dashboard indistinguishable from /storefront/X/products.
        path = getattr(request.state, "platform_clean_path", None) or request.url.path

        # Check if store context exists (set by StoreContextMiddleware)
        has_store_context = (
            hasattr(request.state, "store")
            and request.state.store is not None
        )

        # Detect frontend type using centralized detector
        frontend_type = FrontendDetector.detect(
            host=host,
            path=path,
            has_store_context=has_store_context,
        )

        # Store in request state
        request.state.frontend_type = frontend_type

        # Log detection for debugging
        logger.debug(
            f"[FRONTEND_TYPE_MIDDLEWARE] Frontend type detected: {frontend_type.value}",
            extra={
                "path": request.url.path,
                "clean_path": getattr(request.state, "clean_path", "NOT SET"),
                "host": host,
                "frontend_type": frontend_type.value,
                "has_store": has_store_context,
            },
        )

        # Continue processing
        response = await call_next(request)
        return response


def get_frontend_type(request: Request) -> FrontendType | None:
    """
    Helper function to get current frontend type from request.

    Args:
        request: FastAPI request object

    Returns:
        FrontendType enum value, or None if the middleware hasn't run yet.
        Callers should handle None explicitly where context is clear.
    """
    return getattr(request.state, "frontend_type", None)
