using System.Collections.Generic;
using UnityEngine;
using static MapManager;

public abstract class Command
{
    public abstract void Start(Unit unit);
    public abstract void Stop(Unit unit);
    public abstract bool Excecute(Unit unit);
    public virtual void DebugDraw() { }
}

public class MoveCommand : Command
{
    private Tile m_target;
    private Path m_path;
    private Tile m_nextNode;

    public MoveCommand(Vector3 target)
    {
        m_target = MapManager.Instance.GetTile(WorldPosToTile(target));
    }

    public MoveCommand(Tile target)
    {
        m_target = target;
    }
    public MoveCommand(Path path)
    {
        m_path = path;
    }

    public override void DebugDraw()
    {
        if (m_path != null && m_path.Valid())
        {
            foreach(Tile t in m_path)
            {
                Gizmos.color = Color.red;
                Gizmos.DrawWireSphere(MapManager.TileToWorld(t), 0.5f);
            }
        }
    }

    public override void Start(Unit unit)
    {
        m_path ??= MapManager.Instance.FindPath(WorldPosToTile(unit.transform.position), m_target);

        if (m_path.Valid())
            m_nextNode = m_path.Next();
        else
            m_nextNode = MapManager.Instance.GetTile(MapManager.WorldPosToTile(unit.transform.position));
        unit.GetComponent<Animator>().SetBool("Walkning", true);
    }

    public override void Stop(Unit unit)
    {
        unit.GetComponent<Animator>().SetBool("Walkning", false);
    }

    public override bool Excecute(Unit unit)
    {
        unit.LookAt(m_nextNode);
        
        float distance = Vector3.Distance(unit.transform.position, TileToWorld(m_nextNode));
        if (distance < 0.2f)
        {
            if(m_path.Valid())
            {
                m_nextNode = m_path.Next();
                return false;
            }
            return true;
        }

        if(distance < unit.MovementSpeed * Time.deltaTime)
        {
            unit.transform.position = TileToWorld(m_nextNode);
        }
        else
        {
            Vector3 dir = TileToWorld(m_nextNode) - unit.transform.position;
            dir.y = 0;
            dir.Normalize();
            unit.transform.position += dir * unit.MovementSpeed * Time.deltaTime;
        }

        return false;
    }
}

public class MineCommand : Command
{
    private Tile m_tile;
    private float m_timeLeft;
    private MoveCommand m_movement;
    private Path m_path;

    public MineCommand(Tile targetTile)
    {
        m_tile = targetTile;
        m_timeLeft = 5f;
    }

    public override void Start(Unit unit)
    {
        unit.GetComponent<Animator>().SetBool("Mining", true);
    }

    public override void Stop(Unit unit)
    {
        unit.GetComponent<Animator>().SetBool("Mining", false);
    }

    public override bool Excecute(Unit unit)
    {
        unit.LookAt(m_tile);
        
        m_timeLeft -= Time.deltaTime;
        if (m_timeLeft <= 0)
        {
            MapManager.Instance.DestroyTile(m_tile);
            return true;
        }
        else
        {
            return false;
        }
    }
}

public class ClimbLadderCommand : Command
{
    public override bool Excecute(Unit unit)
    {
        WinCondition.DwarfClimbedLadder();
        GameObject.Destroy(unit.gameObject);
        return true;
    }

    public override void Start(Unit unit)
    {

    }

    public override void Stop(Unit unit)
    {

    }
}