from django.shortcuts import render,redirect
from django.contrib.auth import authenticate,login,logout
from django.contrib import messages
from django.contrib.auth.forms import  UserCreationForm
from .decorators import *
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseRedirect
from .forms import *
from .models import *

import logging

logger = logging.getLogger(__name__)

@login_required
def home(request):
    patients_total = Patients.objects.all().count()
    exipred = Stock.objects.annotate(
        expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
    ).filter(expired=True).count()
    out_of_stock = Stock.objects.filter(quantity__lte=0).count()
    total_stock = Stock.objects.all().count()
    context = {
        "patients_total": patients_total,
        "expired_total": exipred,
        "out_of_stock": out_of_stock,
        "total_drugs": total_stock,  
    }
    return render( request, 'pharmacist_templates/pharmacist_home.html', context)


@login_required
def user_profile(request):
    pharmacists = Pharmacist.objects.all()
    form = CustomerForm()
    if request.method == "POST":
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        password = request.POST.get('password')
        address = request.POST.get('address')
        customuser = CustomUser.objects.get(id=request.user.id)
        customuser.first_name = first_name
        customuser.last_name = last_name
        customuser.save()
        pharmacists = Pharmacist.objects.get(admin=customuser.id)
        form = CustomerForm(request.POST,request.FILES,instance=pharmacists)
        pharmacists.address = address
        if form.is_valid():
            form.save()
        pharmacists.save()       
        messages.success(request, "Profile updated successfully")
        return redirect('pharmacist_profile')
    context={
        "staff": pharmacists,
        "form": form
    }
    return render( request, 'pharmacist_templates/staff_profile.html', context)


@login_required
def list_prescriptions(request):
    prescriptions = Dispense.objects.all()
    context = {
        "prescrips": prescriptions,
    }
    return render(request, 'pharmacist_templates/patient_prescrip.html', context)


@login_required
def dispense_drug(request,pk):
    queryset = Patients.objects.get(id=pk)
    prescrips = queryset.prescription_set.all()
    form = DispenseForm(request.POST or None,initial={'patient_id':queryset} )
    drugs = Stock.objects.all()
    ex = Stock.objects.annotate(
        expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
    ).filter(expired=True)
    eo = Stock.objects.annotate(
        expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
    ).filter(expired=False)

    try:  
        if request.method == 'POST':
            if form.is_valid(): 
                username = form.cleaned_data['taken']
                qu = form.cleaned_data['dispense_quantity']
                ka = form.cleaned_data['drug_id']
                stock = eo = Stock.objects.annotate(
                    expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
                ).filter(expired=False).get(id=username)
                form = DispenseForm(request.POST or None, instance=stock)
                instance=form.save()
                instance.quantity -= qu
                instance.save()
                form = DispenseForm(request.POST or None ,initial={'patient_id':queryset})
                form.save()
                messages.success(request, "Drug Has been Successfully Dispensed")
                return redirect('all_pharmacist_patients')
            else:
                messages.error(request, "Validty Error")
                return redirect('all_pharmacist_patients')

        context = {
            "patients":queryset,
            "form":form,
            "drugs":drugs,
            "prescrips":prescrips,
            "expired":ex,
            "expa":eo,
            }
        if request.method == 'POST':
            context = {
                "drugs": drugs,
                form: form,
                "prescrips": prescrips,
                "patients": queryset,
                "expired": ex,
                "expa": eo,
            }
    except:
        messages.error(request, "Dispensing Not Allowed! The Drug is Expired, please contanct the admin for re-stock ")
        return redirect('all_pharmacist_patients')
    context = {
        "patients": queryset,
        "form": form,
         "drugs": drugs,
         "prescrips": prescrips,
         "expired": ex,
         "expa": eo,
         }
    return render( request, 'pharmacist_templates/manage_dispense.html', context)


@login_required
def list_feedbacks(request):
    feedbacks = PatientFeedback.objects.all()
    context = {
        "feedbacks": feedbacks
    }
    return render(request, 'pharmacist_templates/patient_feedback.html', context)


@csrf_exempt
# @login_required
def send_feedbacks(request):
    feedback_id = request.POST.get('id')
    feedback_reply = request.POST.get('reply')
    try:
        feedback =  PatientFeedback.objects.get(id=feedback_id)
        feedback.feedback_reply = feedback_reply
        feedback.save()
        return HttpResponse("True")
    except:
        return HttpResponse("False")


@login_required
def delete_feedback(request,pk):
    try:
        feedback = PatientFeedback.objects.get(id=pk)
        if request.method == 'POST':
            feedback.delete()
            messages.success( request, "Feedback deleted successfully")
            return redirect('patient_feedback_message')
    except:
        messages.error(request, "An error occurede while deleting Feedback. Please Check again")
        return redirect('patient_feedback_message')
    return render( request, 'pharmacist_templates/sure_delete.html')


@login_required
def delete_dispense(request, pk):
    try:
        dispense = Dispense.objects.get(id=pk)
        if request.method == 'POST':
            dispense.delete()
            messages.success(request, "Dispense deleted successfully")
            return redirect('pharmacist_prescription')
    except:
        messages.error(request, "Delete Error. Please Check again")
        return redirect('pharmacist_prescription')
    return render(request,'pharmacist_templates/sure_delete.html')


@login_required
def add_patient(request):
    logger.info('Adding a new patient')
    form = PatientForm(request.POST, request.FILES)
    try:
        if request.method == "POST":
            if form.is_valid():
                first_name = form.cleaned_data['first_name']
                last_name = form.cleaned_data['last_name']
                username = form.cleaned_data['username']
                email = form.cleaned_data['email']
                password = form.cleaned_data['password']
                address = form.cleaned_data['address']
                phone_number = form.cleaned_data['phone_number']
                dob = form.cleaned_data['dob']
                gender = form.cleaned_data['gender']
                user = CustomUser.objects.create_user(username=username, email=email, password=password, first_name=first_name, last_name=last_name,user_type=5)
                user.patients.address = address
                user.patients.phone_number = phone_number
                user.patients.dob = dob
                user.patients.gender = gender
                user.save()
                messages.success(request, "Patient added successfully!")
            else:
                messages.error(request, "There is an error in the patient form")
            return redirect('pharmacist_patient_form')            
    except Exception as e:
        logger.error('Patient not saved', e)
        messages.error(request, 'Patient not saved')
        return redirect('pharmacist_patient_form')
    context={
        "form":form
    }       
    return render(request,'pharmacist_templates/add_patient.html',context)


@login_required
def list_patients(request):
    patients = Patients.objects.all()
    context = {
        "patients": patients,
        }
    return render( request, 'pharmacist_templates/manage_patients.html', context)
    

@login_required
def edit_patient(request, patient_id):
    request.session['patient_id'] = patient_id
    patient = Patients.objects.get(admin=patient_id)
    form = EditPatientForm()
    form.fields['email'].initial = patient.admin.email
    form.fields['username'].initial = patient.admin.username
    form.fields['first_name'].initial = patient.admin.first_name
    form.fields['last_name'].initial = patient.admin.last_name
    form.fields['address'].initial = patient.address
    form.fields['gender'].initial = patient.gender
    form.fields['phone_number'].initial = patient.phone_number
    form.fields['dob'].initial = patient.dob
    try:
        if request.method == "POST":
            if patient_id == None:
                return redirect('all_pharmacist_patients')
            form = EditPatientForm( request.POST)
            if form.is_valid():                
                email = form.cleaned_data['email']
                username = form.cleaned_data['username']
                first_name = form.cleaned_data['first_name']
                last_name = form.cleaned_data['last_name']
                address = form.cleaned_data['address']
                gender = form.cleaned_data['gender']
                dob=form.cleaned_data['dob']
                phone_number = form.cleaned_data['phone_number']
                try:
                    user = CustomUser.objects.get(id=patient_id)
                    user.first_name = first_name
                    user.last_name = last_name
                    user.email = email
                    user.username = username
                    user.save()

                    patients_edit = Patients.objects.get(admin=patient_id)
                    patients_edit.address = address
                    patients_edit.gender = gender
                    patients_edit.dob=dob
                    patients_edit.phone_number=phone_number     
                    patients_edit.save()
                    messages.success(request, "Patient Updated Successfully!")
                    return redirect('all_pharmacist_patients')
                except:
                    messages.error(request, "Failed to update patient.")
                    return redirect('all_pharmacist_patients')
    except:
         messages.error(request, "Invalid Error!")
         return redirect('all_pharmacist_patients')

    context = {
        "id": patient_id,
        "form": form
    }
    return render(request, "pharmacist_templates/edit_patient.html", context)


@login_required
def patient_details(request, pk):
    patient = Patients.objects.get(id=pk)
    prescrip = patient.prescription_set.all()
    context = {
        "patient": patient,
        "prescription": prescrip
    }
    return render( request, 'pharmacist_templates/patient_personalRecords.html', context)


@login_required
def confirm_delete(request, pk):
    try:
        patient = Patients.objects.get(id=pk)
        if request.method == 'POST':
            patient.delete()
            messages.success(request, "Patient deleted")
            return redirect('all_pharmacist_patients')
    except:
        messages.error(request, "Patient Cannot be deleted. Patient is still on medication or an error occured")
        return redirect('all_pharmacist_patients')
    context = {
        "patient":patient,
    }    
    return render( request, 'pharmacist_templates/delete_patient.html', context)


@login_required
def add_drug(request):
    form = StockForm(request.POST,request.FILES)
    if form.is_valid():
        form = StockForm(request.POST,request.FILES)
        form.save()
        return redirect('add_stock')
    context = {
        "form":form,
        "title":"Add new drug"
    }
    return render( request, 'pharmacist_templates/add_stock.html', context)


@login_required
def add_category(request):
    try:
        form = CategoryForm(request.POST or None)
        if request.method == 'POST':
            if form.is_valid():
                form.save()
                messages.success(request, "Category added Successfully!")
                return redirect('add_category')
    except:
        messages.error(request, "Category Not added! Try again")
        return redirect('add_category')   
    context={
        "form":form,
        "title":"Add a new drug category"
    }
    return render(request, 'pharmacist_templates/add_category.html', context)


@login_required
def list_stock(request):
    stocks = Stock.objects.all().order_by("-id")
    ex = Stock.objects.annotate(
        expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
        ).filter(expired=True)
    eo = Stock.objects.annotate(
        expired=ExpressionWrapper(Q(valid_to__lt=Now()), output_field=BooleanField())
        ).filter(expired=False)
    context = {
        "stocks": stocks,
        "expired":ex,
        "expa": eo,
        "title":"Manage stocked drugs"
    }
    return render( request, 'pharmacist_templates/manage_stock.html', context)


@login_required
def edit_drug(request, pk):
    drugs = Stock.objects.get(id=pk)
    form = StockForm(request.POST or None,instance=drugs)
    if request.method == "POST":
        if form.is_valid():
            form = StockForm(request.POST or None ,instance=drugs)
            category = request.POST.get('category')
            drug_name = request.POST.get('drug_name')
            quantity = request.POST.get('quantity')
            # email=request.POST.get('email')
            try:
                drugs = Stock.objects.get(id=pk)
                drugs.drug_name = drug_name
                drugs.quantity = quantity
                drugs.save()
                form.save()
                messages.success(request,'Drug updated succefully')
            except:
                messages.error(request,'An error was encounterd. Drug not updated')   
    context = {
        "drugs":drugs,
        "form":form,
        "title":"Edit drug"
         }
    return render( request, 'pharmacist_templates/edit_drug.html', context)


@login_required
def increase_drug_quantity(request, pk):
    receive = Stock.objects.get(id=pk)
    form = ReceiveStockForm()
    try:
        form = ReceiveStockForm(request.POST or None )
        if form.is_valid():
            form = ReceiveStockForm(request.POST or None ,instance=receive)
            instance = form.save(commit=False) 
            instance.quantity += instance.receive_quantity
            instance.save()
            form = ReceiveStockForm()
            messages.success(request, str(instance.receive_quantity) + " " + instance.drug_name +" "+ "drugs added successfully")
            return redirect('manage_stock') 
    except:
        messages.error(request,"An Error occured. Drug quantity not added")         
        return redirect('pharmacist_manage_stock')
    context = {
        "form": form,
        "title": "Add Drug"
        }
    return render( request, 'pharmacist_templates/modal_form.html', context)


@login_required
def reorder_level(request, pk):
    queryset = Stock.objects.get(id=pk)
    form = ReorderLevelForm(request.POST or None, instance=queryset)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        messages.success(request, "Reorder level for " + str(instance.drug_name) + " is updated to " + str(instance.reorder_level))
        return redirect("pharmacist_manage_stock")
    context ={
        "instance": queryset,
        "form": form,
        "title": "Reorder Level"
    }
    return render(request,'pharmacist_templates/reorder_level.html',context)


@login_required
def drug_details(request, pk):
    stocks = Stock.objects.get(id=pk)
    context = {
        "stocks":stocks,
    }
    return render( request, 'pharmacist_templates/view_drug.html', context)


@login_required
def delete_drug(request, pk):
    try:
        drugs = Stock.objects.get(id=pk)
        if request.method == 'POST':
            drugs.delete()
            messages.success(request, "Drug successfully deleted.")  
            return redirect('pharmacist_manage_stock')
    except:
        messages.error(request, "Drug aready deleted")
        return redirect('manage_stock')
    return render(request,'pharmacist_templates/sure_delete_drug.html')