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

public class PlayerControllerScript : CharacterScript {

    bool canMove = true;

    [SerializeField]ControllerProfileScript playerControllerProfileScript;

    // Use this for initialization
    protected override void Start () {
		
	}

    // Update is called once per frame
    protected override void Update () {
        SetHealthText();
    }

    override public void HandleActions()
    {
        if (currentAction == Action.Wait)
        {
            //ResetActionPoints();
        }
        else if (currentAction == Action.Move)
        {
            MovePlayer();
        }
        else if (currentAction == Action.Attack)
        {
            Attack();
        }
        else if (currentAction == Action.Defend)
        {
            Defend();
        }
        else if (currentAction == Action.Dodge)
        {
            Dodge();
        }
        else if (currentAction == Action.Infect)
        {
            Infect();
        }
    }

    override public void NextAction()
    {
        //Debug.Log(characterName + "Last Action: " + currentAction);
        if (currentAction == Action.Wait)
        {
            //ResetActionPoints();
            currentAction = Action.Move;
        }
        else if (currentAction == Action.Move)
        {
            currentAction = Action.Attack;
        }
        else if (currentAction == Action.Attack)
        {
            currentAction = Action.Defend;
        }
        else if (currentAction == Action.Defend)
        {
            currentAction = Action.Dodge;
        }
        else if (currentAction == Action.Dodge)
        {
            currentAction = Action.Infect;
        }
        else if (currentAction == Action.Infect)
        {
            currentAction = Action.Wait;
        }
        //Debug.Log(characterName + " Next Action: " + currentAction);
    }

    #region Phase Functions

    #region Infect
    override protected void Infect()
    {
        InfectTargeter();
        if (playerControllerProfileScript.IsNextButtonPushed() || lastActionPoints <= 0)
        {
            for(int i = 0; i < MapScript.GetCharacters().Count; i++)
            {
                if(locationsTargeted.Contains(MapScript.GetCharacters()[i].GetCurrentLocation()) &&
                    MapScript.GetCharacters()[i] != this &&
                    MapScript.GetCharacters()[i].GetCurrentAffiliation() != this.GetCurrentAffiliation())
                {
                    float hitHealthPercent = ((float)MapScript.GetCharacters()[i].GetCurrentHealth() / (float)MapScript.GetCharacters()[i].GetMaxHealth());
                    if(hitHealthPercent <= critalhealthPercent)
                    {
                        Debug.Log("INFECTED: " + MapScript.GetCharacters()[i].GetCharacterName());
                        MapScript.GetCharacters()[i].SetIsInfected();
                    }
                }
            }

            NextAction();
            lastActionPoints = currentActionPoints;
            locationsTargeted.Clear();
        }
    }

    override protected void InfectTargeter()
    {
        for(int i = 1; i <= currentActionPoints; i++)
        {
           
            //up
            if(currentXLoc >= 0 && currentXLoc < MapScript.GetXTileCount() &&
                currentYLoc >= 0 - i && currentYLoc - i < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc, currentYLoc - i);
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //right
            if (currentXLoc + i >= 0 && currentXLoc + i < MapScript.GetXTileCount() &&
                currentYLoc >= 0 && currentYLoc < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc + i, currentYLoc);
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //down
            if (currentXLoc >= 0 && currentXLoc < MapScript.GetXTileCount() &&
                currentYLoc + i >= 0 && currentYLoc + i < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc, currentYLoc + i);
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //left
            if (currentXLoc - i >= 0 && currentXLoc - i < MapScript.GetXTileCount() &&
                currentYLoc >= 0 && currentYLoc < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc - i, currentYLoc);
                if(!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }

            //corners minus one so they are shorter than cardinal directions
            //top right
            if (currentXLoc + (i - 1) >= 0 && currentXLoc + (i - 1) < MapScript.GetXTileCount() &&
                currentYLoc - (i - 1) >= 0 && currentYLoc - (i - 1) < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc + (i - 1), currentYLoc - (i - 1));
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //bottom right
            if (currentXLoc + (i - 1) >= 0 && currentXLoc + (i - 1) < MapScript.GetXTileCount() &&
                currentYLoc + (i - 1) >= 0 && currentYLoc + (i - 1) < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc + (i - 1), currentYLoc + (i - 1));
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //bottom left
            if (currentXLoc - (i - 1) >= 0 && currentXLoc - (i - 1) < MapScript.GetXTileCount() &&
                currentYLoc + (i - 1) >= 0 && currentYLoc + (i - 1) < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc - (i - 1), currentYLoc + (i - 1));
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
            //top left
            if (currentXLoc - (i - 1) >= 0 && currentXLoc - (i - 1) < MapScript.GetXTileCount() &&
                currentYLoc - (i - 1) >= 0 && currentYLoc - (i - 1) < MapScript.GetYTileCount())
            {
                Vector2 loc = new Vector2(currentXLoc - (i - 1), currentYLoc - (i - 1));
                if (!locationsTargeted.Contains(loc))
                {
                    locationsTargeted.Add(loc);
                }
            }
        }
    }
    #endregion

    #region Dodge
    override protected void Dodge()
    {
        ChargeDodgePoints();
        if (playerControllerProfileScript.IsNextButtonPushed() || lastActionPoints <= 0)
        {
            NextAction();
            lastActionPoints = currentActionPoints;
            locationsTargeted.Clear();
            if (lastActionPoints > 0)
            {
                SoundPlayerScript.PlayConfirmSound();
            }

        }
        else if (playerControllerProfileScript.IsBackButtonPushed())
        {
            SetActionPointsToLast();
            currentDodgePoints = 0;
            locationsTargeted.Clear();
            SoundPlayerScript.PlayBackSound();
        }
    }

    override protected void ChargeDodgePoints()
    {
        Vector2 currentDir = playerControllerProfileScript.GetLastDirection();
        if (currentDir == Vector2.zero)
        {
            canMove = true;
        }
        else if ((currentDir == Vector2.right || currentDir == Vector2.up) && canMove)
        {
            if (currentActionPoints > 0)
            {
                currentDodgePoints += 1;
                currentActionPoints -= 1;
                SoundPlayerScript.PlayValChangeSound();
            }
            else
            {
                SoundPlayerScript.PlayFailSound();
            }
            canMove = false;
        }
        else if ((currentDir == Vector2.left || currentDir == Vector2.down) && canMove)
        {
            if (currentDodgePoints > 0)
            {
                currentDodgePoints -= 1;
                currentActionPoints += 1;
                SoundPlayerScript.PlayValChangeSound();
            }
            else
            {
                SoundPlayerScript.PlayFailSound();
            }
            canMove = false;
        }
    }
    #endregion

    #region Defend
    override protected void Defend()
    {
        ChargeDefencePoints();
        if (playerControllerProfileScript.IsNextButtonPushed() || lastActionPoints <= 0)
        {
            NextAction();
            lastActionPoints = currentActionPoints;
            locationsTargeted.Clear();
            if (lastActionPoints > 0)
            {
                SoundPlayerScript.PlayConfirmSound();
            }
        }
        else if (playerControllerProfileScript.IsBackButtonPushed())
        {
            SetActionPointsToLast();
            currentDefendPoints = 0;
            locationsTargeted.Clear();
            SoundPlayerScript.PlayBackSound();
        }
    }

    override protected void ChargeDefencePoints()
    {
        Vector2 currentDir = playerControllerProfileScript.GetLastDirection();
        if (currentDir == Vector2.zero)
        {
            canMove = true;
        }
        else if ((currentDir == Vector2.right || currentDir == Vector2.up) && canMove)
        {
            if (currentActionPoints > 0)
            {
                currentDefendPoints += 1;
                currentActionPoints -= 1;
                SoundPlayerScript.PlayValChangeSound();
            }
            else
            {
                SoundPlayerScript.PlayFailSound();
            }
            canMove = false;
        }
        else if ((currentDir == Vector2.left || currentDir == Vector2.down) && canMove)
        {
            if (currentDefendPoints > 0)
            {
                currentDefendPoints -= 1;
                currentActionPoints += 1;
                SoundPlayerScript.PlayValChangeSound();
            }
            else
            {
                SoundPlayerScript.PlayFailSound();
            }
            canMove = false;
        }

    }
    #endregion

    #region Attack
    override protected void Attack()
    {
        AttackTargeter();
        if (playerControllerProfileScript.IsNextButtonPushed() || lastActionPoints <= 0)
        {
            for (int i = 0; i < MapScript.GetCharacters().Count; i++)
            {
                if (locationsTargeted.Contains(MapScript.GetCharacters()[i].GetCurrentLocation()) &&
                    MapScript.GetCharacters()[i] != this &&
                    MapScript.GetCharacters()[i].GetCurrentAffiliation() != this.GetCurrentAffiliation())
                {

                    MapScript.GetCharacters()[i].TakeDamage(damage - (locationsTargeted.Count - 1));
                }
            }
            targetXLoc = currentXLoc;
            targetYLoc = currentYLoc;

            NextAction();
            lastActionPoints = currentActionPoints;
            locationsTargeted.Clear();
            if(lastActionPoints > 0)
            {
                SoundPlayerScript.PlayConfirmSound();
            }

        }
        else if (playerControllerProfileScript.IsBackButtonPushed())
        {
            targetXLoc = currentXLoc;
            targetYLoc = currentYLoc;

            SetActionPointsToLast();
            locationsTargeted.Clear();
            SoundPlayerScript.PlayBackSound();
        }
    }

    override protected void AttackTargeter()
    {
        Vector2 currentDir = playerControllerProfileScript.GetLastDirection();
        int newXLoc = targetXLoc;
        int newYLoc = targetYLoc;

        if (currentDir == Vector2.zero)
        {
            canMove = true;
        }
        else if (currentDir == Vector2.right && canMove && directionFacing == Vector2.right)
        {
            if (currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc + 1, targetYLoc)))
            {
                newXLoc += 1;
                currentActionPoints -= 1;
            }
            canMove = false;
        }
        else if (currentDir == Vector2.left && canMove && directionFacing == Vector2.left)
        {
            if (currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc - 1, targetYLoc)))
            {
                newXLoc -= 1;
                currentActionPoints -= 1;
            }
            canMove = false;
        }

        if (newXLoc < 0)
        {
            newXLoc = 0;
            currentActionPoints += 1;
        }
        else if (newXLoc >= MapScript.GetXTileCount())
        {
            newXLoc = MapScript.GetXTileCount() - 1;
            currentActionPoints += 1;
        }

        if (newYLoc < 0)
        {
            newYLoc = 0;
            currentActionPoints += 1;
        }
        else if (newYLoc >= MapScript.GetYTileCount())
        {
            newYLoc = MapScript.GetYTileCount() - 1;
            currentActionPoints += 1;
        }

        targetXLoc = newXLoc;
        targetYLoc = newYLoc;
        Vector2 loc = new Vector2(targetXLoc, targetYLoc);
        if (!locationsTargeted.Contains(loc))
        {
            locationsTargeted.Add(loc);
        }
    }
    #endregion

    #region Movement
    override protected void MovePlayer()
    {
        FindMovementTargetSquare();
        if (playerControllerProfileScript.IsNextButtonPushed())
        {
            bool isSafe = true;
            for(int i = 0; i < MapScript.GetCharacters().Count; i++)
            {
                if(locationsTargeted.Contains(MapScript.GetCharacters()[i].GetCurrentLocation()) &&
                    MapScript.GetCharacters()[i] != this)
                {
                    isSafe = false;
                }
            }
            if(isSafe)
            {
                currentXLoc = targetXLoc;
                currentYLoc = targetYLoc;

                NextAction();
                lastActionPoints = currentActionPoints;
                locationsTargeted.Clear();
                SoundPlayerScript.PlayMoveSound();
            }
            else
            {
                Debug.Log("CAN'T MOVE");
                SoundPlayerScript.PlayFailSound();
            }
        }
        else if (playerControllerProfileScript.IsBackButtonPushed())
        {
            targetXLoc = currentXLoc;
            targetYLoc = currentYLoc;

            SetActionPointsToLast();
            locationsTargeted.Clear();
            SoundPlayerScript.PlayBackSound();
        }
    }

    override protected void FindMovementTargetSquare()
    {
        Vector2 currentDir = playerControllerProfileScript.GetLastDirection();
        int newXLoc = targetXLoc;
        int newYLoc = targetYLoc;
        if (currentDir == Vector2.zero)
        {
            canMove = true;
        }
        else if (currentDir == Vector2.up && canMove)
        {
            if (currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc, targetYLoc - 1)))
            {
                newYLoc -= 1;
                currentActionPoints -= 1;
            }
            canMove = false;
        }
        else if (currentDir == Vector2.right && canMove)
        {
            if (currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc + 1, targetYLoc)))
            {
                newXLoc += 1;
                currentActionPoints -= 1;
            }
            canMove = false;
        }
        else if (currentDir == Vector2.down && canMove)
        {
            if (currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc, targetYLoc + 1)))
            {
                newYLoc += 1;
                currentActionPoints -= 1;
            }
            canMove = false;
        }
        else if (currentDir == Vector2.left && canMove)
        {
            if(currentActionPoints > 0 && !locationsTargeted.Contains(new Vector2(targetXLoc - 1, targetYLoc)))
            {
                newXLoc -= 1;
                currentActionPoints -= 1;
            }   
            canMove = false;
        }

        //check x pos if still on map
        if (newXLoc < 0)
        {
            newXLoc = 0;
            currentActionPoints += 1;
        }
        else if (newXLoc >= MapScript.GetXTileCount())
        {
            newXLoc = MapScript.GetXTileCount() - 1;
            currentActionPoints += 1;
        }
        //check y pos if still on map
        if (newYLoc < 0)
        {
            newYLoc = 0;
            currentActionPoints += 1;
        }
        else if (newYLoc >= MapScript.GetYTileCount())
        {
            newYLoc = MapScript.GetYTileCount() - 1;
            currentActionPoints += 1;
        }

        Affiliation oppositeAf = CharacterScript.Affiliation.Enemy;
        if(currentAffiliation == Affiliation.Enemy)
        {
            oppositeAf = CharacterScript.Affiliation.Friendly;
        }
        //check territory type
        if (MapScript.GetTiles()[newXLoc + (newYLoc * MapScript.GetXTileCount())].GetCurrentAffiliation() == oppositeAf)
        {
            newXLoc = targetXLoc;
            newYLoc = targetYLoc;
            currentActionPoints += 1;
        }

        targetXLoc = newXLoc;
        targetYLoc = newYLoc;
        Vector2 loc = new Vector2(targetXLoc, targetYLoc);
        if (!locationsTargeted.Contains(loc))
        {
            locationsTargeted.Add(loc);
        }
    }
    #endregion

    #endregion
}
