using System;
using UnityEngine;
using Random = UnityEngine.Random;

[SelectionBase]
public class ShipView : MonoBehaviour, IInteractableObjectView
{
    [SerializeField]
    private string id = String.Empty;
    [SerializeField]
    private ParticleSystem moveEffectSystem = null;
    [SerializeField]
    private float radius = 1;
    [SerializeField]
    private TextEffectController effectController = null;
    [SerializeField]
    private LaserEffectView laserEffect = null;
    [SerializeField]
    private EffectController hitEffectController = null;

    private bool isEffectShown = false;

    public float Radius => radius;
    public string Id => id;

    public StarShip Ship { get; private set; } = null;

    public IInteractableObject GetInteractableObject() => Ship;

    public void Fire(ShipView enemy)
    {
        var direction = (transform.position - enemy.transform.position).normalized;
        var start = enemy.transform.position + Random.insideUnitSphere * (enemy.radius * 0.5f) + direction * enemy.radius * 0.25f;
        var end = enemy.transform.position + Random.insideUnitSphere * (enemy.radius * 0.5f) + direction * enemy.radius * 0.25f;
        laserEffect.Show(start, end, true);
        enemy.hitEffectController.Spawn(start);
    }

    public void Miss(ShipView enemy)
    {
        var delta = transform.position - enemy.transform.position;
        var direction = delta.normalized;
        var angle = Random.Range(0, 360);
        var offsetStart = Quaternion.AngleAxis(angle, direction) * Vector3.up;
        var offsetEnd = Quaternion.AngleAxis(angle + Random.Range(-15, 15), direction) * Vector3.up;
        laserEffect.Show(enemy.transform.position + offsetStart * (enemy.radius * Random.Range(2f, 2.3f)) - delta, enemy.transform.position + offsetEnd * (enemy.radius * Random.Range(2f, 2.3f)) - delta, false);
    }

    public void Init(StarShip ship)
    {
        Ship = ship;
        transform.localPosition = ship.Position;
        transform.localRotation = ship.Rotation;
    }

    public void ShowMoveEffect(bool shown) {
        if (isEffectShown == shown)
            return;
        isEffectShown = shown;
        if (isEffectShown)
            moveEffectSystem.Play();
        else
            moveEffectSystem.Stop();
    }

    public void SetTransform(Vector3 position, Quaternion rotation)
    {
        transform.localPosition = position;
        transform.localRotation = rotation;
    }

    public void ShowTextEffect(string text, float time = 0.5f) {
        effectController.Spawn(text, time, transform.position, Vector3.up);
    }

#if UNITY_EDITOR
    [ContextMenu("find radius")]
    private void FindMinRadius()
    {
        var renderers = GetComponentsInChildren<MeshRenderer>();
        var maxRadius = 1f;
        foreach (var renderer in renderers)
        {
            maxRadius = Mathf.Max(maxRadius, renderer.bounds.size.x, renderer.bounds.size.y, renderer.bounds.size.z);
        }
        radius = maxRadius;
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.DrawWireSphere(transform.position, radius);
    }
#endif
}
