from __future__ import annotations

import webbrowser

from django.db import models
from django.db.models import QuerySet
from django.urls import reverse


class AdminUrlResolver:
    """Builds Django admin URLs for model instances and querysets."""

    @staticmethod
    def get_admin_url(instance: models.Model) -> str | None:
        """Build the admin change URL for a single model instance.

        Returns None if the URL cannot be resolved (e.g. model not registered in admin).
        """
        meta = instance._meta
        try:
            url = reverse(
                f"admin:{meta.app_label}_{meta.model_name}_change",
                args=[instance.pk],
            )
            return url
        except Exception:
            return None

    @staticmethod
    def get_changelist_url(queryset: QuerySet) -> str | None:
        """Build the admin changelist URL for the queryset's model."""
        meta = queryset.model._meta
        try:
            url = reverse(f"admin:{meta.app_label}_{meta.model_name}_changelist")
            return url
        except Exception:
            return None

    @staticmethod
    def get_admin_url_for_target(target: object) -> str | None:
        """Resolve an admin URL for either a model instance or a queryset."""
        if isinstance(target, models.Model):
            return AdminUrlResolver.get_admin_url(target)
        elif isinstance(target, QuerySet):
            return AdminUrlResolver.get_changelist_url(target)
        return None

    @staticmethod
    def open_in_browser(url: str) -> str:
        """Attempt to open a URL in the default browser.

        Returns the URL string regardless (for display in TUI status bar).
        """
        try:
            webbrowser.open(url)
        except Exception:
            pass
        return url

