from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import viewsets, permissions, filters, status
from rest_framework.decorators import action
import logging

from .models import (
    School,
    Country,
    State,
    City,
    Area,
    Pincode,
)

from .location_serializers import (
    CountrySerializer,
    StateSerializer,
    PincodeSerializer,
    AreaSerializer,
    CitySerializer,
)

logger = logging.getLogger(__name__)


class CountryViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for Country model
    """

    queryset = Country.objects.all().order_by("sort_order", "name")
    serializer_class = CountrySerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "phone_code", "currency_code"]
    ordering_fields = ["name", "code", "sort_order", "is_active"]

    @action(detail=True, methods=["get"])
    def stats(self, request, pk=None):
        """Get statistics for a country"""
        country = self.get_object()
        stats = {
            "total_states": country.states.count(),
            "total_cities": City.objects.filter(state__country=country).count(),
            "total_schools": School.objects.filter(country=country).count(),
            "states_with_cities": country.states.annotate(city_count=Count("cities"))
            .filter(city_count__gt=0)
            .count(),
        }
        return Response(stats)

    @action(detail=False, methods=["get"])
    def active(self, request):
        """Get only active countries"""
        countries = Country.objects.filter(is_active=True).order_by(
            "sort_order", "name"
        )
        serializer = self.get_serializer(countries, many=True)
        return Response(serializer.data)


class StateViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for State model
    """

    queryset = State.objects.all().order_by("country", "sort_order", "name")
    serializer_class = StateSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "local_name", "capital"]
    ordering_fields = ["name", "code", "sort_order", "is_active", "population"]

    def get_queryset(self):
        """Filter states by country if country_id query param is provided"""
        queryset = super().get_queryset()
        country_code = self.request.query_params.get("country_code")
        if country_code:
            queryset = queryset.filter(country__code=country_code)
        return queryset

    @action(detail=True, methods=["get"])
    def cities(self, request, pk=None):
        """Get all cities in this state"""
        state = self.get_object()
        cities = state.cities.filter(is_active=True).order_by("name")
        serializer = CitySerializer(cities, many=True)
        return Response(serializer.data)


class CityViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for City model
    """

    queryset = City.objects.all().order_by("state", "sort_order", "name")
    serializer_class = CitySerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "local_name"]
    ordering_fields = ["name", "sort_order", "is_active", "population", "is_metro"]

    def get_queryset(self):
        """Filter cities by state if state_id query param is provided"""
        queryset = super().get_queryset()
        state_id = self.request.query_params.get("state_id")
        if state_id:
            queryset = queryset.filter(state_id=state_id)
        return queryset

    @action(detail=True, methods=["get"])
    def areas(self, request, pk=None):
        """Get all areas in this city"""
        city = self.get_object()
        areas = city.areas.filter(is_active=True).order_by("name")
        serializer = AreaSerializer(areas, many=True)
        return Response(serializer.data)


class AreaViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for Area model
    """

    queryset = Area.objects.all().order_by("city", "sort_order", "name")
    serializer_class = AreaSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["name", "local_name", "pincode", "zone"]
    ordering_fields = ["name", "sort_order", "is_active"]

    def get_queryset(self):
        """Filter areas by city if city_id query param is provided"""
        queryset = super().get_queryset()
        city_id = self.request.query_params.get("city_id")
        if city_id:
            queryset = queryset.filter(city_id=city_id)
        return queryset

    @action(detail=True, methods=["get"])
    def pincodes(self, request, pk=None):
        """Get all pincodes in this area"""
        area = self.get_object()
        pincodes = area.pincodes.filter(is_active=True).order_by("pincode")
        serializer = PincodeSerializer(pincodes, many=True)
        return Response(serializer.data)


class PincodeViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for Pincode model
    """

    queryset = Pincode.objects.all().order_by("pincode")
    serializer_class = PincodeSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["pincode", "delivery_office", "delivery_status"]
    ordering_fields = ["pincode", "is_active"]

    def get_queryset(self):
        """Filter pincodes by area if area_id query param is provided"""
        queryset = super().get_queryset()
        area_id = self.request.query_params.get("area_id")
        if area_id:
            queryset = queryset.filter(area_id=area_id)
        pincode = self.request.query_params.get("pincode")
        if pincode:
            queryset = queryset.filter(pincode__icontains=pincode)
        return queryset

    # In views.py, add these views


class CountryStatesView(APIView):
    """Get states for a specific country (nested endpoint)"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, country_code):
        try:
            states = State.objects.filter(
                country__code=country_code.upper(), is_active=True
            ).order_by("sort_order", "name")
            serializer = StateSerializer(states, many=True)
            return Response(serializer.data)
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class StateCitiesView(APIView):
    """Get cities for a specific state (nested endpoint)"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, state_id):
        try:
            state_id = int(state_id)
            cities = City.objects.filter(state_id=state_id, is_active=True).order_by(
                "sort_order", "name"
            )
            serializer = CitySerializer(cities, many=True)
            return Response(serializer.data)
        except ValueError:
            return Response(
                {"error": "Invalid state ID"}, status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class CityAreasView(APIView):
    """Get areas for a specific city (nested endpoint)"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, city_id):
        try:
            city_id = int(city_id)
            areas = Area.objects.filter(city_id=city_id, is_active=True).order_by(
                "sort_order", "name"
            )
            serializer = AreaSerializer(areas, many=True)
            return Response(serializer.data)
        except ValueError:
            return Response(
                {"error": "Invalid city ID"}, status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class AreaPincodesView(APIView):
    """Get pincodes for a specific area (nested endpoint)"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, area_id):
        try:
            area_id = int(area_id)
            pincodes = Pincode.objects.filter(area_id=area_id, is_active=True).order_by(
                "pincode"
            )
            serializer = PincodeSerializer(pincodes, many=True)
            return Response(serializer.data)
        except ValueError:
            return Response(
                {"error": "Invalid area ID"}, status=status.HTTP_400_BAD_REQUEST
            )
        except Exception as e:
            return Response(
                {"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class CountryListView(APIView):
    """Get list of all active countries"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        countries = Country.objects.filter(is_active=True).order_by(
            "sort_order", "name"
        )
        serializer = CountrySerializer(countries, many=True)
        return Response(serializer.data)


class StateListView(APIView):
    """Get list of states, optionally filtered by country"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        states = State.objects.filter(is_active=True)

        # Filter by country if country_code provided
        country_code = request.query_params.get("country_code")
        if country_code:
            states = states.filter(country__code=country_code)

        states = states.order_by("sort_order", "name")
        serializer = StateSerializer(states, many=True)
        return Response(serializer.data)


class CityListView(APIView):
    """Get list of cities, optionally filtered by state"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        cities = City.objects.filter(is_active=True)

        # Filter by state if state_id provided
        state_id = request.query_params.get("state_id")
        if state_id:
            try:
                cities = cities.filter(state_id=int(state_id))
            except ValueError:
                pass

        cities = cities.order_by("sort_order", "name")
        serializer = CitySerializer(cities, many=True)
        return Response(serializer.data)


class AreaListView(APIView):
    """Get list of areas, optionally filtered by city"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        areas = Area.objects.filter(is_active=True)

        # Filter by city if city_id provided
        city_id = request.query_params.get("city_id")
        if city_id:
            try:
                areas = areas.filter(city_id=int(city_id))
            except ValueError:
                pass

        areas = areas.order_by("sort_order", "name")
        serializer = AreaSerializer(areas, many=True)
        return Response(serializer.data)


class PincodeListView(APIView):
    """Get list of pincodes, optionally filtered by area"""

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        pincodes = Pincode.objects.filter(is_active=True)

        # Filter by area if area_id provided
        area_id = request.query_params.get("area_id")
        if area_id:
            try:
                pincodes = pincodes.filter(area_id=int(area_id))
            except ValueError:
                pass

        # Filter by pincode search
        search = request.query_params.get("search")
        if search:
            pincodes = pincodes.filter(pincode__icontains=search)

        pincodes = pincodes.order_by("pincode")
        serializer = PincodeSerializer(pincodes, many=True)
        return Response(serializer.data)
