"""
Dashboard views for Aimantis hotel management platform.

Provides optimized, cached dashboard API with:
- Structure-based filtering
- Multi-tenant isolation
- Service-layer architecture
- Django cache integration
- Serializer-driven responses
- drf-spectacular compatibility
"""

from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from django.core.cache import cache

from structures.models import Structure

from dashboard.constants import (
    DASHBOARD_CACHE_TIMEOUT,
    DASHBOARD_CACHE_KEY_PREFIX,
    DEFAULT_UPCOMING_EVENTS_LIMIT,
)
from dashboard.permissions import HasStructureAccess
from dashboard.serializers import DashboardResponseSerializer
from dashboard.services.charts_service import ChartsService
from dashboard.services.occupancy_service import OccupancyService
from dashboard.services.overview_service import OverviewService
from dashboard.services.pricing_service import PricingService
from dashboard.services.upcoming_events_service import UpcomingEventsService
from dashboard.services.utils import get_today


class DashboardWidgetsView(APIView):
    """
    Dashboard widgets API endpoint.
    
    Returns comprehensive dashboard data including:
    - Overview metrics (check-ins, check-outs, occupancy)
    - Occupancy forecasts (today, 7 days, 30 days)
    - Average nightly rates
    - Upcoming events (chronological)
    - Monthly occupancy charts
    
    Supports structure filtering via query parameter.
    Response is cached for performance.
    
    Query Parameters:
        structure (int): Structure ID to filter by (optional)
        events_limit (int): Max upcoming events to return (default: 5)
    """
    
    permission_classes = [IsAuthenticated, HasStructureAccess]
    
    def _get_cache_key(self, structure_id: int = None) -> str:
        """
        Generate cache key for the dashboard data.
        
        Args:
            structure_id: Optional structure ID
            
        Returns:
            Cache key string
        """
        today = get_today().isoformat()
        structure_part = structure_id or "all"
        return f"{DASHBOARD_CACHE_KEY_PREFIX}:{structure_part}:{today}"
    
    def _get_cached_response(self, cache_key: str):
        """
        Attempt to retrieve cached dashboard response.
        
        Args:
            cache_key: Cache key to look up
            
        Returns:
            Cached data or None
        """
        return cache.get(cache_key)
    
    def _cache_response(self, cache_key: str, data: dict):
        """
        Cache the dashboard response.
        
        Args:
            cache_key: Cache key
            data: Data to cache
        """
        cache.set(cache_key, data, timeout=DASHBOARD_CACHE_TIMEOUT)
    
    def _get_structure_info(self, structure_id: int = None) -> dict:
        """
        Get structure information for the response.
        
        Args:
            structure_id: Optional structure ID
            
        Returns:
            Dict with structure id and name
        """
        if structure_id:
            structure = Structure.objects.filter(id=structure_id).first()
            if structure:
                return {"id": structure.id, "name": structure.name}
        
        # Default/fallback
        return {"id": None, "name": "All Structures"}
    
    def get(self, request):
        """
        GET /api/dashboard/widgets
        
        Retrieve dashboard data with optional structure filtering.
        """
        # Parse query parameters
        structure_id = request.query_params.get("structure")
        events_limit = request.query_params.get("events_limit")
        
        # Convert to proper types
        structure_id = int(structure_id) if structure_id else None
        events_limit = int(events_limit) if events_limit else DEFAULT_UPCOMING_EVENTS_LIMIT
        
        # Check cache
        cache_key = self._get_cache_key(structure_id)
        cached_data = self._get_cached_response(cache_key)
        
        if cached_data:
            return Response(cached_data, status=status.HTTP_200_OK)
        
        # Get today's date
        today = get_today()
        
        # Initialize services
        overview_service = OverviewService(structure_id=structure_id)
        occupancy_service = OccupancyService(structure_id=structure_id)
        pricing_service = PricingService(structure_id=structure_id)
        events_service = UpcomingEventsService(
            structure_id=structure_id,
            limit=events_limit,
        )
        charts_service = ChartsService(structure_id=structure_id)
        
        # Build response data
        response_data = {
            "date": today.isoformat(),
            "structure": self._get_structure_info(structure_id),
            "overview": overview_service.get_overview(),
            "occupancy": occupancy_service.get_occupancy(),
            "average_rates": pricing_service.get_average_rates(),
            "upcoming_events": events_service.get_events(),
            "charts": charts_service.get_charts_data(),
        }
        
        # Serialize response
        serializer = DashboardResponseSerializer(data=response_data)
        serializer.is_valid(raise_exception=True)
        
        serialized_data = serializer.data
        
        # Cache the response
        self._cache_response(cache_key, serialized_data)
        
        return Response(serialized_data, status=status.HTTP_200_OK)