from __future__ import annotations

from django.contrib.auth import get_user_model
from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response

from config.auth_views import _check_bcrypt_password, _fetch_legacy_user, _normalize_role_string

_MASTER_ROLES = frozenset({"admin", "superadmin", "super_admin", "owner"})


def _is_master_role(role) -> bool:
    return _normalize_role_string(role) in _MASTER_ROLES


@api_view(["POST"])
@permission_classes([AllowAny])
def master_login(request):
    """POST { "email": "...", "password": "..." } -> { "success": true, "token": "...", "user": {...} }"""
    identifier = (
        request.data.get("email") or request.data.get("username") or ""
    ).strip()
    password = (request.data.get("password") or "").strip()

    if not identifier or not password:
        return Response({"success": False, "error": "Email and password are required."}, status=400)

    legacy = _fetch_legacy_user(identifier)
    if not legacy:
        # Local/dev fallback: allow Django admin users when legacy DB users table
        # isn't present / doesn't contain this user.
        DjangoUser = get_user_model()
        django_user = None

        # Try standard Django auth (usually username+password).
        authed = authenticate(request, username=identifier, password=password)
        if authed is not None:
            django_user = authed
        else:
            # If user typed an email, attempt lookup by email then re-auth by username.
            try:
                candidate = DjangoUser.objects.filter(email__iexact=identifier).first()
            except Exception:
                candidate = None
            if candidate is not None:
                authed2 = authenticate(request, username=getattr(candidate, "username", ""), password=password)
                if authed2 is not None:
                    django_user = authed2

        if django_user is None:
            return Response({"success": False, "error": "Invalid credentials."}, status=401)

        if not (getattr(django_user, "is_staff", False) or getattr(django_user, "is_superuser", False)):
            return Response({"success": False, "error": "Admin access required."}, status=403)

        token, _ = Token.objects.get_or_create(user=django_user)
        role = "admin" if getattr(django_user, "is_superuser", False) else "admin"
        return Response({
            "success": True,
            "token": token.key,
            "user": {
                "id": str(getattr(django_user, "id", "")),
                "name": str(getattr(django_user, "username", "") or ""),
                "email": str(getattr(django_user, "email", "") or ""),
                "role": role,
                "business_id": None,
            },
        })

    stored_hash = (legacy.get("password") or "").strip()
    if not stored_hash or not _check_bcrypt_password(password, stored_hash):
        return Response({"success": False, "error": "Invalid credentials."}, status=401)

    role = _normalize_role_string(legacy.get("role"))
    if not _is_master_role(role):
        return Response({"success": False, "error": "Admin access required."}, status=403)

    DjangoUser = get_user_model()
    django_username = str(legacy.get("username") or legacy.get("email") or identifier)[:150]
    django_user, created = DjangoUser.objects.get_or_create(username=django_username)
    if created:
        django_user.set_unusable_password()
    django_user.email = str(legacy.get("email") or "")
    django_user.is_staff = True
    django_user.is_superuser = True
    django_user.save(update_fields=["email", "is_staff", "is_superuser"] + (["password"] if created else []))

    token, _ = Token.objects.get_or_create(user=django_user)

    return Response({
        "success": True,
        "token": token.key,
        "user": {
            "id": str(legacy.get("user_id") or django_user.id),
            "name": str(legacy.get("name") or legacy.get("username") or ""),
            "email": str(legacy.get("email") or ""),
            "role": role,
            "business_id": legacy.get("business_id"),
        },
    })


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def master_validate_token(request):
    """GET — returns success if the DRF token is valid."""
    return Response({"success": True})


@api_view(["POST"])
@permission_classes([IsAuthenticated])
def master_logout(request):
    """POST — deletes the DRF token (invalidates session)."""
    try:
        request.user.auth_token.delete()
    except Exception:
        pass
    return Response({"success": True})


@api_view(["POST"])
@permission_classes([IsAuthenticated])
def master_refresh(request):
    """POST — DRF tokens don't expire; return the existing token."""
    token, _ = Token.objects.get_or_create(user=request.user)
    return Response({"success": True, "token": token.key})


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def master_me(request):
    """GET — return current master user info."""
    u = request.user
    ident = (getattr(u, "email", None) or getattr(u, "username", None) or "").strip()
    legacy = _fetch_legacy_user(ident) if ident else None

    return Response({
        "success": True,
        "user": {
            "id": str(legacy.get("user_id") if legacy else getattr(u, "id", "")),
            "name": str((legacy or {}).get("name") or (legacy or {}).get("username") or getattr(u, "username", "")),
            "email": str((legacy or {}).get("email") or getattr(u, "email", "")),
            "role": _normalize_role_string((legacy or {}).get("role") or ("admin" if u.is_staff else "agent")),
            "business_id": (legacy or {}).get("business_id"),
        },
    })
