using System.Collections.Generic;
using System.Linq;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using Unity.Netcode;
using UnityEngine;

namespace Unity.Multiplayer.Samples.BossRoom
{
    public class PlatformManager : NetworkBehaviour
    {
        public static PlatformManager Instance;
        public List<Platform> m_Platforms;
        public int numberOfPlayers = 2;   // Number of players (n)
        public float planeRadius = 4f;  // Radius of the circular plane

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

        private void Start()
        {
            //if (IsServer) // Ensure only the server assigns IDs and initializes
            {
                m_Platforms = GetComponentsInChildren<Platform>().ToList();

                // Assign unique IDs to each platform
                for (int i = 0; i < m_Platforms.Count; i++)
                {
                    m_Platforms[i].AssignID(i + 1); // IDs start from 1
                }

                Debug.Log("All platforms have been assigned unique IDs.");
                Starter();
            }
        }
        void Starter()
        {
            numberOfPlayers = PlayerPrefs.GetInt("NumberOfLobbyPlayers");
            int platformsToSpawn = numberOfPlayers - 1;

            if (platformsToSpawn <= 0)
            {
                Debug.LogWarning("Not enough players to spawn platforms.");
                return;
            }
            for(int i=0;i < m_Platforms.Count;i++)
            {
                m_Platforms[i].gameObject.SetActive(false);
            }
            for(int i=0;i<platformsToSpawn;i++)
            {
                m_Platforms[i].gameObject.SetActive(true);
            }
            float angleIncrement = 360f / platformsToSpawn; // Divide the circle into equal segments

            for (int i = 0; i < platformsToSpawn; i++)
            {
                // Calculate angle in radians
                float angle = i * angleIncrement * Mathf.Deg2Rad;

                // Determine the position on the circular plane
                Vector3 position = new Vector3(
                    Mathf.Cos(angle) * planeRadius,
                    0f, // Assume the circular plane is on the XZ plane
                    Mathf.Sin(angle) * planeRadius
                );

                // Instantiate the platform
                m_Platforms[i].transform.position = position;
                m_Platforms[i].gameObject.SetActive(true);
                //m_Platforms[i].AnimationStarter();

                //Instantiate(platformPrefab, position, Quaternion.identity);
            }
        }
        public Platform FindNearestUnoccupiedPlatform(Vector3 position)
        {
            if (!IsServer)
            {
                Debug.LogError("FindNearestUnoccupiedPlatform should only be called on the server.");
                return null;
            }

            return m_Platforms
                .Where(platform => !platform.IsOccupied)
                .OrderBy(platform => Vector3.Distance(position, platform.transform.position))
                .FirstOrDefault();
        }

        public bool AreAllPlatformsOccupied()
        {
            return m_Platforms.All(platform => platform.IsOccupied);
        }

        public bool AssignPlayerToPlatform(ServerCharacter player)
        {
            if (!IsServer)
            {
                Debug.LogError("AssignPlayerToPlatform should only be called on the server.");
                return false;
            }

            var platform = m_Platforms.FirstOrDefault(p => !p.IsOccupied);
            if (platform != null)
            {
                platform.Occupy(player);
                return true;
            }

            Debug.LogWarning($"No unoccupied platforms available for {player.name}.");
            return false;
        }

        public Platform GetPlatformOccupiedByPlayer(ServerCharacter player)
        {
            return m_Platforms.FirstOrDefault(p => p.IsOccupied && p.GetOccupierId() == player.OwnerClientId);
        }

        public bool IsPlatformOccupied(Platform platform)
        {
            return platform.IsOccupied;
        }

        public Vector3 GetPlatformPosition(int platformId)
        {
            var platform = m_Platforms.FirstOrDefault(p => p.PlatformID == platformId);
            return platform ? platform.transform.position : Vector3.zero;
        }

        public Platform GetPlatformById(int platformId)
        {
            return m_Platforms.FirstOrDefault(p => p.PlatformID == platformId);
        }
    }
}