from django.shortcuts import render, redirect, get_object_or_404
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 LineInspectionForm, LineInspectionUpdateForm, LineInspectionAlcoholicForm, LineInspectionAlcoholicUpdateForm, LineInspectionNonAlcoholicForm, LineInspectionNonAlcoholicUpdateForm, LineInspectionDespatchPalletForm, LineInspectionFaultForm, LineInspectionFaultUpdateForm, LineInspectionSubmitWorkflowForm, LineInspectionCheckWorkflowForm, LineInspectionApprovalWorkflowForm, LineInspectionFilesModelForm
from .models import LineInspectionModel, LineInspectionFaultModel, LineInspectiontDefectModel, LineInspectionWorkFlowModel, LineInspectionFilesModel, LineInspectionDespatchPalletModel
from .models_analysis import LineInspectionAlcModel, LineInspectionNonAlcModel

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_shift_analysis_table, actions_validator, paginate, set_shift_inspection_table
from accounts.fxns import user_activity
from dispute.models import DisputeModel
from dispute.forms import DisputeCreateForm



""" LINE INSPECTION =================================================================================================== """
@login_required(login_url='/login')
def line_inspection(request):
    template_name = 'line_inspection.html'
    

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

            LineInspectionWorkFlowModel(line_id=obj).save()

            """ USER ACTIVITY """
            user_activity(request, model_name='LINE_INSPECTION', model_id=obj.id, activity='CREATE', description=f"Line {obj.l_id.line} Inspection form Created")

            messages.success(request, 'Line Inspection Form Created')
            return redirect(f'/line/inspection/detail/{obj.id}/')
        messages.error(request, 'Error in Connection!!!')
        return redirect('/line/inspection/')
    else:
        query = LineInspectionModel.objects.all().order_by('-date', '-id')
        context = {
            'data': paginate(request, query=query, page_number=60),
            'form': LineInspectionForm(),
        }
    return render(request, template_name, context)


""" LINE INSPECTION DETAILS =================================================================================================== """
@login_required(login_url='/login')
#@cache_page(60 * 30)
def line_inspection_detail(request, pk):
    template_name = 'line_inspection_detail.html'
    query = get_object_or_404(LineInspectionModel, pk=pk)

    if query.product_id.product_type == "ALCOHOLIC":
        analysis_form = LineInspectionAlcoholicForm()
        product_type = "ALCOHOLIC"
    elif query.product_id.product_type == "NON-ALCOHOLIC":
        analysis_form = LineInspectionNonAlcoholicForm()
        product_type = "NON-ALCOHOLIC"
    else:
        analysis_form = None

    

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

            """ USER ACTIVITY """
            user_activity(request, model_name='LINE_INSPECTION', model_id=query.id, activity='UPDATE', description=f"Line {query.l_id.line} Inspection form Updated")

            messages.success(request, 'Line Inspection Form Updated')
            return redirect(f'/line/inspection/detail/{pk}/')
        messages.error(request, 'Error in Connection!!!')
        return redirect(f'/line/inspection/detail/{pk}/')
    else:

        if product_type == "ALCOHOLIC":
            analysis_data = list(query.hourly.all().values())
        elif product_type == "NON-ALCOHOLIC":
            analysis_data = list(query.hourly1.all().values())

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

        defect_data = query.defect.all()
        
        shift_data = set_shift_inspection_table(shift=query.shift, analysis_data=analysis_data, fault_data=fault_data, product_type=product_type)#, 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,
            'pallet': query.line_pallet.all(),
            'workflow': workflow,
            'form': LineInspectionUpdateForm(instance=query),
            'fault_form': LineInspectionFaultForm(),
            'analysis_form': analysis_form,
            'product_type':product_type,
            'submit_form': LineInspectionSubmitWorkflowForm(instance=workflow),
            'check_form':  LineInspectionCheckWorkflowForm(instance=workflow),
            'approve_form': LineInspectionApprovalWorkflowForm(instance=workflow),
            'upload_form': LineInspectionFilesModelForm(),
            'add_pallet_form':LineInspectionDespatchPalletForm(),
            'dispute_form':DisputeCreateForm(),
            'files': list(LineInspectionFilesModel.objects.filter(line_id=query).values()),#.files if hasattr(query, 'files') else None,
            'actions': actions,
            'disputes': list(DisputeModel.objects.filter(model_name='LINE_INSPECTION', model_id=pk).values())
        }
    return render(request, template_name, context)



""" LINE INSPECTION DELETE =================================================================================================== """
@login_required(login_url='/login')
def line_inspection_delete(request, pk):
    query = get_object_or_404(LineInspectionModel, pk=pk)

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



""" CREATE LINE INSPECTION HOURLY =================================================================================================== """
@login_required(login_url='/login')
def line_inspection_hourly(request, pk):
    query = get_object_or_404(LineInspectionModel, pk=pk)

    if request.method == 'POST':
        if request.POST.get('product_type') == "ALCOHOLIC":
            check = query.hourly.filter(hour=request.POST.get('hour')).first()
            if check:
                return redirect(f'/line/inspection/hour/{check.id}/?product_type=ALCOHOLIC')
            analysis_form = LineInspectionAlcoholicForm(request.POST)
        elif request.POST.get('product_type') == "NON-ALCOHOLIC":
            check = query.hourly1.filter(hour=request.POST.get('hour')).first()
            if check:
                return redirect(f'/line/inspection/hour/{check.id}/?product_type=NON-ALCOHOLIC')
            analysis_form = LineInspectionNonAlcoholicForm(request.POST)
        else:
            analysis_form = None

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



""" CREATE LINE INSPECTION FAULT =================================================================================================== """
@login_required(login_url='/login')
def line_inspection_create_fault(request, pk):
    query = get_object_or_404(LineInspectionModel, pk=pk)

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

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

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



""" LINE INSPECTION 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 line_inspection_form(request, pk):
    query = get_object_or_404(LineInspectionModel, pk=pk)
    template_name = 'line_inspection_form.html'

    product_type = query.product_id.product_type
    if product_type == 'ALCOHOLIC':
        analysis_data = query.hourly.all().order_by('hour')
        analysis_data_value = list(analysis_data.values())
        sight1 = [a['sighter1'].strip().upper() for a in analysis_data_value]
        sight2 = [a['sighter2'].strip().upper() for a in analysis_data_value]
        sighters = ', '.join(list(dict.fromkeys(sight1 + sight2)))
        pkg_codes = {}
        pkg_codes['nylon_code'] = ', '.join(list(dict.fromkeys([a['nylon_code'].strip().upper() for a in analysis_data_value if a['nylon_code'] ])))
        pkg_codes['cap_code'] = ', '.join(list(dict.fromkeys([a['cap_code'].strip().upper() for a in analysis_data_value if a['cap_code'] ])))
        pkg_codes['label_code'] = ', '.join(list(dict.fromkeys([a['label_code'].strip().upper() for a in analysis_data_value if a['label_code']])))
        pkg_codes['bottle_code'] = ', '.join(list(dict.fromkeys([a['bottle_code'].strip().upper() for a in analysis_data_value if a['bottle_code']])))
        pkg_codes['case_code'] = ', '.join(list(dict.fromkeys([a['case_code'].strip().upper() for a in analysis_data_value if a['case_code'] ])))

    elif product_type == 'NON-ALCOHOLIC':
        analysis_data = query.hourly1.all().order_by('hour')
        analysis_data_value = list(analysis_data.values())
        sight1 = [a['sighter1'].strip().upper() for a in analysis_data_value]
        sight2 = [a['sighter2'].strip().upper() for a in analysis_data_value]
        sight3 = [a['sighter3'].strip().upper() for a in analysis_data_value]
        sight4 = [a['sighter4'].strip().upper() for a in analysis_data_value]
        sighters = ', '.join(list(dict.fromkeys(sight1 + sight2 + sight3 + sight4)))

        pkg_codes = {}
        pkg_codes['wire_hood_code'] = ', '.join(list(dict.fromkeys([a['wire_hood_code'].strip().upper() for a in analysis_data_value if a['wire_hood_code'] ])))
        pkg_codes['corking_cap_code'] = ', '.join(list(dict.fromkeys([a['corking_cap_code'].strip().upper() for a in analysis_data_value if a['corking_cap_code'] ])))
        pkg_codes['label_code'] = ', '.join(list(dict.fromkeys([a['label_code'].strip().upper() for a in analysis_data_value if a['label_code']])))
        pkg_codes['bottle_code'] = ', '.join(list(dict.fromkeys([a['bottle_code'].strip().upper() for a in analysis_data_value if a['bottle_code']])))
        pkg_codes['case_code'] = ', '.join(list(dict.fromkeys([a['case_code'].strip().upper() for a in analysis_data_value if a['case_code'] ])))

    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,
        'product_type' : product_type,
        'sighters':sighters,
        'pkg_codes':pkg_codes
    }
    return render(request, template_name, context)



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

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


""" FILE DELETE MODEL ========================================== """

@login_required(login_url='/login')
def file_delete(request, pk):
    query = get_object_or_404(LineInspectionFilesModel, 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'/line/inspection/detail/{query.line_id.id}/')



""" DEFECT DELETE MODEL ========================================== """

@login_required(login_url='/login')
def defect_delete(request, pk):
    query = get_object_or_404(LineInspectiontDefectModel, 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'/line/inspection/hour/{query.line_id.id}/{analysis_pk}/')





""" ADD DESPATCHED PALLET """
@login_required(login_url='/login')
def pallet_add(request, pk):
    query = get_object_or_404(LineInspectionModel, pk=pk)

    if request.method == "POST":
        form = LineInspectionDespatchPalletForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.line_id = query
            obj.created_by = request.user.username
            obj.save()
            messages.success(request, f"Pallet Added")
            return redirect(f'/line/inspection/detail/{pk}/')
        else:
            messages.error(request, f"Failed!!!")
            return redirect(f'/line/inspection/detail/{pk}/')
    else:
        messages.error(request, f"Method not Allowed!!!")
        return redirect(f'/line/inspection/detail/{pk}/')



""" DELETE DESPATCHED PALLET ========================================== """

@login_required(login_url='/login')
def pallet_delete(request, pk):
    query = get_object_or_404(LineInspectionDespatchPalletModel, pk=pk)

    if query.created_by == request.user.username:
        query.delete()
        messages.success(request, f"Pallet Deleted successfully")
    else:
        messages.error(request, 'Action not allowed!!!')
    return redirect(f'/line/inspection/detail/{query.line_id.id}/')