from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from django.shortcuts import get_object_or_404

from drf_spectacular.utils import OpenApiExample, extend_schema

from bookings.models import Booking
from structures.models import Structure

from .city_tax_service import (
    build_configured_exemption_map,
    build_monthly_rate_map,
    build_period_bounds,
    calculate_city_tax_report,
    get_missing_city_tax_settings_fields,
    normalize_platform_tokens,
)
from .models import StructureCityTaxSettings
from .serializers_city_tax_preview import CityTaxPreviewRequestSerializer


@extend_schema(
    tags=["City Tax"],
    summary="Preview city tax calculation for a structure and period",
    request=CityTaxPreviewRequestSerializer,
    examples=[
        OpenApiExample(
            name="Preview Request",
            value={
                "period": {"from_month": 1, "to_month": 3, "year": 2025},
                "rates": {"1": 3},
            },
            request_only=True,
        )
    ],
)
class CityTaxPreviewAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, structure_id):
        structure = get_object_or_404(Structure, id=structure_id)

        serializer = CityTaxPreviewRequestSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        period = serializer.validated_data["period"]
        rates_override = serializer.validated_data["rates"]
        property_type_id = serializer.validated_data.get("property_type_id")
        property_id = serializer.validated_data.get("property_id")

        settings = get_object_or_404(
            StructureCityTaxSettings,
            structure=structure,
            is_active=True,
        )

        missing = get_missing_city_tax_settings_fields(settings)
        if missing:
            return Response(
                {
                    "error": "City tax configuration incomplete",
                    "missing_fields": missing,
                },
                status=400,
            )

        period_start_year = period["year"]
        monthly_rate_map = build_monthly_rate_map(structure, period_start_year)
        configured_exemptions = build_configured_exemption_map(
            settings.exemption_reasons
        )
        platform_exemptions = normalize_platform_tokens(settings.platform_exemptions)
        period_start, period_end_exclusive, _ = build_period_bounds(period)

        bookings = (
            Booking.objects.filter(
                structure=structure,
                check_in_date__lt=period_end_exclusive,
                check_out_date__gt=period_start,
            )
            .select_related("property")
            .prefetch_related("guests")
        )

        if property_type_id:
            bookings = bookings.filter(property_type_id=property_type_id)

        if property_id:
            bookings = bookings.filter(property_id=property_id)

        result = calculate_city_tax_report(
            bookings=bookings.order_by("check_in_date", "id"),
            period=period,
            rates_override=rates_override,
            default_rate=settings.default_rate,
            monthly_rate_map=monthly_rate_map,
            max_taxable_nights=int(settings.max_taxable_nights or 0),
            minor_age_limit=int(settings.minor_age_limit or 0),
            configured_exemptions=configured_exemptions,
            platform_exemptions=platform_exemptions,
            platform_exemption_labels=list(settings.platform_exemptions or []),
        )

        return Response(result.preview_payload)
