from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.contrib.auth.models import Group
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render

from .forms import PatientProfileForm, EncounterForm, VitalSignForm, DiagnosisForm, PrescriptionForm, LabResultForm
from .models import PatientProfile, Encounter, LabResult, AuditEvent
from .permissions import ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE, role_required

def _ensure_groups_exist():
    for name in (ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE):
        Group.objects.get_or_create(name=name)

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_emr_dashboard(request):
    _ensure_groups_exist()
    stats = {
        "patients": PatientProfile.objects.count(),
        "encounters": Encounter.objects.count(),
        "open_encounters": Encounter.objects.filter(is_closed=False).count(),
        "lab_results": LabResult.objects.count(),
    }
    return render(request, "emr/staff/dashboard.html", {
        "stats": stats,
        "recent_patients": PatientProfile.objects.order_by("-created_at")[:8],
        "recent_encounters": Encounter.objects.order_by("-visit_datetime")[:8],
        "recent_audit": AuditEvent.objects.all()[:10],
    })

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)

def staff_patient_list(request):
    q = request.GET.get("q","").strip()
    qs = PatientProfile.objects.all().order_by("-created_at")
    if q:
        qs = qs.filter(Q(full_name__icontains=q) | Q(email__icontains=q) | Q(phone__icontains=q))
    paginator = Paginator(qs, 25)
    page_obj = paginator.get_page(request.GET.get("page") or 1)
    return render(request, "emr/staff/patient_list.html", {"patients": page_obj.object_list, "page_obj": page_obj, "q": q})


def staff_patient_create(request):
    if request.method == "POST":
        form = PatientProfileForm(request.POST)
        if form.is_valid():
            patient = form.save()
            messages.success(request, "Patient created.")
            return redirect("website:emr:staff_patient_detail", patient_id=patient.id)
    else:
        form = PatientProfileForm()
    return render(request, "emr/staff/patient_form.html", {"form": form, "mode": "create"})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_patient_detail(request, patient_id):
    patient = get_object_or_404(PatientProfile, pk=patient_id)
    return render(request, "emr/staff/patient_detail.html", {
        "patient": patient,
        "encounters": patient.encounters.order_by("-visit_datetime"),
    })

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_patient_edit(request, patient_id):
    patient = get_object_or_404(PatientProfile, pk=patient_id)
    if request.method == "POST":
        form = PatientProfileForm(request.POST, instance=patient)
        if form.is_valid():
            form.save()
            messages.success(request, "Patient updated.")
            return redirect("website:emr:staff_patient_detail", patient_id=patient.id)
    else:
        form = PatientProfileForm(instance=patient)
    return render(request, "emr/staff/patient_form.html", {"form": form, "mode": "edit", "patient": patient})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_encounter_create(request, patient_id):
    patient = get_object_or_404(PatientProfile, pk=patient_id)
    if request.method == "POST":
        form = EncounterForm(request.POST)
        if form.is_valid():
            enc = form.save(commit=False)
            enc.patient = patient
            enc.created_by = request.user
            enc.save()
            messages.success(request, "Encounter created.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = EncounterForm()
    return render(request, "emr/staff/encounter_form.html", {"form": form, "patient": patient, "mode": "create"})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_encounter_detail(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    return render(request, "emr/staff/encounter_detail.html", {
        "encounter": enc,
        "patient": enc.patient,
        "vitals": enc.vitals.order_by("-recorded_at"),
        "diagnoses": enc.diagnoses.order_by("-created_at"),
        "prescriptions": enc.prescriptions.order_by("-created_at"),
        "lab_results": enc.lab_results.order_by("-created_at"),
    })

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_encounter_edit(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    if request.method == "POST":
        form = EncounterForm(request.POST, instance=enc)
        if form.is_valid():
            form.save()
            messages.success(request, "Encounter updated.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = EncounterForm(instance=enc)
    return render(request, "emr/staff/encounter_form.html", {"form": form, "patient": enc.patient, "mode": "edit", "encounter": enc})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_add_vitals(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    if request.method == "POST":
        form = VitalSignForm(request.POST)
        if form.is_valid():
            vit = form.save(commit=False)
            vit.encounter = enc
            vit.recorded_by = request.user
            vit.save()
            messages.success(request, "Vitals saved.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = VitalSignForm()
    return render(request, "emr/staff/item_form.html", {"form": form, "title": "Add vitals", "encounter": enc})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR)
def staff_add_diagnosis(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    if request.method == "POST":
        form = DiagnosisForm(request.POST)
        if form.is_valid():
            dx = form.save(commit=False)
            dx.encounter = enc
            dx.diagnosed_by = request.user
            dx.save()
            messages.success(request, "Diagnosis added.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = DiagnosisForm()
    return render(request, "emr/staff/item_form.html", {"form": form, "title": "Add diagnosis", "encounter": enc})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR)
def staff_add_prescription(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    if request.method == "POST":
        form = PrescriptionForm(request.POST)
        if form.is_valid():
            rx = form.save(commit=False)
            rx.encounter = enc
            rx.prescribed_by = request.user
            rx.save()
            messages.success(request, "Prescription added.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = PrescriptionForm()
    return render(request, "emr/staff/item_form.html", {"form": form, "title": "Add prescription", "encounter": enc})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)
def staff_add_lab_result(request, encounter_id):
    enc = get_object_or_404(Encounter, pk=encounter_id)
    if request.method == "POST":
        form = LabResultForm(request.POST, request.FILES)
        if form.is_valid():
            lab = form.save(commit=False)
            lab.encounter = enc
            lab.uploaded_by = request.user
            lab.save()
            messages.success(request, "Lab result uploaded.")
            return redirect("website:emr:staff_encounter_detail", encounter_id=enc.id)
    else:
        form = LabResultForm()
    return render(request, "emr/staff/item_form.html", {"form": form, "title": "Upload lab result", "encounter": enc})

@login_required
@role_required(ROLE_ADMIN, ROLE_DOCTOR, ROLE_NURSE)

def staff_audit_log(request):
    q = request.GET.get("q","").strip()
    qs = AuditEvent.objects.all().select_related("actor").order_by("-created_at")
    if q:
        qs = qs.filter(Q(model_label__icontains=q) | Q(object_repr__icontains=q) | Q(actor__username__icontains=q) | Q(action__icontains=q))
    paginator = Paginator(qs, 50)
    page_obj = paginator.get_page(request.GET.get("page") or 1)
    return render(request, "emr/staff/audit_log.html", {"events": page_obj.object_list, "page_obj": page_obj, "q": q})


