import random
import math
import matplotlib.pyplot as plt


def calculate_xp_needed_for_next_level(level: int) -> int:
    return int(
        35 * (level**2) + 35 * level
    )

def get_level_from_xp(total_xp: int) -> int:
    level = 0
    while True:
        xp_needed = calculate_xp_needed_for_next_level(level)
        if total_xp < xp_needed:
            break
        level += 1
    return level


def simulate_xp(num_messages=1000):
    total_xp = 0
    xp_per_message = []
    xp_progression = []
    level_ups = []
    current_level = 0

    for i in range(num_messages):
        # Simulate a message length between 5 and 120 characters
        msg_length = random.randint(5, 120)
        base = random.randint(2, 5)
        length_bonus = min(msg_length, 100) // 20  # +1 XP per 20 chars, max +5
        extra_xp = base + length_bonus
        extra_xp = min(extra_xp, 8)  # cap at 8 XP per message
        xp_per_message.append(extra_xp)
        total_xp += extra_xp
        xp_progression.append(total_xp)

        # Check for level up
        next_level_xp = calculate_xp_needed_for_next_level(current_level)
        if total_xp >= next_level_xp:
            current_level += 1
            level_ups.append(i + 1)  # Message number where level up occurred

    avg_xp = total_xp / num_messages
    level = get_level_from_xp(total_xp)

    print(f"Simulated {num_messages} messages.")
    print(f"Total XP: {total_xp}")
    print(f"Average XP per message: {avg_xp:.2f}")
    print(f"Min XP in a message: {min(xp_per_message)}")
    print(f"Max XP in a message: {max(xp_per_message)}")
    print(f"Level reached: {level}")

    # Plot XP progression and level-ups
    plt.figure(figsize=(10, 6))
    plt.plot(range(1, num_messages + 1), xp_progression, label="Total XP")
    if level_ups:
        plt.scatter(
            level_ups,
            [xp_progression[i - 1] for i in level_ups],
            color="red",
            label="Level Up",
            zorder=5,
        )
    plt.xlabel("Message Number")
    plt.ylabel("Cumulative XP")
    plt.title("XP Progression Over Messages")
    plt.grid(True)
    plt.legend()
    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    simulate_xp(1000000)
