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

namespace LiveOpsExamples
{
  /// <summary>
  /// Spawns collectible snacks at random positions inside the configured bounds,
  /// picking a random collectible slug (moonberry/acorn/star/snack) and applying
  /// its sprite from the library. Mirrors GameScene.spawnCollectible.
  ///
  /// Phaser spawn margins x∈[115,1165], y∈[118,625] px on a 1280×720 field at
  /// 100 PPU map to x∈[-5.25,5.25], y∈[-2.65,2.42] world units (y is flipped).
  /// </summary>
  public class SnackSpawner : MonoBehaviour
  {
    private static readonly string[] CollectibleSlugs = { "moonberry", "acorn", "star", "snack" };

    [SerializeField] private Snack prefab;
    [SerializeField] private CozyCollectorSpriteLibrary library;
    [SerializeField] private Vector2 spawnMin = new Vector2(-5.25f, -2.65f);
    [SerializeField] private Vector2 spawnMax = new Vector2(5.25f, 2.42f);
    [SerializeField] private Transform parent;

    private readonly List<Snack> _spawned = new List<Snack>();

    public SpriteRenderer Player { get; set; }

    public event Action<Snack> Collected;

    public Snack Spawn()
    {
      var slug = CollectibleSlugs[UnityEngine.Random.Range(0, CollectibleSlugs.Length)];
      var position = new Vector3(
        UnityEngine.Random.Range(spawnMin.x, spawnMax.x),
        UnityEngine.Random.Range(spawnMin.y, spawnMax.y),
        0f);

      var snack = Instantiate(prefab, position, Quaternion.identity, parent);
      var sprite = library.ForSlug(slug);
      snack.GetComponent<SpriteRenderer>().sprite = sprite;
      // Phaser setDisplaySize(52, 52) at 100 PPU -> 0.52 x 0.52 world units.
      var spriteBounds = sprite.bounds.size;
      var scale = new Vector3(0.52f / spriteBounds.x, 0.52f / spriteBounds.y, 1f);
      snack.transform.localScale = scale;
      // The prefab collider radius is tuned to snack.png; a circle collider's
      // world radius scales by the largest transform axis, so retune per sprite.
      snack.GetComponent<CircleCollider2D>().radius = 0.22f / Mathf.Max(scale.x, scale.y);
      snack.Player = Player;
      snack.Collected += OnSnackCollected;
      _spawned.Add(snack);
      return snack;
    }

    public void Clear()
    {
      foreach (var snack in _spawned)
      {
        if (snack == null)
          continue;

        snack.Collected -= OnSnackCollected;
        Destroy(snack.gameObject);
      }

      _spawned.Clear();
    }

    private void OnSnackCollected(Snack snack)
    {
      snack.Collected -= OnSnackCollected;
      _spawned.Remove(snack);
      Collected?.Invoke(snack);
    }
  }
}
