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

public class Campfire : MonoBehaviour {
    public GameState GameState;
    public Light DynamicLight;
    public Flame Flame;
    public CampfireSfx Sfx;
    public float GoodFuelAmount;
    [Tooltip("The light turns this color when Fuel < GoodFuelAmount. Otherwise it'll be as it is in the editor.")]
    public Color TooLowFuelColor;
    public float RandomVarianceDuration;
    public float RandomVarianceMagnitude;
    [Tooltip("How long of a break the campfire takes between eating logs, if multiple are placed on it.")]
    public float LogBurningCooldown;

    [Header("Runtime values")]
    public float Fuel;
    public float TimeToEnd {
        get {
            return Fuel - 0.7f;
        }
    }

    private Color EnoughFuelColor;
    private float FullRange;

    private float RandomVariance = 0;
    private float NextRandomVariance = 0;
    private float LastRandomVarianceChange = 0;

    private List<Item> LogQueue = new List<Item>();
    private float LastLogBurned = 0;

    private void Awake() {
        EnoughFuelColor = DynamicLight.color;
        FullRange = DynamicLight.range;
    }

    private void Update() {
        if (LogQueue.Count > 0 && Time.time - LastLogBurned > LogBurningCooldown) {
            LastLogBurned = Time.time;
            if (BurnLog(LogQueue[0])) {
                LogQueue.RemoveAt(0);
            }
        }

        if (Time.time - LastRandomVarianceChange > RandomVarianceDuration) {
            NextRandomVariance = (Random.value - 0.5f) * 2f * RandomVarianceMagnitude;
            LastRandomVarianceChange = Time.time;
        }
        RandomVariance = Mathf.Lerp(RandomVariance, NextRandomVariance, (Time.time - LastRandomVarianceChange) / RandomVarianceDuration);

        Fuel = Mathf.Max(0, Fuel - Time.deltaTime);
        DynamicLight.range = Fuel / GoodFuelAmount / 2f * FullRange + RandomVariance;
        DynamicLight.color = Color.Lerp(DynamicLight.color, Fuel < GoodFuelAmount ? TooLowFuelColor : EnoughFuelColor, 10f * Time.deltaTime);
        Flame.Aliveness = Mathf.Log(Mathf.Max(0.01f, TimeToEnd), 10) / 2f;

        if (Fuel <= 0) {
            GameState.Current = State.GameOver;
        }
    }

    private bool BurnLog(Item burnable) {
        if (Fuel >= GoodFuelAmount * 2) {
            return false;
        } else {
            Fuel += burnable.Quality.FuelValue * Mathf.Max(0.5f, (2 - Fuel / GoodFuelAmount));
            Destroy(burnable.gameObject);
            return true;
        }
    }

    private void OnCollisionEnter(Collision c) {
        if (c.collider.attachedRigidbody != null && c.collider.attachedRigidbody) {
            Item Burnable = c.collider.attachedRigidbody.GetComponent<Item>();
            if (Burnable != null && !LogQueue.Contains(Burnable)) {
                Flame.AddFuelEffect += Burnable.Quality.FlameEffect;
                Sfx.ActiveBurn += Burnable.Quality.SoundEffect;
                LogQueue.Add(Burnable);
            }
        }
    }

    private void OnCollisionExit(Collision c) {
        if (c.collider.attachedRigidbody != null && c.collider.attachedRigidbody) {
            Item Burnable = c.collider.attachedRigidbody.GetComponent<Item>();
            if (Burnable != null) {
                LogQueue.Remove(Burnable);
            }
        }
    }
}
