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

public class LevelController : MonoBehaviour
{
	public int day = 1;
	public int graveSpawnMultiplier = 5;
	public int initialGravestoneRange = 10;
    public float gravestoneY = -1.92f;
    public float fighterZombieY = -1.92f;
    public int maxRandomMobSounds = 5;
	public Transform[] graveStoneSource;
    public Transform fighterZombieSource;
    public int graveStoneSpawnChance = 40;
    public AudioSource[] knightBattleCry;

    private int currentRandomSounds;

    void Awake()
    {
        currentRandomSounds = 0;
        EventManager.SubscribeSpawnFighterZombie(SpawnFighterZombie);
        EventManager.SubscribeSeekEnemy(SeekEnemy);
        EventManager.SubscribeMobRandomSoundRequest(CheckRandomMobSoundLimit);
        EventManager.SubscribeMobRandomSoundComplete(CompleteRandomMobSound);
        EventManager.SubscribeMobDeath(HandleKnightDeath);
        EventManager.SubscribeSunrise(FireRandomKnightBattleCry);
    }

    void CheckRandomMobSoundLimit(MobBase mob)
    {
        if (currentRandomSounds < maxRandomMobSounds)
        {
            mob.PlayRandomSound();
            currentRandomSounds++;
        }
    }

    void CompleteRandomMobSound()
    {
        currentRandomSounds--;
    }

    void FireRandomKnightBattleCry()
    {
        System.Random rnd = new System.Random();
        int cryIndex = rnd.Next(knightBattleCry.Length);
        knightBattleCry[cryIndex].Play();
    }

    void HandleKnightDeath(float xPosition, LevelObjectFaction faction)
    {
        //Place a gravestone maybe
        if (faction == LevelObjectFaction.Human) 
        {
            System.Random rnd = new System.Random();
            if (rnd.Next(100) < graveStoneSpawnChance)
            {
                //Make sure new gravestone can't spawn on tower
                if (xPosition < 0.0f && xPosition > -3.0f)
                {
                    xPosition = -3.0f;
                }
                else if (xPosition < 3.0f && xPosition >= 0.0f)
                {
                    xPosition = 3.0f;
                }
                int graveStoneChoice = rnd.Next(graveStoneSource.Length);
                Transform obj = Instantiate(graveStoneSource[graveStoneChoice], new Vector3(xPosition, gravestoneY, 0), Quaternion.identity);
                obj.transform.parent = transform;
            }
        }
    }

    void SeekEnemy(FighterZombie zombie)
    {
        GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
        float zombieX = zombie.transform.position.x;
        GameObject closestEnemy = null;
        float closestDistance = 10000.0f;
        foreach (GameObject enemy in enemies)
        {
            if (System.Math.Abs(enemy.transform.position.x - zombieX) < closestDistance)
            {
                closestEnemy = enemy;
                closestDistance = System.Math.Abs(enemy.transform.position.x - zombieX);
            }
        }

        zombie.SearchComplete(closestEnemy);
    }

    void SpawnFighterZombie()
    {
        Transform zombie = Instantiate(fighterZombieSource, new Vector3(0, fighterZombieY, 0), Quaternion.identity);
        zombie.transform.parent = transform;
    }

    void Start()
    {
    	System.Random rnd = new System.Random();
    	int spawnSide = 1;
        Transform obj = null;
        int graveStoneChoice;
    	for (int i = 0; i < graveSpawnMultiplier; i++) {
            graveStoneChoice = rnd.Next(graveStoneSource.Length);
            obj = Instantiate(graveStoneSource[graveStoneChoice], new Vector3(rnd.Next(3, initialGravestoneRange) * spawnSide, gravestoneY, 0), Quaternion.identity);
            obj.transform.parent = transform;
            spawnSide = spawnSide * -1;
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    internal void InitializeLevel()
    {
        //throw new NotImplementedException();
    }
}
