from ._base import *
from .pages import check_server_status, get_online_characters_count
from .auth import _set_game_account_session
from .account import get_account_characters, get_account_status, formatear_fecha

# Endpoints JSON que alimentan las islas React/TSX del frontend (Vite).
# Se montan bajo /api/ (fuera de i18n_patterns). De momento con JsonResponse;
# si crece la superficie de la API se puede introducir DRF.


def home_news_api(request):
    """Últimas noticias para la isla de la portada."""
    noticias = Noticia.objects.order_by('-fecha_publicacion')[:50]
    data = [
        {
            "id": n.id,
            "titulo": n.titulo,
            "fecha": n.fecha_publicacion.isoformat() if n.fecha_publicacion else None,
            "contenido": n.contenido,
            "enlace": n.enlace or None,
        }
        for n in noticias
    ]
    return JsonResponse({"noticias": data})


def home_status_api(request):
    """Estado del servidor para la isla de la portada (nombre, online, login, dirección)."""
    server = ServerSelection.objects.first()
    online = get_online_characters_count()
    status = "Online" if (server and check_server_status(server.address, server.port)) else "Offline"
    expansion = server.expansion if server else "Unknown"
    return JsonResponse(
        {
            "server_name": server.name if server else None,
            "address": server.address if server else None,
            "expansion": expansion,
            "online_characters": online,
            "status": status,
        }
    )


def account_select_api(request):
    """Selecciona la cuenta de juego de la bnet en sesión (isla del selector).

    Vía GET (sin POST): es idempotente y solo permite elegir cuentas ligadas a la
    propia cuenta Battle.net de la sesión, así que no expone nada de otros usuarios.
    """
    bnet_id = request.session.get('bnet_id')
    if not bnet_id:
        return JsonResponse({"success": False, "error": "No autenticado"}, status=401)
    try:
        selected_id = int(request.GET.get("account_id", ""))
    except (TypeError, ValueError):
        return JsonResponse({"success": False, "error": "Cuenta no válida"})
    with connections['acore_auth'].cursor() as cursor:
        accounts = bnet.get_game_accounts_for_bnet(cursor, bnet_id)
    chosen = next((g for g in accounts if g["id"] == selected_id), None)
    if not chosen:
        return JsonResponse({"success": False, "error": "Cuenta de juego no válida."})
    _set_game_account_session(request, chosen)
    return JsonResponse({"success": True, "redirect": reverse("my-account")})


def account_me_api(request):
    """Datos del panel «Mi cuenta» (isla): info de cuenta, estado, puntos,
    créditos Battlepay, token de seguridad y personajes. Requiere sesión."""
    username = request.session.get('username')
    if not username:
        return JsonResponse({"authenticated": False}, status=401)
    try:
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute(
                "SELECT id, username, reg_mail, email, last_ip, last_attempt_ip, joindate "
                "FROM account WHERE username = %s", [username])
            row = cursor.fetchone()
        if not row:
            return JsonResponse({"authenticated": False}, status=404)
        account_id = row[0]
        characters = get_account_characters(account_id)
        status = get_account_status(account_id)
        points = HomeApiPoints.objects.filter(accountID=account_id).first()
        sectoken = SecurityToken.objects.filter(user_id=account_id).first()
        with connections['acore_auth'].cursor() as cursor:
            credits = bnet.get_battlepay_credits(cursor, request.session.get('bnet_id'))
    except Exception as e:
        logger.error("account_me_api: %s", e)
        return JsonResponse({"authenticated": True, "error": "No se pudieron cargar los datos de la cuenta."}, status=200)

    return JsonResponse({
        "authenticated": True,
        "user_info": {
            "bnet_email": request.session.get('bnet_email') or row[3],
            "username": row[1],
            "reg_mail": row[2],
            "email": row[3],
            "last_ip": row[4],
            "last_attempt_ip": row[5],
            "joindate": formatear_fecha(row[6]),
        },
        "account_status": status,
        "dp": points.dp if points else 0,
        "vp": points.vp if points else 0,
        "battlepay_credits": credits,
        "token_status": "Solicitado" if sectoken else "Sin solicitar",
        "token_date": sectoken.created_at.strftime('%H:%M:%S %d-%m-%Y') if sectoken else None,
        "characters": characters,
    })
