"""
Trending content API views for ThrillWiki API v1.

This module contains endpoints for trending and new content discovery
including trending parks, rides, and recently added content.
"""

from datetime import date, datetime

from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_view
from rest_framework import status
from rest_framework.permissions import AllowAny, IsAdminUser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView


@extend_schema_view(
    get=extend_schema(
        summary="Get trending content",
        description="Retrieve trending parks and rides based on view counts, ratings, and recency.",
        parameters=[
            OpenApiParameter(
                name="limit",
                location=OpenApiParameter.QUERY,
                description="Number of trending items to return (default: 20, max: 100)",
                required=False,
                type=OpenApiTypes.INT,
                default=20,
            ),
            OpenApiParameter(
                name="timeframe",
                location=OpenApiParameter.QUERY,
                description="Timeframe for trending calculation (day, week, month) - default: week",
                required=False,
                type=OpenApiTypes.STR,
                enum=["day", "week", "month"],
                default="week",
            ),
        ],
        responses={200: OpenApiTypes.OBJECT},
        tags=["Trending"],
    ),
)
class TrendingAPIView(APIView):
    """API endpoint for trending content."""

    permission_classes = [AllowAny]

    def get(self, request: Request) -> Response:
        """Get trending parks and rides."""
        from apps.core.services.trending_service import trending_service

        # Parse parameters
        limit = min(int(request.query_params.get("limit", 20)), 100)

        # Get trending content using direct calculation service
        all_trending = trending_service.get_trending_content(limit=limit * 2)

        # Separate by content type
        trending_rides = []
        trending_parks = []

        for item in all_trending:
            if item.get("category") == "ride":
                trending_rides.append(item)
            elif item.get("category") == "park":
                trending_parks.append(item)

        # Limit each category
        trending_rides = trending_rides[: limit // 3] if trending_rides else []
        trending_parks = trending_parks[: limit // 3] if trending_parks else []

        # Latest reviews will be empty until review system is implemented
        latest_reviews = []

        # Return in expected frontend format
        response_data = {
            "trending_rides": trending_rides,
            "trending_parks": trending_parks,
            "latest_reviews": latest_reviews,
        }

        return Response(response_data)


@extend_schema_view(
    post=extend_schema(
        summary="Trigger trending content calculation",
        description="Manually trigger the calculation of trending content using Django management commands. Admin access required.",
        responses={
            202: {
                "type": "object",
                "properties": {
                    "message": {"type": "string"},
                    "trending_completed": {"type": "boolean"},
                    "new_content_completed": {"type": "boolean"},
                    "completion_time": {"type": "string"},
                },
            },
            403: {"description": "Admin access required"},
        },
        tags=["Trending"],
    ),
)
class TriggerTrendingCalculationAPIView(APIView):
    """API endpoint to manually trigger trending content calculation."""

    permission_classes = [IsAdminUser]

    def post(self, request: Request) -> Response:
        """Trigger trending content calculation using management commands."""
        try:
            import io
            from contextlib import redirect_stderr, redirect_stdout

            from django.core.management import call_command

            # Capture command output
            trending_output = io.StringIO()
            new_content_output = io.StringIO()

            trending_completed = False
            new_content_completed = False

            try:
                # Run trending calculation command
                with redirect_stdout(trending_output), redirect_stderr(trending_output):
                    call_command("calculate_trending", "--content-type=all", "--limit=50")
                trending_completed = True
            except Exception as e:
                trending_output.write(f"Error: {str(e)}")

            try:
                # Run new content calculation command
                with redirect_stdout(new_content_output), redirect_stderr(new_content_output):
                    call_command(
                        "calculate_new_content",
                        "--content-type=all",
                        "--days-back=30",
                        "--limit=50",
                    )
                new_content_completed = True
            except Exception as e:
                new_content_output.write(f"Error: {str(e)}")

            completion_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

            return Response(
                {
                    "detail": "Trending content calculation completed",
                    "trending_completed": trending_completed,
                    "new_content_completed": new_content_completed,
                    "completion_time": completion_time,
                    "trending_output": trending_output.getvalue(),
                    "new_content_output": new_content_output.getvalue(),
                },
                status=status.HTTP_202_ACCEPTED,
            )

        except Exception as e:
            return Response(
                {
                    "detail": "Failed to trigger trending content calculation",
                    "details": str(e),
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )


@extend_schema_view(
    get=extend_schema(
        summary="Get new content",
        description="Retrieve recently added parks and rides.",
        parameters=[
            OpenApiParameter(
                name="limit",
                location=OpenApiParameter.QUERY,
                description="Number of new items to return (default: 20, max: 100)",
                required=False,
                type=OpenApiTypes.INT,
                default=20,
            ),
            OpenApiParameter(
                name="days",
                location=OpenApiParameter.QUERY,
                description="Number of days to look back for new content (default: 30, max: 365)",
                required=False,
                type=OpenApiTypes.INT,
                default=30,
            ),
        ],
        responses={200: OpenApiTypes.OBJECT},
        tags=["Trending"],
    ),
)
class NewContentAPIView(APIView):
    """API endpoint for new content."""

    permission_classes = [AllowAny]

    def get(self, request: Request) -> Response:
        """Get new parks and rides."""
        from apps.core.services.trending_service import trending_service

        # Parse parameters
        limit = min(int(request.query_params.get("limit", 20)), 100)
        days_back = min(int(request.query_params.get("days", 30)), 365)

        # Get new content using direct calculation service
        all_new_content = trending_service.get_new_content(limit=limit * 2, days_back=days_back)

        recently_added = []
        newly_opened = []
        upcoming = []

        # Categorize items based on date
        today = date.today()

        for item in all_new_content:
            date_added = item.get("date_added", "")
            if date_added:
                try:
                    # Parse the date string
                    item_date = datetime.fromisoformat(date_added).date() if isinstance(date_added, str) else date_added

                    # Calculate days difference
                    days_diff = (today - item_date).days

                    if days_diff <= 30:  # Recently added (last 30 days)
                        recently_added.append(item)
                    elif days_diff <= 365:  # Newly opened (last year)
                        newly_opened.append(item)
                    else:  # Older items
                        newly_opened.append(item)

                except (ValueError, TypeError):
                    # If date parsing fails, add to recently added
                    recently_added.append(item)
            else:
                recently_added.append(item)

        # Upcoming items will be empty until future content system is implemented
        upcoming = []

        # Limit each category
        recently_added = recently_added[: limit // 3] if recently_added else []
        newly_opened = newly_opened[: limit // 3] if newly_opened else []

        # Return in expected frontend format
        response_data = {
            "recently_added": recently_added,
            "newly_opened": newly_opened,
            "upcoming": upcoming,
        }

        return Response(response_data)
