using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering.Universal;

public sealed class WeaponBehaviour : MonoBehaviour
{
	[SerializeField]
	private List<Weapon> weapons = new List<Weapon>();
	[SerializeField]
	private int weaponIndex = 0;
	[SerializeField]
	private LineRenderer shotRangeRenderer;
	public LayerMask shotBlockMask;

	[SerializeField]
	private ParticleSystem bulletParticle;

	public Action<Enemy> OnAttack { get; private set; }
	public Action OnReload { get; private set; }

	public Weapon weapon { get { return weapons[weaponIndex]; } }

	private float shotRadius = 0;

	[SerializeField]
	private Light2D gunFireLight;


	private void Start()
	{
		for (int i = 0; i < weapons.Count; i++)
		{
			weapons[i] = Instantiate(weapons[i]);
		}
		ChangeWeapon(weaponIndex);
	}

	private void Update()
	{
		weapon.UpdateWeapon(Time.deltaTime);
		gunFireLight.intensity = Mathf.Max(0, gunFireLight.intensity - 50 * Time.deltaTime);
	}

	public void Init(Weapon weapon)
	{
		weapon.Init(this);
		OnAttack = weapon.OnAttack;
	}

	public void ChangeWeapon(int index)
	{
		if (index >= weapons.Count)
		{
			Debug.LogError("Index out of bounds");
			return;
		}
		Init(weapons[index]);
	}

	public void EmitBulletParticle()
	{
		bulletParticle.Emit(1);
		gunFireLight.intensity = 3;
	}

	public void DrawWeaponRange()
	{
		shotRadius = Mathf.Min(weapon.shotRange, shotRadius + weapon.shotRange * Time.deltaTime);
		Vector3[] vertices = new Vector3[361];
		for (int i = 0; i < 360; i++)
		{
			Vector2 direction = (Quaternion.Euler(0, 0, i) * Vector2.right).normalized;
			RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, shotRadius, shotBlockMask);

			if (hit.collider != null)
				vertices[i] = hit.point;
			else
				vertices[i] = transform.position + new Vector3(direction.x, direction.y) * shotRadius;
		}
		vertices[360] = vertices[0];

		shotRangeRenderer.SetPositions(vertices);
	}

	public void OnSelected()
	{
		shotRadius = 0;
		shotRangeRenderer.enabled = true;
	}

	public void OnUnselected()
	{
		shotRangeRenderer.enabled = false;
	}

	public bool IsAttackable(Enemy enemy)
	{
		return !(Vector2.Distance(transform.position, enemy.transform.position) > weapon.shotRange) &&
			!Physics2D.Linecast(transform.position, enemy.transform.position, shotBlockMask);
	}
}
