from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.utils.http import url_has_allowed_host_and_scheme

from .models import AuditEvent, Dispatch, Order, Payment


def _authenticate_identifier(identifier, password):
    identifier = (identifier or "").strip()

    user = authenticate(username=identifier, password=password)
    if user is not None:
        return user

    try:
        account = User.objects.get(email__iexact=identifier)
    except User.DoesNotExist:
        return None

    return authenticate(username=account.username, password=password)


def home(request):
    if request.user.is_authenticated:
        return redirect("dashboard")
    return redirect("login")


def staff_login(request):
    if request.user.is_authenticated:
        return redirect("dashboard")

    if request.method == "POST":
        identifier = request.POST.get("identifier", "")
        password = request.POST.get("password", "")
        user = _authenticate_identifier(identifier, password)

        if user is not None and user.is_active:
            login(request, user)
            next_url = request.POST.get("next") or request.GET.get("next")

            if next_url and url_has_allowed_host_and_scheme(
                next_url,
                allowed_hosts={request.get_host()},
                require_https=request.is_secure(),
            ):
                return redirect(next_url)

            return redirect("dashboard")

        messages.error(
            request,
            "The username/email or password you entered is incorrect.",
        )

    return render(
        request,
        "accounts/login.html",
        {"next": request.GET.get("next", "")},
    )


@login_required
def dashboard(request):
    orders = Order.objects.select_related("customer", "assigned_to").all()

    pending_payment_count = Payment.objects.filter(
        status__in=[
            Payment.Status.PENDING,
            Payment.Status.SUBMITTED,
            Payment.Status.RECEIVED,
        ]
    ).count()

    ready_dispatch_count = orders.filter(
        status=Order.Status.READY
    ).count()

    context = {
        "order_counts": {
            "new": orders.filter(status=Order.Status.NEW).count(),
            "accepted": orders.filter(status=Order.Status.ACCEPTED).count(),
            "processing": orders.filter(status=Order.Status.PROCESSING).count(),
            "pending_payments": pending_payment_count,
            "ready_dispatch": ready_dispatch_count,
            "delivered": orders.filter(status=Order.Status.DELIVERED).count(),
        },
        "recent_orders": orders[:8],
        "dispatch_count": Dispatch.objects.filter(
            status__in=[
                Dispatch.Status.QUEUED,
                Dispatch.Status.ASSIGNED,
            ]
        ).count(),
    }

    return render(request, "dashboard.html", context)


def staff_logout(request):
    logout(request)
    return redirect("login")


def db_status(request):
    from django.db import connection

    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
            cursor.fetchone()

        return HttpResponse(
            "<h1>Database Connectivity</h1>"
            "<p style='color:green;font-weight:bold'>"
            "DATABASE CONNECTION SUCCESSFUL"
            "</p>"
        )
    except Exception as exc:
        return HttpResponse(
            f"<h1>Database connection failed</h1><pre>{type(exc).__name__}: {exc}</pre>",
            status=500,
        )
