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

public class NetworkedProjectile : MonoBehaviour
{
    [Header("Visuals")]
    [SerializeField] private GameObject hitParticlesPrefab;
    [SerializeField] private GameObject visuals;

    [Header("Set by code")]
    public PhotonView photonView;
    public PhotonView owner;
    public Taggable ownerTag;
    public ProjectileAbility ability;
    public float speed;
    public float lifeSpan;
    public bool canPierce;
    public bool canHitSelf;

    private PhotonView possibleTarget;
    private Taggable target;

    private bool waitingForDestroy = false;

    public UnityEvent<Vector3> onTargetHit = new UnityEvent<Vector3>();

    private List<GameObject> hitSpawnedVFXs = new List<GameObject>();
    private GameObject hitSpawnedVFX;
    private Vector3 hitPositionCorrected;

    NetworkedAntiProjectile possibleBlock;

    private void Awake()
    {
        photonView = GetComponent<PhotonView>();
        onTargetHit.AddListener(SpawnHitParticleVFX);
    }
    public void Init()
    {
        waitingForDestroy = false;

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

            StartCoroutine(SelfDestruct());
        }
    }

    [PunRPC]
    private void RPC_RemoteInit(int abilityIndex)
    {
        ability = (ProjectileAbility)AbilityIndexer.Instance.Abilities[abilityIndex];
    }
    [PunRPC]
    private void RPC_DisableVisuals()
    {
        visuals.SetActive(false);
    }

    private void SpawnHitParticleVFX(Vector3 position)
    {
        if (hitParticlesPrefab == null) return;

        hitSpawnedVFX = Instantiate(hitParticlesPrefab, position, this.transform.rotation);
        //hitSpawnedVFX.transform.localScale = visuals.transform.localScale;

        hitSpawnedVFXs.Add(hitSpawnedVFX);
    }

    private void Update()
    {
        if (!photonView.IsMine) return;

        if (waitingForDestroy) return;

        this.transform.position += this.transform.forward * speed * Time.deltaTime;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (waitingForDestroy) return;

        possibleTarget = other.GetComponentInParent<PhotonView>();
        if (possibleTarget != null)
        {
            if (!canHitSelf)
                if (possibleTarget == owner) return;
        }

        target = other.GetComponentInParent<Taggable>();

        if (target == null) return;

        if (!target.IsValidTarget(ability.targettingTags)) return;

        hitPositionCorrected = target.transform.position;
        hitPositionCorrected.y = this.transform.position.y;
        onTargetHit.Invoke(hitPositionCorrected);

        if (!photonView.IsMine) return;

        possibleBlock = target.GetComponentInParent<NetworkedAntiProjectile>();
        if (possibleBlock != null)
        {
            waitingForDestroy = true;

            possibleBlock.SendBlockNotice();

            StartCoroutine(DelayedDestroy());
            return;
        }

        foreach (BaseEffect effect in ability.abilityEffects)
        {
            effect.ApplyEffect(ownerTag, new List<Taggable> { target });
        }

        if (!canPierce)
        {
            waitingForDestroy = true;
            StartCoroutine(DelayedDestroy());
        }
    }

    IEnumerator SelfDestruct()
    {
        yield return new WaitForSeconds(lifeSpan);

        waitingForDestroy = true;

        StartCoroutine(DelayedDestroy());
    }


    IEnumerator DelayedDestroy()
    {
        visuals.SetActive(false);

        photonView.RPC(nameof(RPC_DisableVisuals), RpcTarget.Others);

        yield return new WaitForSeconds(1.5f);



        for (int i = hitSpawnedVFXs.Count - 1; i >= 0; i--)
        {
            if (hitSpawnedVFXs[i] != null)
            {
                Destroy(hitSpawnedVFXs[i]);
            }
        }

        yield return new WaitForSeconds(1f);

        PhotonNetwork.Destroy(photonView);
    }
}
