using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NetworkedAreaOfEffectOverTime : NetworkedAreaOfEffect
{
    public float duration;
    public bool followUser;
    public bool followTarget;
    public bool damageFollowingTarget;

    private float endTime;

    private Taggable followingTargetTaggable;

    public override void Init()
    {
        if (photonView.IsMine)
        {
            //resizedByAbility.x = radius * 2;
            //resizedByAbility.y = radius * 2;
            //resizedByAbility.z = radius * 2;
            //
            ////telegraph.transform.localScale = resizedByAbility;
            //effectVisual.transform.localScale = resizedByAbility;

            photonView.RPC(nameof(RPC_RemoteInit), RpcTarget.Others, AbilityIndexer.Instance.Abilities.IndexOf(ability));

            ApplyArea();

            if (followUser)
                StartCoroutine(FollowTransform(owner.transform));
        }
    }

    public void Init(Transform target)
    {
        if (photonView.IsMine)
        {
            photonView.RPC(nameof(RPC_RemoteInit), RpcTarget.Others, AbilityIndexer.Instance.Abilities.IndexOf(ability));

            ApplyArea();

            if (followTarget)
            {
                followingTargetTaggable = target.GetComponentInParent<Taggable>();
                StartCoroutine(FollowTransform(target));
            }
        }
    }

    IEnumerator FollowTransform(Transform target)
    {
        while (Time.time < endTime)
        {
            this.transform.position = target.position;
            yield return new WaitForEndOfFrame();
        }

        effectVisual.SetActive(false);
    }

    [PunRPC]
    protected override void RPC_RemoteInit(int abilityIndex)
    {
        ability = (AreaOfEffectOverTimeAbility)AbilityIndexer.Instance.Abilities[abilityIndex]; // TODO: change casting to areaofeffectovertimeability
    }

    protected override IEnumerator ApplyTelegraphDelay(float delay)
    {
        return base.ApplyTelegraphDelay(delay);
    }

    protected override void ApplyArea()
    {
        effectVisual.SetActive(true);

        StartCoroutine(ApplyAreaOverTime());
    }

    private IEnumerator ApplyAreaOverTime()
    {
        endTime = Time.time + duration;
        while (Time.time < endTime)
        {
            yield return new WaitForSeconds(0.5f);
            CheckSurroundings();
        }

        StartCoroutine(SelfDestruct());
    }

    protected override void CheckSurroundings()
    {
        //TODO: spread the total value over ticks, for now just apply the instant effect every tick, manage tick values on effect applied
        hits = Physics.OverlapSphere(this.transform.position, radius, abilityHitLayer);
        targets.Clear();
        foreach (Collider collider in hits)
        {
            // Debug.Log("hit collider " + collider.name);

            possibleTarget = collider.GetComponentInParent<PhotonView>();
            if (possibleTarget != null)
                if (possibleTarget == owner && !canHitSelf) continue;

            target = collider.GetComponentInParent<Taggable>();

            //Debug.Log("hit collider, Got taggable: " + target.name);

            if (target == null) continue;

            if (followTarget && !damageFollowingTarget && target == followingTargetTaggable) return;

            //Debug.Log("hit collider, targetTag: " + target.targetTag.name);

            /*foreach (TargetTag tag in ability.targettingTags)
            {
                Debug.Log("hit collider, ability.Tags: " + tag);
            }*/
            if (!target.IsValidTarget(ability.targettingTags)) continue;

            Debug.Log("hit collider, added target: " + target.name);
            targets.Add(target);

        }

        foreach (BaseEffect effect in ability.abilityEffects)
        {
            effect.ApplyEffect(ownerTag, targets);
        }
    }
}
