# admin_panel/views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.utils.dateparse import parse_date
from django.views import View
from datetime import date
from django.utils.decorators import method_decorator

from accounts.models import UserRole
from common.models import Departments
from admin_panel.models import Admin
from doctors.models import Doctor
from appointments.models import Appointments
from blogs.models import Blogs
from utilities.models import GlobalSettings
from admin_panel.decoratots import admin_login_required


# ===========================
# Admin Authentication Mixin
# ===========================
class AdminLoginRequiredMixin(View):
    """Applies admin_login_required decorator to all dispatch calls."""

    @method_decorator(admin_login_required)
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)


# ===========================
# Authentication Views
# ===========================
class AdminLoginView(View):
    def get(self, request):
        if request.user.is_authenticated:
            messages.success(request, "You are now logged in!!")
            return redirect(reverse("dashboard"))
        return render(request, "admin_panel/login.html")

    def post(self, request):
        email = request.POST.get("email")
        password = request.POST.get("password")
        user = authenticate(email=email, password=password)
        if not user:
            messages.error(request, "Invalid Credentials!!")
            redirect_url = reverse("admin_login")
        elif user and (not user.role or user.role.title != "Admin"):
            messages.error(request, "Not authorised to access admin panel!!")
            redirect_url = reverse("admin_login")
        else:
            login(request, user)
            messages.success(request, "You are now logged in!!")
            redirect_url = reverse("dashboard")
        return redirect(redirect_url)


class AdminLogoutView(AdminLoginRequiredMixin, View):
    def get(self, request):
        logout(request)
        return redirect(reverse("admin_login"))


# ===========================
# Dashboard
# ===========================
class DashboardView(AdminLoginRequiredMixin, View):
    def get(self, request):
        todays_appointment = Appointments.objects.filter(appointment_date=date.today())
        context = {
            "total_appointment_count": Appointments.objects.count(),
            "todays_appointment_count": todays_appointment.count(),
            "new_appointment_count": Appointments.objects.filter(status="New").count(),
            "todays_appointment": todays_appointment,
        }
        return render(request, "admin_panel/dashboard.html", context)


# ===========================
# Admin Users
# ===========================
class AdminsView(AdminLoginRequiredMixin, View):
    def get(self, request):
        admins = Admin.objects.all()
        return render(request, "admin_panel/admins.html", {"admins": admins})


class AdminView(AdminLoginRequiredMixin, View):
    template_list = "admin_panel/admins.html"
    template_create = "admin_panel/admins_create.html"
    template_edit = "admin_panel/admins_edit.html"

    def get(self, request, admin_id=None):
        path = request.path

        # Add new
        if "add_new_admin" in path:
            return render(request, self.template_create)

        # Edit
        elif "admin_edit" in path and admin_id:
            admin = get_object_or_404(Admin, id=admin_id)
            return render(request, self.template_edit, {"admin": admin})

        # Delete
        elif "admin_delete" in path and admin_id:
            admin = Admin.objects.filter(id=admin_id).first()
            if admin:
                admin.delete()
                messages.success(request, "Admin deleted successfully!!")
            else:
                messages.error(request, "Admin not found!!")
            return redirect(reverse("admins"))

        # List
        else:
            admins = Admin.objects.all()
            return render(request, self.template_list, {"admins": admins})

    def post(self, request, admin_id=None):
        name = request.POST.get("name")
        email = request.POST.get("email")
        password = request.POST.get("password")
        confirm_password = request.POST.get("confirm_password")
        profile_pic = request.FILES.get("profile_pic")

        # Frontend should already validate password == confirm_password

        # Edit Admin
        if "admin_edit" in request.path and admin_id:
            admin = get_object_or_404(Admin, id=admin_id)
            admin.first_name = name
            admin.email = email
            if profile_pic:
                admin.profile_pic = profile_pic
            admin.save()
            messages.success(request, "Admin details updated!!")

        # Add Admin
        else:
            if Admin.objects.filter(email=email).exists():
                messages.error(request, "Email already exists!!")
                return redirect(reverse("add_new_admin"))

            role = UserRole.objects.get(title="Admin")
            admin = Admin.objects.create(
                email=email,
                role=role,
                first_name=name,
                email_verification=True,
                profile_pic=profile_pic
            )
            admin.set_password(password)
            admin.save()
            messages.success(request, "New admin created!!")

        return redirect(reverse("admins"))



# ===========================
# Departments CRUD
# ===========================
class DepartmentView(AdminLoginRequiredMixin, View):
    template_list = "admin_panel/departments.html"
    template_create = "admin_panel/departments_create.html"
    template_edit = "admin_panel/departments_edit.html"

    def get(self, request, department_id=None):
        path = request.path

        # Add new
        if "add_new_department" in path:
            return render(request, self.template_create)

        # Edit
        elif "department_edit" in path and department_id:
            department = get_object_or_404(Departments, id=department_id)
            return render(request, self.template_edit, {"department": department})

        # Delete
        elif "department_delete" in path and department_id:
            department = Departments.objects.filter(id=department_id).first()
            if department:
                department.delete()
                messages.success(request, "Department deleted successfully!!")
            else:
                messages.error(request, "Department not found!!")
            return redirect(reverse("departments"))

        # List all
        else:
            departments = Departments.objects.all()
            return render(request, self.template_list, {"departments": departments})

    def post(self, request, department_id=None):
        title = request.POST.get("title")
        icon = request.FILES.get("icon")
        description = request.POST.get("description")
        status = request.POST.get("status")

        # Edit
        if "department_edit" in request.path and department_id:
            department = get_object_or_404(Departments, id=department_id)
            department.title = title
            if icon:
                department.icon = icon
            department.description = description
            department.status = status
            department.save()
            messages.success(request, "Department updated successfully!!")

        # Add
        else:
            Departments.objects.create(title=title, icon=icon, description=description)
            messages.success(request, "New department created!!")

        return redirect(reverse("departments"))


# ===========================
# Doctors CRUD
# ===========================
class DoctorView(AdminLoginRequiredMixin, View):
    template_list = "admin_panel/doctors.html"
    template_create = "admin_panel/doctors_create.html"
    template_edit = "admin_panel/doctors_edit.html"

    def get(self, request, doctor_id=None):
        path = request.path

        # Add new
        if "add_new_doctor" in path:
            departments = Departments.objects.filter(status=True)
            return render(request, self.template_create, {"departments": departments})

        # Edit
        elif "doctor_edit" in path and doctor_id:
            doctor = get_object_or_404(Doctor, id=doctor_id)
            departments = Departments.objects.filter(status=True)
            return render(request, self.template_edit, {"doctor": doctor, "departments": departments})

        # Delete
        elif "doctor_delete" in path and doctor_id:
            doctor = Doctor.objects.filter(id=doctor_id).first()
            if doctor:
                doctor.delete()
                messages.success(request, "Doctor deleted successfully!!")
            else:
                messages.error(request, "Doctor not found!!")
            return redirect(reverse("doctors"))

        # List
        else:
            doctors = Doctor.objects.all()
            return render(request, self.template_list, {"doctors": doctors})

    def post(self, request, doctor_id=None):
        full_name = request.POST.get("full_name")
        photo = request.FILES.get("photo")
        department = request.POST.get("department")
        specialisation = request.POST.get("specialisation")
        status = request.POST.get("status")

        # Edit
        if "doctor_edit" in request.path and doctor_id:
            doctor = get_object_or_404(Doctor, id=doctor_id)
            doctor.full_name = full_name
            if photo:
                doctor.photo = photo
            doctor.department_id = department
            doctor.specialisation = specialisation
            doctor.status = status
            doctor.save()
            messages.success(request, "Doctor details updated!!")

        # Add
        else:
            Doctor.objects.create(
                full_name=full_name,
                photo=photo,
                department_id=department,
                specialisation=specialisation,
            )
            messages.success(request, "New doctor created!!")

        return redirect(reverse("doctors"))


# ===========================
# Appointments
# ===========================
class AppointmentView(AdminLoginRequiredMixin, View):
    def get(self, request):
        appointments = Appointments.objects.all()
        departments = Departments.objects.all()
        from_date = request.GET.get('from_date')
        to_date = request.GET.get('to_date')
        department = request.GET.get('department')
        status = request.GET.get('status')

        if from_date:
            appointments = appointments.filter(appointment_date__gte=parse_date(from_date))
        if to_date:
            appointments = appointments.filter(appointment_date__lte=parse_date(to_date))
        if department:
            appointments = appointments.filter(department_id=department)
        if status:
            appointments = appointments.filter(status=status)

        context = {"appointments": appointments, "departments": departments}
        return render(request, "admin_panel/appointments.html", context)


# ===========================
# Blogs CRUD
# ===========================
class BlogView(AdminLoginRequiredMixin, View):
    template_list = "admin_panel/blogs.html"
    template_create = "admin_panel/blogs_create.html"
    template_edit = "admin_panel/blogs_edit.html"

    def get(self, request, blog_id=None):
        path = request.path

        # Add new
        if "add_new_blog" in path:
            return render(request, self.template_create)

        # Edit
        elif "blog_edit" in path and blog_id:
            blog = get_object_or_404(Blogs, id=blog_id)
            return render(request, self.template_edit, {"blog": blog})

        # List
        else:
            blogs = Blogs.objects.all()
            return render(request, self.template_list, {"blogs": blogs})

    def post(self, request, blog_id=None):
        title = request.POST.get("title")
        tag = request.POST.get("tag")
        icon = request.FILES.get("icon")
        summary = request.POST.get("summary")
        blog_content = request.POST.get("blog_content")
        status = request.POST.get("status")

        # Edit
        if "blog_edit" in request.path and blog_id:
            blog = get_object_or_404(Blogs, id=blog_id)
            blog.title = title
            if icon:
                blog.icon = icon
            blog.tag = tag
            blog.summary = summary
            blog.blog_content = blog_content
            blog.status = status
            blog.save()
            messages.success(request, "Blog updated successfully!!")

        # Add
        else:
            Blogs.objects.create(
                title=title,
                tag=tag,
                icon=icon,
                summary=summary,
                blog_content=blog_content,
            )
            messages.success(request, "New blog created!!")

        return redirect(reverse("blogs"))


# ===========================
# Global Settings
# ===========================
class GlobalSettingsView(AdminLoginRequiredMixin, View):
    def get(self, request):
        gs, _ = GlobalSettings.objects.get_or_create()
        return render(request, "admin_panel/global_settings.html", {"gs": gs})

    def post(self, request):
        gs, _ = GlobalSettings.objects.get_or_create()
        if request.FILES.get("hospital_logo"):
            gs.hospital_logo = request.FILES.get("hospital_logo")
        gs.hospital_name = request.POST.get("hospital_name")
        gs.hospital_location = request.POST.get("hospital_location")
        gs.emergency_contact = request.POST.get("emergency_contact")
        gs.hospital_email = request.POST.get("hospital_email")
        gs.smtp_email = request.POST.get("smtp_email")
        gs.smtp_password = request.POST.get("smtp_password")
        gs.save()
        messages.success(request, "Global Settings Saved!!")
        return redirect(reverse("dashboard"))
