from django.shortcuts import render, redirect, get_object_or_404

from .serializers import SachetAnalysisSerializer, SachetFaultSerializer, SachetDefectSerializer, LineAnalysisWorkFlowSerializer
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 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.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.http import Http404
from django.urls import reverse, reverse_lazy
from .forms import SachetAnalysisForm, SachetAlcoholicAnalysisForm, SachetFaultForm, SachetAnalysisSubmitWorkflowForm, SachetAnalysisCheckWorkflowForm, SachetAnalysisApprovalWorkflowForm, SachetAnalysisFilesModelForm
from .models import SachetAnalysisModel, SachetFaultModel, SachetDefectModel, SachetAnalysisWorkFlowModel, SachetAnalysisWorkFlowModel, SachetAnalysisFilesModel


from django.http.response import JsonResponse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.views.decorators.cache import cache_page
from utilz.fxns import set_case_code, set_sachet_shift_analysis_table, actions_validator, paginate
from accounts.fxns import user_activity
from dispute.models import DisputeModel
from dispute.forms import DisputeCreateForm


""" SACHET ANALYSIS =================================================================================================== """
@login_required(login_url='/login')
def sachet_analysis(request):
    template_name = 'sachet_analysis.html'
    

    if request.method == 'POST':
        checker = SachetAnalysisModel.objects.filter(date=request.POST.get('date')).filter(shift=request.POST.get('shift')).filter(mc_id=request.POST.get('mc_id')).first()
        
        if checker:
            messages.error(request, 'Form already exists')
            return redirect(f'/sachet/analysis/detail/{checker.id}/')
        form = SachetAnalysisForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.created_by = request.user.username
            obj.save()

            SachetAnalysisWorkFlowModel(machine_id=obj).save()

            """ USER ACTIVITY """
            user_activity(request, model_name='SACHET_ANALYSIS', model_id=obj.id, activity='CREATE', description=f"Sachet {obj.mc_id.machine} Analysis form Created")

            messages.success(request, 'Sachet Analysis Form Created')
            return redirect(f'/sachet/analysis/detail/{obj.id}/')
        messages.error(request, 'Error in Connection!!!')
        return redirect('/sachet/analysis/')
    else:
        query = SachetAnalysisModel.objects.all().order_by('-date')
        context = {
            'data': paginate(request, query=query, page_number=60),
            'form':SachetAnalysisForm(),
            #'prods':prods,
            #'size':size,
            #'lines':lines
        }
    return render(request, template_name, context)


""" SACHET ANALYSIS DETAILS =================================================================================================== """
@login_required(login_url='/login')
#@cache_page(60 * 30)
def sachet_analysis_detail(request, pk):
    template_name = 'sachet_analysis_detail.html'
    query = get_object_or_404(SachetAnalysisModel, pk=pk)

    

    if request.method == 'POST':
        form = SachetAnalysisForm(request.POST, instance=query)
        if form.is_valid():
            form.save()

            """ USER ACTIVITY """
            user_activity(request, model_name='SACHET_ANALYSIS', model_id=query.id, activity='UPDATE', description=f"Sachet {query.mc_id.machine} Analysis form Updated")

            messages.success(request, 'Sachet Analysis Form Updated')
            return redirect(f'/sachet/analysis/detail/{pk}/')
        messages.error(request, 'Error in Connection!!!')
        return redirect(f'/sachet/analysis/detail/{pk}/')
    else:
        
        analysis_data = list(query.hourly.all().values())

        fault_data = list(query.fault.all().values())

        defect_data = query.defect.all()
        
        shift_data = set_sachet_shift_analysis_table(shift=query.shift, analysis_data=analysis_data, fault_data=fault_data, defect_data=defect_data)#, product_type=product_type)

        workflow = query.workflow

        if len(shift_data[0]) > 0:
            actions =  actions_validator(request, status=query.status, workflow={'analysed_by':workflow.analysed_by, 'checked_by':workflow.checked_by}, has_dependency=True)
        else:
            actions =  actions_validator(request, status=query.status, workflow={'analysed_by':workflow.analysed_by, 'checked_by':workflow.checked_by}, has_dependency=False)

        #print('query_files====================================',dir(query.files))
        context = {
            'data':query,
            'analysis_data':shift_data[0],
            'available_hours':',,'.join(shift_data[1]),
            'defect': defect_data,
            'workflow': workflow,
            'form': SachetAnalysisForm(instance=query),
            'fault_form': SachetFaultForm(),
            'analysis_form': SachetAlcoholicAnalysisForm(),
            'submit_form':SachetAnalysisSubmitWorkflowForm(instance=workflow),
            'check_form': SachetAnalysisCheckWorkflowForm(instance=workflow),
            'approve_form': SachetAnalysisApprovalWorkflowForm(instance=workflow),
            'upload_form':SachetAnalysisFilesModelForm(),
            'dispute_form':DisputeCreateForm(),
            'files': list(SachetAnalysisFilesModel.objects.filter(machine_id=query).values()),#.files if hasattr(query, 'files') else None,
            'actions': actions,
            'disputes': list(DisputeModel.objects.filter(model_name='SACHET_ANALYSIS', model_id=pk).values())
        }
    return render(request, template_name, context)



""" SACHET ANALYSIS DELETE =================================================================================================== """
@login_required(login_url='/login')
def sachet_analysis_delete(request, pk):
    query = get_object_or_404(SachetAnalysisModel, pk=pk)

    if request.method == 'POST':
        yes_no = request.POST.get('yes_no')
        if yes_no == 'YES':
            query.delete()
            messages.success(request, 'Sachet Analysis Form Deleted')
            return redirect('/sachet/analysis/')
        messages.error(request, 'Error in Connection!!!')
        return redirect(f'/sachet/analysis/detail/{pk}/')



""" CREATE SACHET ANALYSIS HOURLY =================================================================================================== """
@login_required(login_url='/login')
def sachet_analysis_hourly(request, pk):
    query = get_object_or_404(SachetAnalysisModel, pk=pk)

    if request.method == 'POST':
        analysis_form = SachetAlcoholicAnalysisForm(request.POST)
        check = query.hourly.filter(hour=request.POST.get('hour')).first()
        if check:
            messages.error(request, 'Hour already analysed')
            return redirect(f'/sachet/analysis/hour/{check.id}/')

        if analysis_form.is_valid():
            obj =analysis_form.save(commit=False)
            obj.machine_id = query
            obj.created_by = request.user.username
            obj.save()
            messages.success(request, f'Sachet Analysis for {request.POST.get("hour")} Hour Created')
            return redirect(f'/sachet/analysis/hour/{pk}/{obj.id}/')
        messages.error(request, 'Error in Connection!!!')
        return redirect(f'/sachet/analysis/detail/{pk}/')



""" CREATE SACHET ANALYSIS FAULT =================================================================================================== """
@login_required(login_url='/login')
def sachet_analysis_create_fault(request, pk):
    query = get_object_or_404(SachetAnalysisModel, pk=pk)

    if request.method == 'POST':
        form = SachetFaultForm(request.POST)

        if form.is_valid():
            obj =form.save(commit=False)
            obj.machine_id = query
            obj.created_by = request.user.username
            obj.save()
            messages.success(request, f'Sachet Fault for {request.POST.get("hour")} Hour Created')
            return redirect(f'/sachet/analysis/fault/{obj.id}')
        messages.error(request, 'Error in Connection!!!')
        return redirect(f'/sachet/analysis/detail/{pk}/')

    messages.error(request, 'Method not allowed!!!')
    return redirect(f'/sachet/analysis/detail/{pk}/')



""" SACHET ANALYSIS FORM PRINT OUT =============================================== """
from utilz.fxns import form_set_shift_analysis_table
from utilz.models import SHIFTS
DEFECT_CAUSE = {"RAW MATERIAL":"M", "ENGINEERING":"E", "MAINTENANCE SETTING":"W", "HUMAN":"O"}
DEFECT_CATEGORY = {"MINOR" : "x", "MAJOR" : "Y", "CRITICAL" : "Z"}
@login_required(login_url='/login')
def sachet_analysis_form(request, pk):
    query = get_object_or_404(SachetAnalysisModel, pk=pk)
    template_name = 'sachet_analysis_form.html'

    analysis_data = query.hourly.all().order_by('hour')

    fault_data = query.fault.all().order_by('hour')
    
    form_data = form_set_shift_analysis_table(shift=query.shift, analysis_data=analysis_data, fault_data=fault_data)

    workflow = query.workflow

    defect_data = query.defect.all().order_by('hour')

    for k,v in form_data.items():
        form_data[k]['defect'] = ', '.join([f'{DEFECT_CATEGORY[d.defect_id.defect_category]}{d.quantity}:{d.defect_id.defect_code}:{DEFECT_CAUSE[d.defect_cause]}' for d in defect_data.filter(hour=k)])
    
    context = {
        'data':query,
        'form_data':form_data,
        'workflow': workflow,
        'hours':SHIFTS[query.shift],
        'fault_data':fault_data,
        'defect_data':defect_data
    }
    return render(request, template_name, context)



""" FILE UPLOAD MODEL ========================================== """
@login_required(login_url='/login')
def file_upload(request, pk):
    query = get_object_or_404(SachetAnalysisModel, pk=pk)

    if request.method == "POST":
        form = SachetAnalysisFilesModelForm(request.POST, request.FILES)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.machine_id = query
            obj.created_by = request.user.username
            obj.save()
            messages.success(request, f"File Uploaded")
            return redirect(f'/sachet/analysis/detail/{pk}/')
        else:
            messages.error(request, f"File Upload Failed!!!")
            return redirect(f'/sachet/analysis/detail/{pk}/')
    else:
        messages.error(request, f"Method not Allowed!!!")
        return redirect(f'/sachet/analysis/detail/{pk}/')


""" FILE DELETE MODEL ========================================== """
from .models import SachetAnalysisFilesModel
@login_required(login_url='/login')
def file_delete(request, pk):
    query = get_object_or_404(SachetAnalysisFilesModel, pk=pk)
    if query.created_by == request.user.username:
        query.delete()
        messages.success(request, f"File Deleted successfully")
    else:
        messages.error(request, 'Action not allowed!!!')
    return redirect(f'/sachet/analysis/detail/{query.machine_id.id}/')



""" DEFECT DELETE MODEL ========================================== """
from .models import SachetAnalysisFilesModel
@login_required(login_url='/login')
def defect_delete(request, pk):
    query = get_object_or_404(SachetDefectModel, pk=pk)
    analysis_pk = request.GET.get('analysis')
    if query.created_by == request.user.username:
        query.delete()
        messages.success(request, f"Defect Deleted successfully")
    else:
        messages.error(request, 'Action not allowed!!!')
    return redirect(f'/sachet/analysis/hour/{query.machine_id.id}/{analysis_pk}')





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

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

    elif request.method == 'POST':
        res_data = JSONParser().parse(request)
        query = SachetAnalysisModel.objects.filter(date=res_data['date']).filter(line=res_data['line']).filter(shift=res_data['shift']).filter(product=res_data['product']).filter(product_size=res_data['product_size'])
        if query.first():
            serializer_obj = SachetAnalysisSerializer(query, many=True)
            return Response({"error":"Already Exist", "data":serializer_obj.data}, status=status.HTTP_409_CONFLICT)
        serializer_obj = SachetAnalysisSerializer(data=res_data)

        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            SachetAnalysisWorkFlowModel(line_id=SachetAnalysisModel.objects.get(id=serializer_obj.data['id'])).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 = SachetAnalysisModel.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 = SachetAnalysisSerializer(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 = SachetAnalysisModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        if query.status == 'APPROVED':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        if query.status != 'CREATED':
            if query.hourly.count() > 0:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)





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

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

    elif request.method == 'POST':
        return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        """
        res_data = JSONParser().parse(request)
        serializer_obj = LineWorkFlowSerializer(data=res_data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            workflow = LineWorkFlowModel(line_id=serializer_obj['id']).save()
            return Response({"data":serializer_obj.data, 'workflow':workflow}, 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 = SachetAnalysisWorkFlowModel.objects.select_related('line_id').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 = LineAnalysisWorkFlowSerializer(query, data=data)
        if serializer_obj.is_valid(raise_exception=True):
            serializer_obj.save()
            query.line_id.status = data['status']
            query.line_id.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':
        return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        """
        if request.user.profile.role != 'SUPERADMIN':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = LineAnalysisModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        if query.status == 'APPROVED':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        if query.status != 'CREATED':
            if query.hourly.count() > 0:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)
        """





""" SACHET FAULT MODEL """
@api_view(('GET','POST', 'PUT', 'DELETE'))
@permission_classes([IsAuthenticated])
def sachet_fault_api(request, pk=0):
    if request.method == 'GET':
        if pk == 0:
            if request.GET.get('line_id'):
                query = SachetFaultModel.objects.filter(line_id__id=request.GET.get('line_id'))
            else:
                query = SachetFaultModel.objects.all()
        else:
            query = SachetFaultModel.objects.filter(pk=pk)
            if query.count() == 0:
                return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        serializer_class = SachetFaultSerializer(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 = SachetFaultSerializer(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 = SachetFaultModel.objects.select_related('line_id').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 = SachetFaultSerializer(query, data=data)
        if serializer_obj.is_valid(raise_exception=True):
            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':
            if request.user.username != query.created_by:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = SachetFaultModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        if query.status == 'APPROVED':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        if query.status != 'CREATED':
            if query.hourly.count() > 0:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)





""" SACHET DEFECTS MODEL """
@api_view(('GET','POST', 'PUT', 'DELETE'))
@permission_classes([IsAuthenticated])
def sachet_defect_api(request, pk=0):
    if request.method == 'GET':
        if pk == 0:
            if request.GET.get('line_id'):
                query = SachetDefectModel.objects.filter(line_id__id=request.GET.get('line_id'))
            else:
                query = SachetDefectModel.objects.all()
        else:
            query = SachetDefectModel.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 = SachetDefectModel.objects.select_related('line_id').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):
            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':
            if request.user.username != query.created_by:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        query = SachetDefectModel.objects.filter(pk=pk).first()
        if not query:
            return Response({"error":"Not Found"}, status=status.HTTP_404_NOT_FOUND)

        if query.status == 'APPROVED':
            return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)

        if query.status != 'CREATED':
            if query.hourly.count() > 0:
                return Response({"error":"Not Allowed"}, status=status.HTTP_401_UNAUTHORIZED)
        
        query.delete()
        return JsonResponse("Deleted Successfully", safe=False)

