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

public sealed class ScalablePlanetsView : MonoBehaviour
{
    [SerializeField]
    private GameObject planetPrefab = null;
    [SerializeField]
    private Camera controlCamera = null;
    [SerializeField]
    private float distance = 10;
    [SerializeField]
    private float objectsDelta = 1;

    private List<ObjectParams> planets = new List<ObjectParams>();

    public sealed class ObjectParams {
        public GameObject Planet;
        public Vector3 Position;
        public float Radius;
        public float Distance;
    }

    private List<(Vector3 position, float radius)> positions = new List<(Vector3 position, float radius)>() {
        (Vector3.forward * 5, 1),
        (Vector3.back * 7, 2),
        (Vector3.left * 5, 1),
        (Vector3.right * 6, 3),
        (Vector3.forward * 10, 2),
        (Vector3.back * 12, 2),
        (Vector3.left * 16, 4),
        (Vector3.right * 18, 3)
    };

    private void Start()
    {
        foreach (var position in positions)
        {
            planets.Add(new ObjectParams()
            {
                Planet = CreatePlanet(position.position, position.radius),
                Position = position.position,
                Radius = position.radius,
                Distance = distance
            });
        }
    }

    private void Update()
    {
        var cameraPosition = controlCamera.transform.position;
        var globalPosition = transform.position;
        foreach (var obj in planets)
        {
            var delta = cameraPosition - (obj.Position + globalPosition);
            obj.Distance = delta.magnitude;
        }
        planets.Sort((a, b) => a.Distance.CompareTo(b.Distance));

        for (var i = 0; i < planets.Count; i++)
        {
            var planet = planets[i];
            var sortedDistance = distance + i * objectsDelta;
            SetPlanetPosition(cameraPosition, globalPosition, planet.Planet.transform, planet.Position, planet.Radius, sortedDistance);
        }
    }

    private void SetPlanetPosition(Vector3 cameraPosition, Vector3 globalPosition, Transform planetTransform, Vector3 position, float radius, float sortedDistance)
    {
        var resultPosition = globalPosition + position;
        var delta = cameraPosition - resultPosition;
        var actualDistance = delta.magnitude;
        var scaledDelta = delta.normalized * sortedDistance;
        var scaledRadius = radius / actualDistance * sortedDistance;
        planetTransform.position = cameraPosition - scaledDelta;
        planetTransform.localScale = Vector3.one * scaledRadius;
    }

    private GameObject CreatePlanet(Vector3 position, float radius)
    {
        var planet = Instantiate(planetPrefab, transform);
        planet.transform.localPosition = position;
        planet.transform.localScale = Vector3.one * radius;
        return planet;
    }
}
