from datetime import timedelta

from django.conf import settings
from django.utils import timezone


ADMIN_PASSWORD_EXPIRY_DAYS = int(getattr(settings, "ADMIN_PASSWORD_EXPIRY_DAYS", 30))
ADMIN_ROLE_CODES = {"ADMIN", "CONTRACT_ADMIN", "MARKET_ADMIN", "MARKET_STAFF"}
ADMIN_PERMISSION_CODES = {
    "market.dashboard.admin",
    "market.roles.manage",
    "contract.dashboard.access",
}


def _role_codes(user):
    if not user or not hasattr(user, "get_role_codes"):
        return []
    try:
        return list(user.get_role_codes())
    except Exception:
        return []


def _permission_codes(user):
    if not user or not hasattr(user, "get_permission_codes"):
        return set()
    try:
        return set(user.get_permission_codes())
    except Exception:
        return set()


def is_admin_level_user(user):
    if not getattr(user, "is_authenticated", False):
        return False

    if getattr(user, "is_superuser", False) or getattr(user, "is_staff", False):
        return True

    if getattr(user, "type", "") == "ADMIN":
        return True

    try:
        if user.groups.filter(name__iexact="Admins").exists():
            return True
    except Exception:
        pass

    role_codes = set(_role_codes(user))
    if role_codes & ADMIN_ROLE_CODES:
        return True

    if any(str(code).endswith("_ADMIN") for code in role_codes):
        return True

    return bool(_permission_codes(user) & ADMIN_PERMISSION_CODES)


def is_password_expired(user, now=None):
    if not is_admin_level_user(user):
        return False

    reference = getattr(user, "password_changed_at", None) or getattr(user, "date_joined", None)
    if not reference:
        return True

    now = now or timezone.now()
    return reference <= now - timedelta(days=ADMIN_PASSWORD_EXPIRY_DAYS)


def get_password_change_reason(user):
    if not getattr(user, "is_authenticated", False):
        return ""

    if getattr(user, "is_temporary_password", False):
        return "TEMPORARY_PASSWORD"

    if getattr(user, "force_password_change", False):
        return "FORCE_PASSWORD_CHANGE"

    if is_password_expired(user):
        return "PASSWORD_EXPIRED"

    return ""


def requires_password_change(user):
    return bool(get_password_change_reason(user))


def password_change_message(reason):
    if reason == "PASSWORD_EXPIRED":
        return "Your password has expired. Please change it to continue."
    if reason == "TEMPORARY_PASSWORD":
        return "Please change your temporary password to continue."
    if reason == "FORCE_PASSWORD_CHANGE":
        return "Please change your password to continue."
    return ""
