using System.Collections;
using System.Collections.Generic;
using Unity.Multiplayer.Samples.BossRoom;
using UnityEngine;
using Unity.Netcode;

public class ScoreManager : NetworkBehaviour
{
    public static ScoreManager Instance { get; private set; }

    public Dictionary<ulong, int> playerScores = new Dictionary<ulong, int>();
    public Dictionary<ulong, string> playerNames = new Dictionary<ulong, string>();

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
    }

    public override void OnNetworkSpawn()
    {
        if (IsServer)
        {
            StartCrowPenaltyCoroutineServerRpc();
        }
    }

    [ServerRpc(RequireOwnership = false)]
    public void InitializePlayerScoreServerRpc(ulong ownerClientId, string name)
    {
        if (!playerScores.ContainsKey(ownerClientId))
        {
            playerScores[ownerClientId] = 200;
            playerNames[ownerClientId] = name;
            Debug.Log($"[ScoreManager] Player {ownerClientId} initialized with a starting score of 200 and name '{name}'.");
            Scoreboard.instance.ScoreBoardItemInitializer(ownerClientId, playerScores[ownerClientId], name);
            UpdatePlayerScoreClientRpc(ownerClientId, 200);
        }
        else
        {
            Debug.LogWarning($"[ScoreManager] Player {ownerClientId} already initialized.");
        }
    }

    public void UpdatePlayerScore(ulong ownerClientId, int newScore)
    {
        if (playerScores.ContainsKey(ownerClientId))
        {
            playerScores[ownerClientId] = newScore;
            Debug.Log($"[ScoreManager] Updating Player {ownerClientId} score to {newScore}.");
            UpdatePlayerScoreClientRpc(ownerClientId, newScore);
        }
        else
        {
            Debug.LogWarning($"[ScoreManager] No entry found for Player {ownerClientId}. Cannot update score.");
        }
    }

    [ClientRpc]
    public void UpdatePlayerScoreClientRpc(ulong ownerClientId, int newScore)
    {
        if (playerNames.ContainsKey(ownerClientId))
        {
            string playerName = playerNames[ownerClientId];
            Debug.Log($"[ScoreManager] Received score update for Player {ownerClientId} (Name: {playerName}): {newScore}");
            Scoreboard.instance.ScoreBoardUpdater(playerName, newScore);
        }
        else
        {
            Debug.LogWarning($"[ScoreManager] Player name not found for Player {ownerClientId}. Cannot update scoreboard.");
        }
    }

    public void AddPlayerScore(ulong ownerClientId, int scoreToAdd)
    {
        if (playerScores.ContainsKey(ownerClientId))
        {
            playerScores[ownerClientId] += scoreToAdd;
            UpdatePlayerScore(ownerClientId, playerScores[ownerClientId]);
        }
    }

    public void SubtractPlayerScore(ulong ownerClientId, int scoreToSubtract)
    {
        if (playerScores.ContainsKey(ownerClientId))
        {
            int newScore = Mathf.Max(0, playerScores[ownerClientId] - scoreToSubtract);
            UpdatePlayerScore(ownerClientId, newScore);
        }
    }

    [ServerRpc]
    public void StartCrowPenaltyCoroutineServerRpc()
    {
        StartCoroutine(ApplyCrowPenaltyCoroutine());
    }

    private IEnumerator ApplyCrowPenaltyCoroutine()
    {
        yield return new WaitUntil(() => PlatformManager.Instance != null && PlatformManager.Instance.AreAllPlatformsOccupied());

        while (true)
        {
            // Create a list to store client IDs whose scores need to be updated
            List<ulong> clientsToModify = new List<ulong>();

            foreach (var entry in playerScores)
            {
                ulong ownerClientId = entry.Key;

                if (CrowManager.Instance != null && CrowManager.Instance.GetCurrentCrow().OwnerClientId == ownerClientId)
                {
                    clientsToModify.Add(ownerClientId);
                }
            }

            // Apply the penalties after the iteration
            foreach (ulong clientId in clientsToModify)
            {
                SubtractPlayerScore(clientId, 2);
                Debug.Log($"[ScoreManager] Applied crow penalty to Player {clientId}. New score: {playerScores[clientId]}");
            }

            yield return new WaitForSeconds(5f);
        }
    }
}