using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Events;

namespace Assets.Scripts.Network
{
    public class Manager : MonoBehaviour
    {
        public enum WorldEventTypes
        {
            wetPlayerMovingStart,
            wetPlayerMovingStop,
            wetCrystalTake,
            wetCrystalUse,
            wetHomeEnter,
            wetHomeLeave,
            wetBeaconEnter,
            wetBeaconLeave,
            wetBeaconTake,
            wetBatteryDead,
            wetBlueprintPickedUp,
            wetBlueprintStored,
            wetBlueprintWon,
            wetHomeDead,
        }

        public static Manager _;

        [System.Serializable]
        public class OnWorldObjectEvent : UnityEvent<WorldObject,WorldEventTypes> { }
        [System.Serializable]
        public class OnWorldObjectDoubleEvent : UnityEvent<WorldObject, WorldObject, WorldEventTypes> { }
        [System.Serializable]
        public class OnWorldObjectDouble2Event : UnityEvent<WorldObject, int, WorldEventTypes> { }

        public OnWorldObjectEvent WorldEvent = new OnWorldObjectEvent();
        public OnWorldObjectDoubleEvent WorldDoubleEvent = new OnWorldObjectDoubleEvent();
        public OnWorldObjectDouble2Event WorldDouble2Event = new OnWorldObjectDouble2Event();

        public List<GameObject> AvailablePrefabs;
        public Dictionary<int, GameObject> Prefabs;

        public Camera_Controller playerCamera;

        public World world;
        public static Network net;

        void Start()
        {
            _ = this;

            Prefabs = new Dictionary<int, GameObject>();

            for( int k = 0; k < AvailablePrefabs.Count; k++ )
            {
                GameObject g = AvailablePrefabs[k];
                PrefabID pid = g.GetComponent<PrefabID>();
                Prefabs[pid.ID] = g;
            }

            world = World.GetFakeWorld(this);

            StartCoroutine(WaitWorldInit());

            //net = new Network();
        }

        void Update()
        {
            if (world != null && world.Me != null)
            {
                Vector2 move = new Vector2(0, 0);
                move.x = Input.GetAxis("Horizontal");
                move.y = Input.GetAxis("Vertical");

                Quaternion lookRot = world.Me.AssignedGameObject.transform.rotation;

                if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
                {
                    var p = playerCamera.characterCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10f));
                    lookRot = Quaternion.LookRotation(p - world.Me.AssignedGameObject.transform.position, Vector3.up);
                }

                Vector2 joyInput = new Vector2(Input.GetAxis("Joy X"), Input.GetAxis("Joy Y"));

                if (joyInput.x != 0 || joyInput.y != 0)
                {
                    var r = world.Me.AssignedGameObject.transform.eulerAngles.y + joyInput.x * 5f;
                    lookRot = Quaternion.Euler(0, r, 0);
                }

                world.FrameMove(Time.deltaTime, move, lookRot.eulerAngles.y);

                if(Vector3.Distance(world.MyHouse.AssignedGameObject.transform.position, world.Me.AssignedGameObject.transform.position) < 50f)
                {
                    playerCamera.eyeSpawner.DisableAnim();
                }
                else
                {
                    playerCamera.eyeSpawner.EnableAnim();
                }
            }
        }

        IEnumerator WaitWorldInit()
        {
            while(world == null)
            {
                yield return null;
            }

            Destroy(Camera.main.gameObject);
            playerCamera = Instantiate(playerCamera, world.Me.AssignedGameObject.transform.position, Quaternion.Euler(90, 0, 0));
            ReInitCamera();
            playerCamera.SetDefaultOffset();
            ObjectOcclusion.Instance.playerTransform = world.Me.AssignedGameObject.transform;
        }

        public void ReInitCamera()
        {
            playerCamera.targetTransform = world.Me.AssignedGameObject.transform;
        }


        public void onBekonsEvent(WorldObject worldObject, WorldObject worldTower, WorldEventTypes eventType)
        {
            Debug.Log("bekonsEventType: " + eventType + " wObj: " + worldObject.AssignedGameObject.name);
            switch (eventType)
            {
                case WorldEventTypes.wetBeaconTake:
                    {
                        Debug.Log("bekons");
                        if (((Player)worldObject).IsMe())
                        {
                            SoundManager.script.PlaySound(1);
                            LightHouse lightHouse = (LightHouse)worldTower;
                            Player player = (Player)worldObject;
                            worldTower.AssignedGameObject.GetComponent<LightColor>().EnableLights();
                            Debug.Log("Player takeeee");
                            float h, s, v;
                            Color.RGBToHSV(player.PlayerColor, out h, out s, out v);
                            Color adjustedColor = Color.HSVToRGB(h, s / 3, Math.Min(v * 2, 1f));
                            worldTower.AssignedGameObject.GetComponent<LightColor>().SetLightColor(Color.clear, adjustedColor);
                        }

                        if (worldObject != null)
                        {
                            LightHouse lightHouse = (LightHouse)worldTower;
                            Player player = (Player)worldObject;
                            worldTower.AssignedGameObject.GetComponent<LightColor>().EnableLights();
                            Debug.Log("Player takeeee " + player.PlayerColor.ToString());
                            float h, s, v;
                            Color.RGBToHSV(player.PlayerColor, out h, out s, out v);
                            Color adjustedColor = Color.HSVToRGB(h, s/3, Math.Min(v * 2, 1f));
                            worldTower.AssignedGameObject.GetComponent<LightColor>().SetLightColor(Color.clear, adjustedColor);
                        }
                    }
                    break;
                case WorldEventTypes.wetBeaconEnter:
                    if (((Player)worldObject).IsMe())
                    {
                        playerCamera.SetLighthouseOffset();
                    }
                    break;
                case WorldEventTypes.wetBeaconLeave:
                    if (((Player)worldObject).IsMe())
                    {
                        playerCamera.SetDefaultOffset();
                    }
                    break;
            }
        }

        public void  bluePrintEvent(WorldObject worldObject, int bluePrintID, WorldEventTypes eventType)
        {
            Debug.Log("blueprint event: " + eventType + " wObj: " + worldObject.AssignedGameObject.name);
            switch (eventType)
            {
                case WorldEventTypes.wetBlueprintPickedUp:
                    {
                        if (((Player)worldObject).IsMe())
                        {
                            Debug.Log("blueprint picked up");
                            blueprintIconController.script.spawnBlueprintIcon(bluePrintID);
                          
                            SoundManager.script.PlaySound(2);
                        }
                        break;
                    }
                case WorldEventTypes.wetBlueprintStored:
                    {
                        if (((Player)worldObject).IsMe())
                        {
                            Debug.Log("blueprint stored up");
                            bluePrintCounter.script.turnOnBP(bluePrintID);
                            blueprintIconController.script.deSpawnBlueprintIcon(bluePrintID);
                        }
                        break;
                    }            
            }
            
        }

        public void onWorldEvent(WorldObject worldObject, WorldEventTypes eventType) {
            switch(eventType) {
                case WorldEventTypes.wetPlayerMovingStart:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("Walking", true);
                    break;
                case WorldEventTypes.wetPlayerMovingStop:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("Walking", false);
                    break;
                case WorldEventTypes.wetCrystalTake:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("Carrying", true);
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().Crystal2.SetActive(true);
                    {
                        if (((Player)worldObject).IsMe())
                        {
                            crystal_icon.crystal_icon_script.SpawnCoin();
                            SoundManager.script.PlaySound(2);
                        }
                    }
                    break;
                case WorldEventTypes.wetCrystalUse:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("Carrying", false);
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().Crystal2.SetActive(false);
                    {
                        if (((Player)worldObject).IsMe())
                        {
                            Debug.Log("atnesu kristaalu");
                            Home_health.script.sparklesAnimator.SetTrigger("launch_sparkles");
                            Home_health.script.homeTextAnimator.SetTrigger("flash");
                            SoundManager.script.PlaySound(0);
                            crystal_icon.crystal_icon_script.DeSpawnCoin();
                        }
                    }
                    break;
                case WorldEventTypes.wetHomeEnter:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("InHouse", true);
                    break;
                case WorldEventTypes.wetHomeLeave:
                    worldObject.AssignedGameObject.GetComponent<GoodPlayerBehaviour>().animator.SetBool("InHouse", false);
                    break;
                case WorldEventTypes.wetBlueprintWon:
                    Debug.Log("GAME WON!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                    if (((Player)worldObject).IsMe())
                    {
                        gameOverPanel.script.ShowPanel("LOL YOU WON");
                    }
                    else
                    {
                        gameOverPanel.script.ShowPanel("LOL YOU LOST");
                    }
                    break;
                case WorldEventTypes.wetHomeDead:
                    if (((Player)worldObject).IsMe())
                    {
                        Debug.Log("game over");
                        SoundManager.script.PlaySound(3);
                        gameOverPanel.script.ShowPanel("YOU DIEDED LOL");
                                             }
                    break;


            }
        }
    }
}
