"""Authentik directory + messaging router.

Resolves an ``authentik`` service instance from the registry, builds an
:class:`AuthentikClient` from its config + decrypted ``api_token`` secret, and
proxies paginated directory queries plus message-compose (email enqueue).
Graceful "not configured" / "unreachable" payloads (matching the monitoring
router's pattern) so the UI always renders.
"""

from __future__ import annotations

import logging
from typing import Any

from fastapi import APIRouter, Depends
from pydantic import BaseModel

from media_library_viewer_api.clients.authentik import AuthentikClient
from media_library_viewer_api.config import get_settings
from media_library_viewer_api.dependencies import get_mail_queue, get_settings_store
from media_library_viewer_api.services.mail_queue import MailQueue
from media_library_viewer_api.services.mailer import validate_smtp_settings
from media_library_viewer_api.services.service_resolution import resolve_service_record
from media_library_viewer_api.services.settings_store import SettingsStore
from media_library_viewer_api.widgets.sources import ServiceRecord

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/services/authentik", tags=["authentik"])


class MessageRequest(BaseModel):
    """Compose-request body for the Authentik messaging endpoint."""

    recipient_emails: list[str]
    subject: str
    html_body: str


def _build_client(service: ServiceRecord) -> AuthentikClient:
    base_url = str(service.config.get("base_url") or "").rstrip("/")
    api_token = str(service.secrets.get("api_token") or "")
    try:
        timeout = float(service.config.get("timeout_seconds") or 10)
    except (TypeError, ValueError):
        timeout = 10.0
    return AuthentikClient(base_url=base_url, api_token=api_token, timeout=timeout)


def _empty(error: str) -> dict[str, Any]:
    return {"items": [], "total": 0, "page": 1, "page_size": 50, "error": error}


@router.get("/{service_id}/users")
def get_authentik_users(
    service_id: str,
    search: str | None = None,
    page: int = 1,
    page_size: int = 50,
    store: SettingsStore = Depends(get_settings_store),
) -> dict[str, Any]:
    """Paginated Authentik user directory for a specific service instance."""
    service = resolve_service_record(store, "authentik", service_id)
    if service is None:
        logger.info("Authentik users requested but no enabled authentik service for id=%s", service_id)
        return _empty("Authentik service not configured")

    try:
        client = _build_client(service)
        return client.users(search=search, page=page, page_size=page_size)
    except Exception:
        logger.exception("Authentik users query failed for service %s", service_id)
        return _empty("Authentik is unreachable")


@router.get("/{service_id}/message/status")
def get_authentik_message_status(
    service_id: str,
    store: SettingsStore = Depends(get_settings_store),
    mail_queue: MailQueue = Depends(get_mail_queue),
) -> dict[str, Any]:
    """Mail-queue status snapshot for the Authentik messaging tab."""
    service = resolve_service_record(store, "authentik", service_id)
    if service is None:
        return {"state": "stopped", "worker_running": False, "error": "Authentik service not configured"}
    return mail_queue.status()


@router.post("/{service_id}/message")
def post_authentik_message(
    service_id: str,
    body: MessageRequest,
    store: SettingsStore = Depends(get_settings_store),
    mail_queue: MailQueue = Depends(get_mail_queue),
) -> dict[str, Any]:
    """Enqueue an email to Authentik-sourced recipients via the mail queue."""
    service = resolve_service_record(store, "authentik", service_id)
    if service is None:
        return {"status": "error", "error": "Authentik service not configured"}

    recipients = [r.strip() for r in body.recipient_emails if r.strip()]
    if not recipients:
        return {"status": "error", "error": "No recipients with valid email addresses."}

    settings = get_settings()
    try:
        validate_smtp_settings(settings)
    except ValueError as exc:
        return {"status": "error", "error": f"SMTP settings invalid: {exc}"}

    request_id = mail_queue.enqueue(
        settings=settings,
        recipients=recipients,
        subject=body.subject,
        html_body=body.html_body,
    )
    logger.info("Authentik message enqueued for service %s (%d recipients)", service_id, len(recipients))
    return {
        "status": "queued",
        "request_id": request_id,
        "recipient_count": len(recipients),
    }
