from rest_framework.generics import (ListAPIView, CreateAPIView, UpdateAPIView, RetrieveAPIView, DestroyAPIView)
from rest_framework.response import Response
from rest_framework.filters import SearchFilter, OrderingFilter

from django.db import transaction

from django.shortcuts import get_object_or_404

from datetime import datetime

from apps.vendor.serializers.vendor_serializers import VendorListAPISerializer, VendorStoreAPISerializer, VendorDeleteAPISerializer
from apps.vendor.models import Vendor
from apps.vendor.services.vendor_services import save_vendor



class VendorListAPIView(ListAPIView):
    serializer_class = VendorListAPISerializer
    filter_backends = [SearchFilter, OrderingFilter]
    ordering_fields = ['id', 'name', 'type', 'phone_no', 'created_by', 'email', 'note']
    search_fields = ['id', 'name', 'type__name', 'phone_no', 'created_by__first_name', 'created_by__last_name', 'email', 'note']

    def get_queryset(self):
        vendors_without_project_id = self.request.query_params.get('vendors_without_project_id')
        project_id = self.request.query_params.get('project_id')
        with_trashed = self.request.query_params.get('with_trashed')
        queryset = Vendor.objects.all()

        if with_trashed == 'true':
            queryset = Vendor.objects.with_trashed()

        if vendors_without_project_id:
            queryset = queryset.exclude(project_vendors__id=vendors_without_project_id)
        elif project_id:
            queryset = queryset.filter(project_vendors__id=project_id)

        return queryset


class VendorCreateAPIView(CreateAPIView):
    serializer_class = VendorStoreAPISerializer

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        validated_data = serializer.validated_data
        validated_data['created_by']= self.request.user

        vendor = save_vendor(validated_data)

        serializer = self.serializer_class(instance=vendor)

        return Response(serializer.data)


class VendorEditAPIView(UpdateAPIView):
    http_method_names = ['patch']
    serializer_class = VendorStoreAPISerializer

    def patch(self, request, pk, *args, **kwargs):
        vendor = get_object_or_404(Vendor, pk=pk)

        serializer = self.serializer_class(instance=vendor, data=request.data)
        serializer.is_valid(raise_exception=True)

        vendor = save_vendor(serializer.validated_data, id=vendor.id)

        serializer = self.serializer_class(instance=vendor)

        return Response(serializer.data)


class VendorDeleteAPIView(DestroyAPIView):
    serializer_class = VendorDeleteAPISerializer

    def delete(self, request, pk, *args, **kwargs):
        vendor = get_object_or_404(Vendor, pk=pk)

        Vendor.objects.filter(id=pk).update(deleted_by=self.request.user, deleted_at=datetime.now())

        serializer = self.serializer_class(vendor)

        return Response(serializer.data)


class VendorDetailAPIView(RetrieveAPIView):
    serializer_class = VendorListAPISerializer
    queryset = Vendor.objects.with_trashed().select_related('type')