from rest_framework import generics
from rest_framework.views import APIView
from django.http import HttpResponse
import io

from .models import Country, State, District, Mandal, Pincode
from .serializers import (
    CountrySerializer, StateSerializer, DistrictSerializer, MandalSerializer, PincodeSerializer,
)
from apps.core.utils import standard_response


class CountryListView(generics.ListAPIView):
    queryset = Country.objects.filter(is_active=True).order_by('name')
    serializer_class = CountrySerializer


class StateListView(generics.ListAPIView):
    queryset = State.objects.filter(is_active=True).order_by('name')
    serializer_class = StateSerializer


class DistrictListView(generics.ListAPIView):
    serializer_class = DistrictSerializer

    def get_queryset(self):
        state_id = self.request.query_params.get('state_id')
        qs = District.objects.filter(is_active=True)
        if state_id:
            qs = qs.filter(state_id=state_id)
        return qs.order_by('name')


class PincodeListView(generics.ListAPIView):
    serializer_class = PincodeSerializer

    def get_queryset(self):
        country_id = self.request.query_params.get('country_id')
        state_id = self.request.query_params.get('state_id')
        district_id = self.request.query_params.get('district_id')
        qs = Pincode.objects.filter(is_active=True)
        if country_id:
            qs = qs.filter(country_id=country_id)
        if state_id:
            qs = qs.filter(state_id=state_id)
        if district_id:
            qs = qs.filter(district_id=district_id)
        return qs.order_by('code', 'location')


class MandalListView(generics.ListAPIView):
    serializer_class = MandalSerializer

    def get_queryset(self):
        district_id = self.request.query_params.get('district_id')
        qs = Mandal.objects.filter(is_active=True)
        if district_id:
            qs = qs.filter(district_id=district_id)
        return qs.order_by('name')


class UploadExcelView(APIView):
    def post(self, request):
        file = request.FILES.get('file')
        if not file:
            return standard_response(False, message='file required', errors=['file required'])
        try:
            import pandas as pd
        except Exception:
            return standard_response(False, message='pandas required for excel parsing')

        try:
            sheets = pd.read_excel(file, sheet_name=None)
        except Exception as e:
            return standard_response(False, message='failed to read excel', errors=[str(e)])

        # Countries
        countries_df = sheets.get('Country')
        if countries_df is not None:
            for _, row in countries_df.fillna('').iterrows():
                Country.objects.update_or_create(code=str(row.get('code')).strip(), defaults={'name': row.get('name')})

        # States (require country_code)
        states_df = sheets.get('State')
        if states_df is not None:
            for _, row in states_df.fillna('').iterrows():
                country_code = str(row.get('country_code')).strip()
                try:
                    country = Country.objects.get(code=country_code)
                    State.objects.update_or_create(name=row.get('name'), country=country)
                except Country.DoesNotExist:
                    continue

        # Districts (require state_name)
        districts_df = sheets.get('District')
        if districts_df is not None:
            for _, row in districts_df.fillna('').iterrows():
                state_name = str(row.get('state_name')).strip()
                try:
                    state = State.objects.get(name=state_name)
                    District.objects.update_or_create(name=row.get('name'), state=state)
                except State.DoesNotExist:
                    continue

        # Pincodes (location required, geo links optional)
        pincodes_df = sheets.get('Pincode')
        if pincodes_df is not None:
            for _, row in pincodes_df.fillna('').iterrows():
                country = None
                state = None
                district = None
                country_code = str(row.get('country_code')).strip()
                state_name = str(row.get('state_name')).strip()
                district_name = str(row.get('district_name')).strip()
                if country_code:
                    country = Country.objects.filter(code=country_code).first()
                if state_name:
                    state = State.objects.filter(name=state_name).first()
                if district_name:
                    district = District.objects.filter(name=district_name).first()

                Pincode.objects.update_or_create(
                    code=str(row.get('code')).strip(),
                    location=str(row.get('location')).strip(),
                    defaults={
                        'country': country,
                        'state': state,
                        'district': district,
                    },
                )

        # Mandals (require district_name)
        mandals_df = sheets.get('Mandal')
        if mandals_df is not None:
            for _, row in mandals_df.fillna('').iterrows():
                district_name = str(row.get('district_name')).strip()
                if not district_name:
                    continue
                district = District.objects.filter(name=district_name).first()
                if not district:
                    continue
                Mandal.objects.update_or_create(name=str(row.get('name')).strip(), district=district)

        return standard_response(True, message='Excel processed')


class TemplateDownloadView(APIView):
    def get(self, request):
        try:
            import pandas as pd
            from pandas import ExcelWriter
        except Exception:
            return standard_response(False, message='pandas required for template generation')

        sheets = {
            'Country': pd.DataFrame(columns=['name', 'code']),
            'State': pd.DataFrame(columns=['name', 'country_code']),
            'District': pd.DataFrame(columns=['name', 'state_name']),
            'Mandal': pd.DataFrame(columns=['name', 'district_name']),
            'Pincode': pd.DataFrame(columns=['code', 'location', 'country_code', 'state_name', 'district_name']),
        }

        buffer = io.BytesIO()
        with ExcelWriter(buffer, engine='openpyxl') as writer:
            for name, df in sheets.items():
                df.to_excel(writer, sheet_name=name, index=False)
        buffer.seek(0)
        response = HttpResponse(buffer.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=geo_template.xlsx'
        return response
