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

public class MapManager : MonoBehaviour
{
    public static MapManager Instance;
    
    public List<MapLocation> Locations;
    public MapLocation StartNode;
    public MapLocation CurrentNode => _currentNode;
    public PlayerMapIcon PlayerIcon;
    public GameObject ConnectionPrefab;
    public GameObject MapBackground;
    public GameObject MessageBox;
    public TypingText MessageBoxText;
    public float MoveDuration = 1;

    public GameObject MapClean;
    public GameObject MapDirty1;
    public GameObject MapDirty2;
    public GameObject MapDirty3;
    public GameObject MapDirty4;

    private bool _isMoving;
    private MapLocation _currentNode;
    private MapLocation _targetNode;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
    }

    private void OnEnable()
    {
        MapBackground.SetActive(true);
    }

    private void OnDisable()
    {
        MapBackground.SetActive(false);
        MessageBox.SetActive(false);
    }

    private void Start()
    {
        ResetPlayerToStartNode();
    }

    private void ResetPlayerToStartNode()
    {
        if (PlayerIcon != null && StartNode != null)
        {
            PlayerIcon.transform.position = StartNode.transform.position;
            _currentNode = StartNode;
        }
    }

    public void TryToMoveToLocation(MapLocation loc)
    {
        if (_currentNode.IsNeighboring(loc) && !_isMoving)
        {
            _targetNode = loc;
            StartCoroutine(MoveToTarget(() => MoveCompleted()));
        }
        else
        {
            Debug.LogError("Not accessible");
        }

        void MoveCompleted()
        {
            Enemy e = _currentNode.GetEnemy();
            GameManager.Instance.DoBattle(e, loc.Type);
        }
    }

    private IEnumerator MoveToTarget(UnityAction done)
    {
        _isMoving = true;
        float t = Time.time + MoveDuration;

        while (Time.time < t)
        {
            float alpha = (t - Time.time) / MoveDuration;
            PlayerIcon.transform.position = Vector3.Lerp(_targetNode.transform.position, _currentNode.transform.position, Mathf.SmoothStep(0,1,alpha));
            yield return null;
        }

        PlayerIcon.transform.position = _targetNode.transform.position;
        _currentNode = _targetNode;
        _isMoving = false;
        done.Invoke();
    }

    public void TransformMap(int state)
    {
        switch (state)
        {
            case 0:
            {
                MapDirty1.SetActive(false);
                MapDirty2.SetActive(false);
                MapDirty3.SetActive(false);
                MapDirty4.SetActive(false);
                break;
            }
            case 1:
            {
                MapDirty1.SetActive(true);
                MapDirty2.SetActive(false);
                MapDirty3.SetActive(false);
                MapDirty4.SetActive(false);
                Animator anim = MapDirty1.GetComponent<Animator>();
                anim.Play("Fade", 0);
                break;
            }
            case 2:
            {
                MapDirty1.SetActive(false);
                MapDirty2.SetActive(true);
                MapDirty3.SetActive(false);
                MapDirty4.SetActive(false);
                Animator anim = MapDirty2.GetComponent<Animator>();
                anim.Play("Fade", 0);
                break;
            }
            case 3:
            {
                MapDirty1.SetActive(false);
                MapDirty2.SetActive(false);
                MapDirty3.SetActive(true);
                MapDirty4.SetActive(false);
                Animator anim = MapDirty3.GetComponent<Animator>();
                anim.Play("Fade", 0);
                break;
            }
            case 4:
            {
                MapDirty1.SetActive(false);
                MapDirty2.SetActive(false);
                MapDirty3.SetActive(false);
                MapDirty4.SetActive(true);
                Animator anim = MapDirty4.GetComponent<Animator>();
                anim.Play("Fade", 0);
                break;
            }
        }
    }
}
