"""
Themis views — function-based views for profile settings, API key
management, notifications, and health check endpoints.
"""
import logging

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_GET, require_http_methods, require_POST

from themis.encryption import encrypt_value
from themis.forms import APIKeyCreateForm, APIKeyEditForm, ProfileSettingsForm
from themis.models import UserAPIKey, UserNotification
from themis.notifications import get_notifications_for_user, get_unread_count

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# Health check endpoints
# ---------------------------------------------------------------------------


@require_GET
def ready(request):
    """
    Readiness probe for Kubernetes / load balancers.

    Checks database connectivity. Returns 200 if ready, 503 if not.
    """
    try:
        connection.ensure_connection()
        return JsonResponse({"status": "ready"}, status=200)
    except Exception as exc:
        logger.warning("Readiness check failed: %s", exc)
        return JsonResponse(
            {"status": "not ready", "error": str(exc)},
            status=503,
        )


@require_GET
def live(request):
    """
    Liveness probe for Kubernetes.

    Simple check that Django is responding to requests.
    """
    return JsonResponse({"status": "alive"}, status=200)


# ---------------------------------------------------------------------------
# Profile settings
# ---------------------------------------------------------------------------


@login_required
@require_http_methods(["GET", "POST"])
def profile_settings(request):
    """Display and update user profile preferences."""
    profile = request.user.profile

    if request.method == "POST":
        form = ProfileSettingsForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, "Preferences saved.")
            return redirect("themis:profile-settings")
    else:
        form = ProfileSettingsForm(instance=profile)

    return render(request, "themis/profile/settings.html", {"form": form})


# ---------------------------------------------------------------------------
# API key management
# ---------------------------------------------------------------------------


@login_required
@require_GET
def key_list(request):
    """List all API keys for the current user."""
    keys = UserAPIKey.objects.filter(user=request.user).order_by(
        "service_name", "label"
    )
    return render(request, "themis/keys/list.html", {"keys": keys})


@login_required
@require_http_methods(["GET", "POST"])
def key_create(request):
    """Create a new API key."""
    if request.method == "POST":
        form = APIKeyCreateForm(request.POST)
        if form.is_valid():
            UserAPIKey.objects.create(
                user=request.user,
                service_name=form.cleaned_data["service_name"],
                key_type=form.cleaned_data["key_type"],
                label=form.cleaned_data["label"],
                encrypted_value=encrypt_value(form.cleaned_data["key_value"]),
                instructions=form.cleaned_data["instructions"],
                help_url=form.cleaned_data["help_url"],
            )
            messages.success(request, "API key added.")
            return redirect("themis:key-list")
    else:
        form = APIKeyCreateForm()

    return render(request, "themis/keys/create.html", {"form": form})


@login_required
@require_GET
def key_detail(request, pk):
    """View API key details and instructions."""
    key = get_object_or_404(UserAPIKey, pk=pk, user=request.user)
    return render(request, "themis/keys/detail.html", {"key": key})


@login_required
@require_http_methods(["GET", "POST"])
def key_edit(request, pk):
    """Edit API key metadata (not the key value)."""
    key = get_object_or_404(UserAPIKey, pk=pk, user=request.user)

    if request.method == "POST":
        form = APIKeyEditForm(request.POST, instance=key)
        if form.is_valid():
            form.save()
            messages.success(request, "API key updated.")
            return redirect("themis:key-detail", pk=key.pk)
    else:
        form = APIKeyEditForm(instance=key)

    return render(request, "themis/keys/edit.html", {"form": form, "key": key})


@login_required
@require_http_methods(["POST"])
def key_delete(request, pk):
    """Delete an API key."""
    key = get_object_or_404(UserAPIKey, pk=pk, user=request.user)
    key.delete()
    messages.success(request, "API key deleted.")
    return redirect("themis:key-list")


# ---------------------------------------------------------------------------
# Notification views
# ---------------------------------------------------------------------------


@login_required
@require_GET
def notification_list(request):
    """Display all notifications for the current user."""
    include_read = request.GET.get("include_read", "0") == "1"
    notifications = get_notifications_for_user(
        request.user, include_read=include_read, limit=100
    )
    unread_count = get_unread_count(request.user)
    return render(
        request,
        "themis/notifications/list.html",
        {
            "notifications": notifications,
            "unread_count": unread_count,
            "include_read": include_read,
        },
    )


@login_required
@require_POST
def notification_mark_read(request, pk):
    """Mark a single notification as read."""
    notification = get_object_or_404(
        UserNotification, pk=pk, user=request.user
    )
    notification.is_read = True
    notification.read_at = timezone.now()
    notification.save(update_fields=["is_read", "read_at", "updated_at"])

    # If the notification has a URL, redirect there
    if notification.url:
        return redirect(notification.url)
    return redirect("themis:notification-list")


@login_required
@require_POST
def notification_mark_all_read(request):
    """Mark all unread notifications as read."""
    UserNotification.objects.filter(
        user=request.user,
        is_read=False,
    ).update(is_read=True, read_at=timezone.now())
    messages.success(request, "All notifications marked as read.")
    return redirect("themis:notification-list")


@login_required
@require_POST
def notification_dismiss(request, pk):
    """Dismiss a single notification."""
    notification = get_object_or_404(
        UserNotification, pk=pk, user=request.user
    )
    notification.is_dismissed = True
    notification.dismissed_at = timezone.now()
    notification.save(
        update_fields=["is_dismissed", "dismissed_at", "updated_at"]
    )
    return redirect("themis:notification-list")


@login_required
@require_GET
def notification_count(request):
    """
    Return unread notification count as JSON.

    Used by the notification bell polling script.
    """
    count = get_unread_count(request.user)
    return JsonResponse({"count": count})
