using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;

public enum DungeonStatusEnum
{
    None,
    FirstEntrance,
    SecondEntrance,
    LastEntrance
}

public class DungeonManager : MonoBehaviour
{
    public const string NAME = "Dungeon.Entrance";

    public DungeonStatusEnum EntranceIndex = DungeonStatusEnum.None;

    public GameObject TeleportModel;

    public GameObject Wizard;

    public bool IsBuilded = false;
    
    public static bool hasTeleported;

    // well finally useless
    public static void SetTeleported()
    {
        hasTeleported = true;
    }

    public void Awake()
    {
        if (PlayerPrefs.HasKey(NAME))
        {
            EntranceIndex = (DungeonStatusEnum)PlayerPrefs.GetInt(NAME);
        } else
        {
            EntranceIndex = DungeonStatusEnum.FirstEntrance;

            SaveProggress(EntranceIndex);
        }
    }

    public void Start()
    {
        hasTeleported = false;
    }

    public void Update()
    {
        if (!IsBuilded)
        {
            ManageTeleports();

            BuildWizard();
            IsBuilded = true;
        }
    }

    /// <summary>
    /// Function to manage which teleport is currently required to build on scene
    /// </summary>
    public void ManageTeleports()
    {
        switch (EntranceIndex)
        {
            case DungeonStatusEnum.FirstEntrance:
                {
                    // define output map
                    BuildTeleport("FirstLabirynthCave", new Vector3(15f, -8f, 10f));
                    break;
                }

            case DungeonStatusEnum.SecondEntrance:
                {
                    BuildTeleport("SecondLabirynthCave", new Vector3(3.5f, 0f, 10));

                    break;
                }

            case DungeonStatusEnum.LastEntrance:
                {
                    BuildTeleport("BossFightLabirynthCave", new Vector3(0, 0, 0));

                    break;
                }

            default:
                {

                    break;
                }
        }
    }

    public void BuildTeleport(string outputMapName, Vector3 spawnCoords)
    {
        // 1. get coordsfor teleport
        Vector3 teleportCoords;

        do {
            teleportCoords = GameObject.FindObjectOfType<TileMapGenerator>().gameObject.GetComponent<TileMapGenerator>().randomCoordsForStanding();
        } while (!(Vector2.Distance(teleportCoords, GameObject.FindGameObjectWithTag("Player").gameObject.transform.position) > 30));

        // 2. Instantiate
        var newTeleport = Instantiate(TeleportModel, teleportCoords, Quaternion.identity);
        newTeleport.name = TeleportModel.name;

        // 3. Set output map & spwan player coords
        newTeleport.GetComponent<DoorBehaviour>().gateway.currentMapName = SceneManager.GetActiveScene().name;
        newTeleport.GetComponent<DoorBehaviour>().gateway.coords = new Vector3(teleportCoords.x, teleportCoords.y, 10);

        newTeleport.GetComponent<DoorBehaviour>().gateway.nextMapName = outputMapName;
        newTeleport.GetComponent<DoorBehaviour>().gateway.respawnCoords = spawnCoords;

        newTeleport.AddComponent<EntryEventObserver>();


    }

    public void SaveProggress(DungeonStatusEnum status)
    {
        PlayerPrefs.SetInt(NAME, (int)status);
    }

    public void ChangeState()
    {
        EntranceIndex = (DungeonStatusEnum)(EntranceIndex + 1);

        SaveProggress(EntranceIndex);
    }



    public void BuildWizard()
    {
        Vector3 teleportCoords;

        do
        {
            teleportCoords = GameObject.FindObjectOfType<TileMapGenerator>().gameObject.GetComponent<TileMapGenerator>().randomCoordsForStanding();
        } while (!(Vector2.Distance(teleportCoords, GameObject.FindGameObjectWithTag("Player").gameObject.transform.position) > 6 &&
                Vector2.Distance(teleportCoords, GameObject.FindGameObjectWithTag("Player").gameObject.transform.position) < 9));

        var newWizard = Instantiate(Wizard, teleportCoords, Quaternion.identity);
        //newWizard.transform.localPosition = teleportCoords;

        newWizard.name = Wizard.name;
    }
}