def _parse_device_type(user_agent: str) -> str:
    ua = user_agent.lower()
    if any(kw in ua for kw in ["ipad", "tablet"]):
        return "TABLET"
    if any(kw in ua for kw in ["mobile", "android", "iphone", "ipod", "windows phone"]):
        return "MOBILE"
    return "DESKTOP"


def _parse_browser(user_agent: str) -> str:
    ua = user_agent.lower()
    if "edg" in ua:
        return "Edge"
    if "opr" in ua or "opera" in ua:
        return "Opera"
    if "chrome" in ua:
        return "Chrome"
    if "safari" in ua:
        return "Safari"
    if "firefox" in ua:
        return "Firefox"
    return "Unknown"


def _get_client_ip(request) -> str:
    xff = request.META.get("HTTP_X_FORWARDED_FOR")
    if xff:
        return xff.split(",")[0].strip()
    return request.META.get("REMOTE_ADDR", "")


def create_user_session(request, user, school, user_type: str, external_id: int, refresh_token):
    """
    Create a UserSession record in the master DB after successful OTP login.
    Returns the session_token UUID string, or None on failure.
    Silently ignores errors so auth flow is never blocked.
    """
    try:
        from .models import UserSession

        ua = request.META.get("HTTP_USER_AGENT", "")
        platform_header = request.META.get("HTTP_X_PLATFORM", "").lower()

        # Mobile app sends X-Platform: android | ios
        if platform_header in ("android", "ios"):
            device_type = "MOBILE"
            device_name = platform_header.capitalize()
            browser = "Mobile App"
        else:
            device_type = _parse_device_type(ua)
            device_name = ""
            browser = _parse_browser(ua)

        session = UserSession.objects.using("default").create(
            user_id=user.id,
            school_id=school.id,
            user_type=user_type,
            external_id=external_id,
            refresh_jti=refresh_token.get("jti", ""),
            device_type=device_type,
            device_name=device_name,
            browser=browser,
            ip_address=_get_client_ip(request) or None,
            user_agent=ua[:2000],
        )
        return str(session.session_token)
    except Exception:
        return None


def get_enabled_modules(school):
    """
    Return the list of enabled module codes for a school.
    Always includes default (always-on) modules regardless of explicit assignments.
    Uses master DB explicitly so it works from any request context.
    """
    from .models import SchoolModuleAccess, SchoolModule

    assigned = list(
        SchoolModuleAccess.objects.using("default")
        .filter(school=school, is_enabled=True)
        .values_list("module__code", flat=True)
    )
    defaults = list(
        SchoolModule.objects.using("default")
        .filter(is_default=True, is_active=True)
        .values_list("code", flat=True)
    )
    return list(set(assigned + defaults))
