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

public enum EAICombatMovementBehavior
{
    stay_near_ally = 0,
    stay_near_anchor_point,
    go_ham,
    destroy_landmarks,
}

public class LDHuntAndKillActionComponent : LDAIDoActionComponent
{
    [Header("Combat Instructions")]
    public bool CanTargetNonCombatants;
    public EAICombatMovementBehavior CombatBehavior;
    public float LeashRangeIfAttached;
    public float FiringRange;
    private LDGameActor myAnchor;
    private LDGameActor myCombatTarget;
    private LDGameActor myOwningActor;
    private Vector2 vAnchorPosition;
    private float fLeashLength;
    private LDGameActor myLandmarkTarget;

    public List<TM_Weapon> WeaponsToFire;

    public override void Start()
    {
        base.Start();
        myOwningActor = GetComponent<LDGameActor>();

        //Just in case, we can always change it later
        vAnchorPosition = myOwningActor.vWorldPos;
        myAnchor = myOwningActor.GetAnchorActor();
    }

    public override bool FigureOutWhereToGo()
    {
        if (fLeashLength == 0f)
        {
            fLeashLength = LeashRangeIfAttached;
        }

        //based on my combat behavior, we should look for location to move to
        switch (CombatBehavior)
        {
            case EAICombatMovementBehavior.go_ham:
                if (myCombatTarget != null)
                {
                    vGoalLocation = myCombatTarget.vWorldPos;
                }
                break;
            case EAICombatMovementBehavior.stay_near_ally:
                if (myAnchor != null)
                {
                    //if we are within our leash length, chase the combat target, otherwise stay in bounds
                    Vector2 vToAlly = myAnchor.vWorldPos - myOwningActor.vWorldPos;

                    if (myCombatTarget == null || vToAlly.SqrMagnitude() > fLeashLength * fLeashLength)
                    {
                        vGoalLocation = myAnchor.vWorldPos;
                    }
                    else if (myCombatTarget != null)
                    {
                        vGoalLocation = myCombatTarget.vWorldPos;
                    }
                    else
                    {
                        vGoalLocation = myOwningActor.vWorldPos;
                    }

                    //Clear my target if i'm too far from the leash, and try to find a closer one
                    if (myCombatTarget != null)
                    {
                        float fDistToTarget = (myCombatTarget.GetTargetingPosition() - myOwningActor.GetTargetingPosition()).sqrMagnitude;
                        if (fDistToTarget > (4 * (fLeashLength * fLeashLength)))
                        {
                            myCombatTarget = null;
                        }
                    }
                }
                break;

            case EAICombatMovementBehavior.stay_near_anchor_point:
                //if we are within our leash length, chase the combat target, otherwise stay in bounds
                Vector2 vToAnchor = vAnchorPosition - (Vector2)myOwningActor.vWorldPos;

                if (myCombatTarget == null || vToAnchor.SqrMagnitude() > fLeashLength * fLeashLength)
                {
                    vGoalLocation = vAnchorPosition;
                }
                else if (myCombatTarget != null)
                {
                    vGoalLocation = myCombatTarget.vWorldPos;
                }
                break;
            case EAICombatMovementBehavior.destroy_landmarks:
                if (myLandmarkTarget != null)
                {
                    vGoalLocation = myLandmarkTarget.vWorldPos;
                }
                break;
        }

        return true;

    }

    public override ECreatureAIState TakeAction(ECreatureAIState myState)
    {
        //do I have a target? I should try to get one
        if (myCombatTarget == null ||
            myCombatTarget.IsDead())
        {
            LDCombatComponent closest = theGame.theAIManager.GetClosestTarget(myOwningActor.Faction, 120f, myOwningActor.vWorldPos, CanTargetNonCombatants);
            if (closest != null)
            {
                myCombatTarget = closest.GetComponent<LDGameActor>();
            } 
        }

        if (CombatBehavior == EAICombatMovementBehavior.destroy_landmarks &&
            (myLandmarkTarget == null || myLandmarkTarget.IsDead()))
        {
            //find a new one
            myLandmarkTarget = theGame.theAIManager.GetNearestLandmark(myOwningActor.GetTargetingPosition());
        }

        //continue to figure out where to go
        FigureOutWhereToGo();

        //if I have something to shoot at, try shooting it
        if (myCombatTarget != null)
        {
            Vector3 vToTarget = myCombatTarget.GetTargetingPosition() - myOwningActor.GetTargetingPosition();
            vToTarget.z = 0;
            float fDeltaToTarget = vToTarget.sqrMagnitude;
            vToTarget.Normalize();
            
            for (int t = 0; t < WeaponsToFire.Count; t++)
            {
                TM_Weapon wep = WeaponsToFire[t];
                wep.transform.up = vToTarget;

                if (fDeltaToTarget < FiringRange * FiringRange)
                {
                    wep.StartBurst();
                }
            }
        }


        return myState;
    }

    public override void SetAnchorActor(LDGameActor anchor, float leash = 0f)
    {
        myAnchor = anchor;
        if (leash == 0f)
        {
            leash = LeashRangeIfAttached;
        }

        fLeashLength = leash;
    }


    public void SetOwningActor(LDGameActor owningActor)
    {
        myOwningActor = owningActor;
    }

    public void SetAnchorPosition(Vector2 vAnchor, float fMaxDistance )
    {
        vAnchorPosition = vAnchor;
        fLeashLength = fMaxDistance;
    }

    public override LDGameActor GetTargetActor()
    {
        return myCombatTarget;
    }

    public LDGameActor GetLandmarkTarget()
    {
        return myLandmarkTarget;
    }
}
