"""Loads SMS provider instances from the database into the registry.

Kept in a separate module so it can be imported lazily (on first SMS send),
which avoids accessing the database during ``AppConfig.ready()`` and prevents
the Django 5 RuntimeWarning about DB access during app initialisation.
"""

from __future__ import annotations

import structlog

_log = structlog.get_logger("simorgh.notifications.sms.loader")


def load_providers_into_registry() -> None:
    """Query ``SmsProvider`` rows and register active provider instances."""
    from simorgh.apps.notifications.models import SmsProvider
    from simorgh.apps.notifications.sms.base import register_provider

    providers = SmsProvider.objects.filter(is_active=True).order_by("-priority")

    for db_provider in providers:
        try:
            instance = _build_provider_instance(db_provider)
            if instance is not None:
                register_provider(instance)
        except Exception as exc:
            _log.error(
                "sms.provider_load_error",
                slug=db_provider.slug,
                error=str(exc),
            )


def _build_provider_instance(db_provider):  # type: ignore[no-untyped-def]
    """Construct the correct provider class from a ``SmsProvider`` DB row."""
    from simorgh.apps.notifications.sms.providers.sms_ir import SmsIrProvider
    from simorgh.apps.notifications.sms.providers.twilio import TwilioProvider

    slug = db_provider.slug
    creds = db_provider.credentials or {}
    params = db_provider.extra_params or {}

    if slug == "sms_ir":
        return SmsIrProvider(
            api_key=creds.get("api_key", ""),
            line_number=creds.get("line_number", ""),
            otp_template_id=int(params.get("otp_template_id", 0)),
            otp_param_name=params.get("otp_param_name", "Code"),
        )

    if slug == "twilio":
        return TwilioProvider(
            account_sid=creds.get("account_sid", ""),
            auth_token=creds.get("auth_token", ""),
            from_number=creds.get("from_number", ""),
            verify_service_sid=params.get("verify_service_sid", ""),
            otp_message_template=params.get(
                "otp_message_template", "Your verification code: {code}"
            ),
            use_verify=bool(params.get("use_verify", False)),
        )

    # Unknown slug — return None (caller skips silently)
    return None
