from django.http import HttpResponseBadRequest, HttpResponse, FileResponse
from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.response import Response
from wsgiref.util import FileWrapper

from right_tree.api.models import Habitat, HabitatImage, Plant, EcologicalDistrictLayer, SoilOrder, Zone
from right_tree.api.serializers import HabitatImageSerializer, HabitatSerializer, PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer, ZoneSerializer

from .filters import *
from .wms_utils import get_address_from_coordinates
from .resource_generation_utils import create_plant_csv_file, get_plant_resource_filepath, create_planting_guide_pdf, PLANTING_GUIDE_PDF_FILENAME


class PlantViewSet(viewsets.ModelViewSet):
    """ Filtered viewset for plants.
    """
    queryset = Plant.objects.all()
    serializer_class = PlantSerializer

    def get_queryset(self):
        """ Filtering plant query set by query parameters in the URL.
            (May want to eventually use django filters to break up the logic...)
        """
        return get_filtered_plants(self.request)


class SoilOrderViewSet(viewsets.ModelViewSet):
    """ Filtered viewset for soil details.
    """
    serializer_class = SoilOrderSerializer

    def get_queryset(self):
        """ Filtering soil order query set by coordinate parameters in the URL.
        """
        coordinates = self.request.query_params.get('coordinates')
        if coordinates is not None:
            return soil_order_coordinate_filter(coordinates)

        return SoilOrder.objects.all()


class EcologicalDistrictViewSet(viewsets.ModelViewSet):
    """ Filtered viewset for ecological district/region details.
    """
    serializer_class = EcologicalDistrictLayerSerializer

    def get_queryset(self):
        """ Filtering ecological district/region query set by coordinate parameters in the URL.
        """
        coordinates = self.request.query_params.get('coordinates')
        if coordinates is not None:
            return ecological_district_coordinate_filter(coordinates)

        return EcologicalDistrictLayer.objects.all()


class LINZPropertyViewSet(viewsets.ViewSet):
    """ Filtered viewset for ecological district/region details.
    """

    def list(self, request):
        coordinates = self.request.query_params.get('coordinates')
        if coordinates is not None:
            address_data = get_address_from_coordinates(coordinates)
            serializer = AddressSerializer(address_data)
            return Response(serializer.data)
        else:
            return HttpResponseBadRequest("No coordinate given.")

class AuckCHCHRegionInformation(viewsets.ViewSet):
    """ Filtered viewset defining if coordinate falls inside auckland and chch regions.
    """

    def list(self, request):
        coordinates = self.request.query_params.get('coordinates')
        if coordinates is not None:
            in_chch = is_in_christchurch(coordinates)
            in_auckland = is_in_auckland(coordinates)
            region_details = {"in_chch": in_chch, "in_auckland": in_auckland}
            return Response(region_details)
        else:
            return HttpResponseBadRequest("No coordinate given.")

class HabitatViewSet(viewsets.ModelViewSet):
    """ Viewset for all habitats.
    """
    serializer_class = HabitatSerializer
    queryset = Habitat.objects.all()


class ZoneViewSet(viewsets.ModelViewSet):
    """ Viewset for all habitats.
    """
    serializer_class = ZoneSerializer
    queryset = Zone.objects.all()


class HabitatImageViewSet(viewsets.ViewSet):
    """ Viewset for a habitat image.
    """

    def list(self, request):
        queryset = HabitatImage.objects.all()
        serializer = HabitatImageSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = HabitatImage.objects.all()
        habitat_image = get_object_or_404(queryset, pk=pk)
        serializer = HabitatImageSerializer(habitat_image)
        return Response(serializer.data)


class CSVDownloadView(viewsets.ViewSet):
    """ Viewset for a downloading a CSV plant list and filters.
    """

    def list(self, request, *args, **kwargs):
        filtered_plants = get_filtered_plants(request)
        create_plant_csv_file(request, filtered_plants)

        csv_file = open(get_plant_resource_filepath(), 'rb')
        response = HttpResponse(csv_file, content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="plants.csv"'
        return response


class PDFDownloadView(viewsets.ViewSet):
    """ Viewset for a downloading a PDF planting guide with appended filter and plant list info.
    """

    def list(self, request, *args, **kwargs):
        filtered_plants = get_filtered_plants(request)

        create_planting_guide_pdf(request, filtered_plants)
        pdf_file = open(get_plant_resource_filepath(PLANTING_GUIDE_PDF_FILENAME), 'rb')

        response = HttpResponse(FileWrapper(pdf_file), content_type='application/pdf')
        return response
