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

public sealed class NavPointSpaceView : MonoBehaviour
{
    [SerializeField]
    private StantionViewsProvider stantionViewsProvider = null;
    [SerializeField]
    private ShipViewProvider shipViewProvider = null;
    [SerializeField]
    private List<SpaceStantionView> stantions = new List<SpaceStantionView>();
    [SerializeField]
    private List<ShipView> ships = new List<ShipView>();

    public NavigationPoint Current { get; private set; } = null;

    public IInteractableObjectView GetView(IInteractableObject interactable) {
        return
            stantions.FirstOrDefault(stantionView => stantionView.Stantion == interactable) as IInteractableObjectView ??
            ships.FirstOrDefault(shipView => shipView.Ship == interactable) as IInteractableObjectView;
    }

    public void GenerateObjects(NavigationPoint point)
    {
        if (point == Current || point == null)
            return;
        Current = point;
        name = $"nav_point_{point.Id}";
        ClearStantions();
        foreach (var stantion in Current.Stantions)
        {
            stantions.Add(CreateStantion(stantion));
        }
        ClearShips();
        foreach (var ship in Current.Ships)
        {
            ships.Add(CreateShip(ship));
        }
    }

    private ShipView CreateShip(StarShip ship)
    {
        var shipView = shipViewProvider.CreateShipView(ship.Equipment.Ship.Blueprint.Id, this.transform);
        shipView.Init(ship);
        return shipView;
    }

    private SpaceStantionView CreateStantion(SpaceStantion stantion)
    {
        var obj = Instantiate(stantionViewsProvider.GetViewPrefab(stantion.TypeId), transform);
        obj.Init(stantion);
        return obj;
    }

    public IInteractableObject Raycast(Ray ray)
    {
        if (Physics.Raycast(ray, out var hit))
        {
            var view = hit.collider.GetComponent<IInteractableObjectView>();
            if (view != null)
                return view.GetInteractableObject();
        }
        return null;
    }

    private void ClearShips()
    {
        ships.ForEach(ship => Destroy(ship.gameObject));
        ships.Clear();
    }

    private void ClearStantions()
    {
        stantions.ForEach(stantion => Destroy(stantion.gameObject));
        stantions.Clear();
    }
}
