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

public class Monster {
    public Transform transform;
    public Rigidbody2D body;
    public Vector2i lastCoord = new Vector2i(1000000, 1000000); // prob wont be this right? lol
    public Vector3 target;
    public float lastCalcTime = 0.0f;
    public SpriteRenderer sr;
    float timer = 0.0f;
    float yoff = 0.0f;
    float xx = 0.0f;

    public Monster(GameObject go, Sprite sprite) {
        transform = go.transform;
        body = go.GetComponent<Rigidbody2D>();
        sr = go.GetComponentInChildren<SpriteRenderer>();
        sr.sprite = sprite;
        sr.color = Random.ColorHSV(0, 1, 0, 1, .3f, .6f, 1, 1);
    }

    const float topSpeed = 1.5f;
    public void Move(float delta) {
        body.AddForce((target - transform.position).normalized * 10.0f);
        float mag = body.velocity.magnitude;
        if (mag > topSpeed) {
            body.velocity = body.velocity.normalized * topSpeed;
        }

        timer += delta * 20.0f;
        yoff = (Mathf.Sin(timer) + 1.0f) * .1f;
        xx = Mathf.Sin(timer / 2.0f);

        // up and down
        var p = sr.transform.localPosition;
        p.y = yoff;
        sr.transform.localPosition = p;
        // side to side
        Vector3 newup = Vector3.up + Vector3.right * xx * .3f;
        sr.transform.up = newup;
    }
}

public class MonsterManager : MonoBehaviour {
    public Game game;
    public GameObject MonsterPrefab;
    public Transform monsterParent;
    public Sprite[] monsterSprites;

    List<Monster> monsters = new List<Monster>();

    TheGrid theGrid;
    // Start is called before the first frame update
    void Start() {
        theGrid = GetComponent<TheGrid>();

        Initialize();
    }

    void SpawnMonster(float x, float y) {
        var go = Instantiate(MonsterPrefab, new Vector3(x, y, 0.0f), Quaternion.identity, monsterParent);
        monsters.Add(new Monster(go, monsterSprites[Random.Range(0, monsterSprites.Length)]));
    }

    public void SpawnMonsterRandom(int count) {
        for (int i = 0; i < count; ++i) {
            SpawnMonster(Random.Range(0.5f, TheGrid.WIDTH - 0.5f), TheGrid.HEIGHT + 1);
        }
    }

    public void Initialize() {
        for (int i = 0; i < monsters.Count; ++i) {
            if (monsters[i] != null && monsters[i].transform && monsters[i].transform.gameObject) {
                Destroy(monsters[i].transform.gameObject);
            }
        }
        monsters.Clear();
        spawnInterval = 5.0f;
        spawnTimer = 2.0f;
    }

    float spawnInterval;
    float spawnTimer;
    // Update is called once per frame
    void FixedUpdate() {
        spawnTimer -= Time.deltaTime;
        spawnInterval -= Time.deltaTime * Time.deltaTime; // maybe try *= .99f
        if (spawnInterval < 0.05f) {
            spawnInterval = 0.05f;
        }
        if (spawnTimer < 0.0f) {
            SpawnMonsterRandom(1);
            spawnTimer += spawnInterval;
            //Debug.Log(spawnInterval);
        }

        for (int i = 0; i < monsters.Count; ++i) {
            if (monsters[i] == null || monsters[i].transform == null) {
                continue;
            }
            var monster = monsters[i];
            Vector3 pos = monster.transform.position;
            Vector2i v = theGrid.GetGridCoord(pos);
            if (v != monster.lastCoord || monster.lastCalcTime < Time.time - 1.0f) {
                monster.lastCoord = v;
                monster.target = theGrid.GetPathTarget(pos);
                monster.lastCalcTime = Time.time;
            }
            monster.Move(Time.deltaTime);
            // if monster is off bottom of screen then delete it off list
            if (monster.transform.position.y < -2) {
                game.Lives--;

                Destroy(monster.transform.gameObject);
                monsters[i] = monsters[monsters.Count - 1];
                monsters.RemoveAt(monsters.Count - 1);
                i--; // undo for loop inc cuz new monster to check at this i now
            }
        }
    }

    //private void OnDrawGizmos() {
    //    foreach (Monster monster in monsters) {
    //        Gizmos.color = Color.green;
    //        Gizmos.DrawWireSphere(monster.target, 0.1f);
    //    }
    //}
}
