from django.contrib.auth.decorators import login_required
from rest_framework import status
from rest_framework.response import Response
from rest_framework.parsers import JSONParser
from django.http.response import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import ProductsModel, LinesModel, SachetDefectsModel
from .serializers import ProductSerializer, LineSerializer, SachetDefectSerializer
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view, renderer_classes, authentication_classes, permission_classes

from django.views import generic
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.urls import reverse, reverse_lazy
from .forms import ProductsModelForm, LinesModelForm


class ProductListView(generic.ListView):
    context_object_name = 'data'
    login_required = True
    queryset = ProductsModel.objects.all()
    template_name = 'product/product_list.html'
    """
    paginate_by = 10
    def get_context_data(self, **kwargs):
        context = super(ProductListView, self).get_context_data(**kwargs)
        context['some_data'] = 'This is just some data'
        return context
    """

class ProductDetailView(generic.DetailView):
    context_object_name = 'data'
    login_required = True
    queryset = ProductsModel.objects.all()
    template_name = 'product/product_detail.html'



class ProductCreateView(generic.CreateView):
    model = ProductsModel
    login_required = True
    #fields = '__all__'
    form_class = ProductsModelForm
    template_name = 'product/product_create.html'

    def form_valid(self, form):
        form.instance.created_by = self.request.user.username
        return super(ProductCreateView, self).form_valid(form)

    def get_success_url(self):
        return f"/utils/products/detail/{self.object.id}/"



class ProductUpdateView(generic.UpdateView):
    model = ProductsModel
    login_required = True
    fields = '__all__'
    template_name = 'product/product_create.html'

    def get_success_url(self):
        return f"/utils/products/detail/{self.object.id}/"



class ProductDeleteView(generic.DeleteView):
    model = ProductsModel
    login_required = True
    template_name = 'product/product_delete.html'
    success_url = reverse_lazy('products')



""" LINE VIEWS ===============================  """

class LineListView(generic.ListView):
    context_object_name = 'data'
    login_required = True
    queryset = LinesModel.objects.all()
    template_name = 'lines/line_list.html'
    """
    paginate_by = 10
    def get_context_data(self, **kwargs):
        context = super(ProductListView, self).get_context_data(**kwargs)
        context['some_data'] = 'This is just some data'
        return context
    """

class LineDetailView(generic.DetailView):
    context_object_name = 'data'
    login_required = True
    queryset = LinesModel.objects.all()
    template_name = 'lines/line_detail.html'



class LineCreateView(generic.CreateView):
    model = LinesModel
    login_required = True
    #fields = '__all__'
    form_class = LinesModelForm
    template_name = 'lines/line_create.html'

    def form_valid(self, form):
        form.instance.created_by = self.request.user.username
        return super(LineCreateView, self).form_valid(form)

    def get_success_url(self):
        return f"/utils/lines/detail/{self.object.id}/"



class LineUpdateView(generic.UpdateView):
    model = LinesModel
    login_required = True
    #fields = '__all__'
    form_class = LinesModelForm
    template_name = 'lines/line_create.html'

    def get_success_url(self):
        return f"/utils/lines/detail/{self.object.id}/"



class LineDeleteView(generic.DeleteView):
    model = LinesModel
    login_required = True
    template_name = 'lines/line_delete.html'
    success_url = '/utils/lines/'

    def get_object(self, queryset=None):
        """ Hook to ensure object is owned by request.user. """
        obj = super(LineDeleteView, self).get_object()
        if not obj.created_by == self.request.user.username:
            raise Http404
        return obj

""" LINE VIEWS ========================================================="""


""" SACHET MACHINES VIEWS ==============================================================  """
from .models import SachetModel
class SachetListView(generic.ListView):
    context_object_name = 'data'
    login_required = True
    queryset = SachetModel.objects.all()
    template_name = 'sachet/sachet_list.html'


class SachetDetailView(generic.DetailView):
    context_object_name = 'data'
    login_required = True
    queryset = SachetModel.objects.all()
    template_name = 'sachet/sachet_detail.html'



class SachetCreateView(generic.CreateView):
    model = SachetModel
    login_required = True
    fields = ['machine']
    template_name = 'sachet/sachet_create.html'

    def form_valid(self, form):
        form.instance.created_by = self.request.user.username
        return super(SachetCreateView, self).form_valid(form)

    def get_success_url(self):
        return f"/utils/sachet/detail/{self.object.id}/"



class SachetUpdateView(generic.UpdateView):
    model = SachetModel
    login_required = True
    fields = ['machine']
    template_name = 'sachet/sachet_create.html'

    def get_success_url(self):
        return f"/utils/sachet/detail/{self.object.id}/"



class SachetDeleteView(generic.DeleteView):
    model = SachetModel
    login_required = True
    template_name = 'sachet/sachet_delete.html'
    success_url = 'utils/sachet/'

""" SACHET MACHINE VIEWS ======================================================================"""



""" PRODUCT LIST MODEL """
@api_view(('GET','POST', 'PUT', 'DELETE'))
@permission_classes([IsAuthenticated])
def product_list_api(request, pk=0):
    if request.method == 'GET':
        if pk == 0:
            if request.GET.get('section'):
                if request.GET.get('section') == 'line':
                    query = ProductsModel.objects.filter(product_size__gte=80)
                elif request.GET.get('section') == 'sachet':
                    query = ProductsModel.objects.filter(product_size__lte=60)
                else:
                    query = ProductsModel.objects.all()
            else:
                query = ProductsModel.objects.all()
        else:
            query = ProductsModel.objects.filter(pk=pk)
            if query.count() == 0:
                return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        serializer_class = ProductSerializer(query, many=True)
        return Response({"data":serializer_class.data}, status=status.HTTP_200_OK)

    elif request.method == 'POST':
        res_data = JSONParser().parse(request)
        serializer_obj = ProductSerializer(data=res_data)
        if serializer_obj.is_valid(raise_exception=True):
            saved_obj = serializer_obj.save()
            #serializer_obj.data
            return Response({"data":serializer_obj.data}, status=status.HTTP_201_CREATED)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        query = ProductsModel.objects.filter(pk=data['id']).first()
        
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        
        if request.user.profile.role != 'SUPERADMIN':
            if request.user.username != query.created_by:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        serializer_obj = ProductSerializer(query, data=data)
        if serializer_obj.is_valid(raise_exception=True):
            saved_obj = serializer_obj.save()
            return Response({"data":serializer_obj.data}, status=status.HTTP_200_OK)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        if request.user.profile.role != 'SUPERADMIN':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = ProductsModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)



""" LINES LIST MODEL """
@api_view(('GET','POST', 'PUT', 'DELETE'))
@permission_classes([IsAuthenticated])
def line_list_api(request, pk=0):
    if request.method == 'GET':
        if pk == 0:
            query = LinesModel.objects.all()
        else:
            query = LinesModel.objects.filter(pk=pk)
            if query.count() == 0:
                return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        serializer_class = LineSerializer(query, many=True)
        return Response({"data":serializer_class.data}, status=status.HTTP_200_OK)

    elif request.method == 'POST':
        res_data = JSONParser().parse(request)
        serializer_obj = LineSerializer(data=res_data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            return Response({"data":serializer_obj.data}, status=status.HTTP_201_CREATED)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        query = LinesModel.objects.filter(pk=data['id']).first()
        
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        
        if request.user.profile.role != 'SUPERADMIN':
            if request.user.username != query.created_by:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        serializer_obj = LineSerializer(query, data=data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            return Response({"data":serializer_obj.data}, status=status.HTTP_200_OK)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        if request.user.profile.role != 'SUPERADMIN':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = LinesModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)


        

""" SACHET DEFECTS MODEL """
@api_view(('GET','POST', 'PUT', 'DELETE'))
@permission_classes([IsAuthenticated])
def sachet_defects_api(request, pk=0):
    if request.method == 'GET':
        if pk == 0:
            query = SachetDefectsModel.objects.all().order_by('defect_code')
        else:
            query = SachetDefectsModel.objects.filter(pk=pk)
            if query.count() == 0:
                return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        serializer_class = SachetDefectSerializer(query, many=True)
        return Response({"data":serializer_class.data}, status=status.HTTP_200_OK)

    elif request.method == 'POST':
        res_data = JSONParser().parse(request)
        serializer_obj = SachetDefectSerializer(data=res_data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            return Response({"data":serializer_obj.data}, status=status.HTTP_201_CREATED)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        query = SachetDefectsModel.objects.filter(pk=data['id']).first()
        
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        
        if request.user.profile.role != 'SUPERADMIN':
            if request.user.username != query.created_by:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        serializer_obj = SachetDefectSerializer(query, data=data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            return Response({"data":serializer_obj.data}, status=status.HTTP_200_OK)
        return Response({"error":serializer_obj.errors}, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        if request.user.profile.role != 'SUPERADMIN':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = SachetDefectsModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)


from .fxns import set_case_code
""" SET CASE CODE API """
def set_case_code_api(request):
    
    line = request.GET.get('line')
    date = request.GET.get('date')
    hour = request.GET.get('hour')

    case_code = set_case_code(line, date, hour)

    return JsonResponse(case_code, safe=False)



