from ._base import *
from .account import get_account_status, get_account_characters


def recruit_a_friend_view(request):
    username = request.session.get('username')
    account_status = None
    characters = []
    claimed_rewards_count = 0

    # Si el usuario está logueado, obtener su información
    if username:
        # Obtener información del usuario
        with connections['acore_auth'].cursor() as cursor:
            cursor.execute("SELECT id, last_ip FROM account WHERE username = %s", [username])
            account_data = cursor.fetchone()

        if account_data:
            account_id = account_data[0]
            user_ip = account_data[1]
            account_status = get_account_status(account_id)
            characters = get_account_characters(account_id)
            claimed_rewards_count = ClaimedReward.objects.filter(account_id=account_id).count()
        else:
            account_id = None
            user_ip = None
    else:
        account_id = None
        user_ip = None

    # Obtener todas las recompensas
    all_rewards = RecruitReward.objects.all()
    available_rewards = []
    
    # Si el usuario está logueado, filtrar recompensas disponibles
    if account_id:
        available_rewards = [reward for reward in all_rewards if not ClaimedReward.objects.filter(account_id=account_id, recruit_reward=reward).exists()]

    # Manejar solicitudes POST (solo si el usuario está logueado)
    if request.method == 'POST':
        if not username:
            return JsonResponse({'success': False, 'message': 'Debes estar logueado para reclamar una recompensa.'})

        if not account_id or account_status is None:
            return JsonResponse({'success': False, 'message': 'No se ha encontrado tu cuenta.'})

        reward_id = request.POST.get('reward_id')
        character_name = request.POST.get('character')

        if not reward_id or not character_name:
            return JsonResponse({'success': False, 'message': 'Selecciona una recompensa y un personaje.'})

        try:
            reward = RecruitReward.objects.get(id=reward_id)

            # Verificar si ya se ha reclamado la recompensa
            if ClaimedReward.objects.filter(account_id=account_id, recruit_reward=reward).exists():
                return JsonResponse({'success': False, 'message': 'Ya has reclamado esta recompensa.'})

            # Verificar si cumple los requisitos
            if account_status['recruited_level_80_count'] < reward.required_friends:
                return JsonResponse({'success': False, 'message': 'No cumples con los requisitos.'})

            # Obtener amigos reclutados que han alcanzado el nivel 80
            recruited_friends = get_recruited_friends_at_level_80(account_id, reward.required_friends)
            
            # Comprobar si alguno de los reclutados es válido
            if len(recruited_friends) < reward.required_friends:
                return JsonResponse({'success': False, 'message': 'No cumples con los requisitos o los amigos tienen la misma IP.'})

            # Comprobar si alguno de los reclutados tiene la misma IP que el usuario
            if check_recruited_ip_conflict(recruited_friends, user_ip):
                return JsonResponse({'success': False, 'message': 'No puedes reclamar recompensas de amigos que tienen la misma IP.'})

            # Ejecutar el comando SOAP
            command = f".send items {character_name} 'Recompensa de Recluta Amigo' 'Tu amigo alcanzó el Nivel 80' {reward.item_id}:{reward.item_quantity}"
            response = execute_soap_command(command)

            if response and "Mail sent to" in response:
                # Registrar la recompensa como reclamada
                ClaimedReward.objects.create(
                    account_id=account_id,
                    username=username,
                    recruit_reward=reward,
                    character_name=character_name,
                    claimed_at=timezone.now(),
                    ip_address=request.META.get('REMOTE_ADDR')
                )
                claimed_rewards_count = ClaimedReward.objects.filter(account_id=account_id).count()
                
                return JsonResponse({
                    'success': True,
                    'message': f"Recompensa '{reward.reward_name}' entregada a {character_name}.",
                    'claimed_count': claimed_rewards_count
                })
            else:
                return JsonResponse({'success': False, 'message': 'Error al entregar la recompensa.'})

        except RecruitReward.DoesNotExist:
            return JsonResponse({'success': False, 'message': 'Recompensa no encontrada.'})

    # Renderizar la página para usuarios no logueados y logueados
    return render(request, 'recruit/recruit_a_friend.html', {
        'account_status': account_status,
        'all_rewards': all_rewards,
        'available_rewards': available_rewards,
        'characters': characters,
        'claimed_rewards_count': claimed_rewards_count,
        'is_logged_in': username is not None
    })
def check_recruited_ip_conflict(recruited_accounts, user_ip):
    """
    Verifica si alguna de las cuentas reclutadas tiene la misma IP que la cuenta del reclutador.
    """
    if not recruited_accounts:
        return False

    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("""
            SELECT last_ip FROM account WHERE id IN %s
        """, [tuple(recruited_accounts)])
        recruited_ips = [ip[0] for ip in cursor.fetchall()]

    return user_ip in recruited_ips
def get_recruited_friends_at_level_80(account_id, required_count):
    """
    Obtiene una lista de IDs de amigos reclutados que han alcanzado el nivel 80 y 
    no tienen la misma IP que el reclutador.
    """
    # Primero obtener los IDs de cuentas reclutadas desde `acore_auth`
    with connections['acore_auth'].cursor() as auth_cursor:
        auth_cursor.execute("""
            SELECT id, last_ip FROM account WHERE recruiter = %s
        """, [account_id])
        recruited_accounts = auth_cursor.fetchall()
    
    if not recruited_accounts:
        return []

    # Extraer IDs y IPs de las cuentas reclutadas
    recruited_ids = [acc[0] for acc in recruited_accounts]
    recruited_ips = {acc[0]: acc[1] for acc in recruited_accounts}

    # Obtener la IP del usuario actual
    with connections['acore_auth'].cursor() as cursor:
        cursor.execute("SELECT last_ip FROM account WHERE id = %s", [account_id])
        user_ip = cursor.fetchone()[0]

    # Luego, verificar cuáles de esas cuentas tienen personajes al nivel 80 en `acore_characters`
    with connections['acore_characters'].cursor() as char_cursor:
        char_cursor.execute("""
            SELECT DISTINCT account FROM characters
            WHERE level = 80 AND account IN %s
            LIMIT %s
        """, [tuple(recruited_ids), required_count])
        recruited_at_level_80 = [acc[0] for acc in char_cursor.fetchall()]

    # Filtrar cuentas que no tienen la misma IP que el usuario actual
    valid_recruits = [acc for acc in recruited_at_level_80 if recruited_ips[acc] != user_ip]

    return valid_recruits
