"""
Route Builder for standardized URL structure
Ensures consistent API patterns across all microservices
"""

from enum import Enum
from typing import Optional


class RouteCategory(Enum):
    """Categories of API routes with different access patterns"""
    BASE = "base"              # Atomic CRUD operations on resources
    DASHBOARD = "dashboard"    # Dashboard data and summaries
    ANALYTICS = "analytics"    # Analytics endpoints (tier-gated)
    OPERATIONS = "operations"  # Service-specific operations


class RouteBuilder:
    """
    Builder for creating standardized API routes

    URL Structure:
    - Base: /api/v1/tenants/{tenant_id}/{service}/{resource}
    - Dashboard: /api/v1/tenants/{tenant_id}/{service}/dashboard/{operation}
    - Analytics: /api/v1/tenants/{tenant_id}/{service}/analytics/{operation}
    - Operations: /api/v1/tenants/{tenant_id}/{service}/operations/{operation}
    """

    API_VERSION = "v1"
    BASE_PATH = f"/api/{API_VERSION}"

    def __init__(self, service_name: str):
        """
        Initialize route builder for a specific service

        Args:
            service_name: Name of the service (e.g., 'inventory', 'production')
        """
        self.service_name = service_name

    def build_base_route(self, resource: str, include_tenant_prefix: bool = True) -> str:
        """
        Build base CRUD route for a resource

        Args:
            resource: Resource name (e.g., 'ingredients', 'batches')
                     Empty string returns just the service path
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('inventory')
            builder.build_base_route('ingredients')
            # Returns: '/api/v1/tenants/{tenant_id}/inventory/ingredients'

            builder.build_base_route('')
            # Returns: '/api/v1/tenants/{tenant_id}/inventory'
        """
        if resource:
            # Resource provided - add it to the path
            if include_tenant_prefix:
                return f"{self.BASE_PATH}/tenants/{{tenant_id}}/{self.service_name}/{resource}"
            return f"{self.BASE_PATH}/{self.service_name}/{resource}"
        else:
            # Empty resource - return just the service path
            if include_tenant_prefix:
                return f"{self.BASE_PATH}/tenants/{{tenant_id}}/{self.service_name}"
            return f"{self.BASE_PATH}/{self.service_name}"

    def build_dashboard_route(self, operation: str, include_tenant_prefix: bool = True) -> str:
        """
        Build dashboard route

        Args:
            operation: Dashboard operation (e.g., 'summary', 'capacity-status')
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('production')
            builder.build_dashboard_route('summary')
            # Returns: '/api/v1/tenants/{tenant_id}/production/dashboard/summary'
        """
        if include_tenant_prefix:
            return f"{self.BASE_PATH}/tenants/{{tenant_id}}/{self.service_name}/dashboard/{operation}"
        return f"{self.BASE_PATH}/{self.service_name}/dashboard/{operation}"

    def build_analytics_route(self, operation: str, include_tenant_prefix: bool = True) -> str:
        """
        Build analytics route (tier-gated: professional/enterprise)

        Args:
            operation: Analytics operation (e.g., 'equipment-efficiency', 'trends')
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('production')
            builder.build_analytics_route('equipment-efficiency')
            # Returns: '/api/v1/tenants/{tenant_id}/production/analytics/equipment-efficiency'
        """
        if include_tenant_prefix:
            return f"{self.BASE_PATH}/tenants/{{tenant_id}}/{self.service_name}/analytics/{operation}"
        return f"{self.BASE_PATH}/{self.service_name}/analytics/{operation}"

    def build_operations_route(self, operation: str, include_tenant_prefix: bool = True) -> str:
        """
        Build service operations route

        Args:
            operation: Operation name (e.g., 'schedule-batch', 'stock-adjustment')
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('production')
            builder.build_operations_route('schedule-batch')
            # Returns: '/api/v1/tenants/{tenant_id}/production/operations/schedule-batch'
        """
        if include_tenant_prefix:
            return f"{self.BASE_PATH}/tenants/{{tenant_id}}/{self.service_name}/operations/{operation}"
        return f"{self.BASE_PATH}/{self.service_name}/operations/{operation}"

    def build_resource_detail_route(self, resource: str, id_param: str = "id", include_tenant_prefix: bool = True) -> str:
        """
        Build route for individual resource details

        Args:
            resource: Resource name
            id_param: Name of the ID parameter
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('inventory')
            builder.build_resource_detail_route('ingredients', 'ingredient_id')
            # Returns: '/api/v1/tenants/{tenant_id}/inventory/ingredients/{ingredient_id}'
        """
        base = self.build_base_route(resource, include_tenant_prefix)
        return f"{base}/{{{id_param}}}"

    def build_nested_resource_route(
        self,
        parent_resource: str,
        parent_id_param: str,
        child_resource: str,
        include_tenant_prefix: bool = True
    ) -> str:
        """
        Build route for nested resources

        Args:
            parent_resource: Parent resource name
            parent_id_param: Parent ID parameter name
            child_resource: Child resource name
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('inventory')
            builder.build_nested_resource_route('ingredients', 'ingredient_id', 'stock')
            # Returns: '/api/v1/tenants/{tenant_id}/inventory/ingredients/{ingredient_id}/stock'
        """
        base = self.build_resource_detail_route(parent_resource, parent_id_param, include_tenant_prefix)
        return f"{base}/{child_resource}"

    def build_resource_action_route(
        self,
        resource: str,
        id_param: str,
        action: str,
        include_tenant_prefix: bool = True
    ) -> str:
        """
        Build route for resource-specific actions

        Args:
            resource: Resource name
            id_param: ID parameter name
            action: Action name
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('pos')
            builder.build_resource_action_route('configurations', 'config_id', 'test-connection')
            # Returns: '/api/v1/tenants/{tenant_id}/pos/configurations/{config_id}/test-connection'
        """
        base = self.build_resource_detail_route(resource, id_param, include_tenant_prefix)
        return f"{base}/{action}"

    def build_global_route(self, path: str) -> str:
        """
        Build global route without tenant context

        Args:
            path: Path after service name

        Returns:
            Route path

        Example:
            builder = RouteBuilder('pos')
            builder.build_global_route('supported-systems')
            # Returns: '/api/v1/pos/supported-systems'
        """
        return f"{self.BASE_PATH}/{self.service_name}/{path}"

    def build_webhook_route(self, path: str) -> str:
        """
        Build webhook route (no tenant context)

        Args:
            path: Webhook path

        Returns:
            Route path

        Example:
            builder = RouteBuilder('pos')
            builder.build_webhook_route('{pos_system}')
            # Returns: '/api/v1/webhooks/{pos_system}'
        """
        return f"{self.BASE_PATH}/webhooks/{path}"

    def build_custom_route(
        self,
        category: RouteCategory,
        path_segments: list,
        include_tenant_prefix: bool = True
    ) -> str:
        """
        Build custom route with specified category and path segments

        Args:
            category: Route category
            path_segments: List of path segments after category
            include_tenant_prefix: Whether to include /tenants/{tenant_id} prefix

        Returns:
            Route path

        Example:
            builder = RouteBuilder('inventory')
            builder.build_custom_route(RouteCategory.DASHBOARD, ['food-safety', 'compliance'])
            # Returns: '/api/v1/tenants/{tenant_id}/inventory/dashboard/food-safety/compliance'
        """
        base_prefix = f"{self.BASE_PATH}/tenants/{{tenant_id}}" if include_tenant_prefix else self.BASE_PATH

        # Build path segments string, avoiding trailing slash when empty
        segments_str = '/'.join(path_segments) if path_segments else ''
        separator = '/' if segments_str else ''

        if category == RouteCategory.BASE:
            return f"{base_prefix}/{self.service_name}{separator}{segments_str}"
        elif category == RouteCategory.DASHBOARD:
            return f"{base_prefix}/{self.service_name}/dashboard{separator}{segments_str}"
        elif category == RouteCategory.ANALYTICS:
            return f"{base_prefix}/{self.service_name}/analytics{separator}{segments_str}"
        elif category == RouteCategory.OPERATIONS:
            return f"{base_prefix}/{self.service_name}/operations{separator}{segments_str}"

        # Fallback to base
        return f"{base_prefix}/{self.service_name}{separator}{segments_str}"

    @staticmethod
    def get_route_pattern(category: RouteCategory, service_name: Optional[str] = None) -> str:
        """
        Get regex pattern for matching routes of a specific category

        Args:
            category: Route category
            service_name: Optional service name to filter

        Returns:
            Regex pattern for route matching

        Example:
            RouteBuilder.get_route_pattern(RouteCategory.ANALYTICS)
            # Returns: r'^/api/v1/tenants/[^/]+/[^/]+/analytics/.*'

            RouteBuilder.get_route_pattern(RouteCategory.ANALYTICS, 'production')
            # Returns: r'^/api/v1/tenants/[^/]+/production/analytics/.*'
        """
        service_pattern = service_name if service_name else "[^/]+"

        if category == RouteCategory.BASE:
            return rf"^/api/v1/tenants/[^/]+/{service_pattern}/(?!dashboard|analytics|operations)[^/]+.*"
        elif category == RouteCategory.DASHBOARD:
            return rf"^/api/v1/tenants/[^/]+/{service_pattern}/dashboard/.*"
        elif category == RouteCategory.ANALYTICS:
            return rf"^/api/v1/tenants/[^/]+/{service_pattern}/analytics/.*"
        elif category == RouteCategory.OPERATIONS:
            return rf"^/api/v1/tenants/[^/]+/{service_pattern}/operations/.*"

        return rf"^/api/v1/tenants/[^/]+/{service_pattern}/.*"
