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

public class TRexGameState : SceneState {
    private List<Scenarios> playableScenarios = new List<Scenarios>();
    private List<Scenarios> playedScenarios = new List<Scenarios>();

    private float ScenarioLength = 60;

    private HUDGUIState hudGUI;
    private LoadNewScenarioController loadScenario;
    private RexController rexController;
    private GameObject pickerBase;
    private ElementPicker picker;
    private CurtainManager curtains;
    private PlayerController playerController;
    private Clock clock;

    private List<string> crowdClips;

    public override void Initialize() {
        GameAccesPoint.Instance.tRexState = this;
        selectedScene = "TRexGameScene";

        crowdClips = new List<string>() {
            "crowd_ahh",
            "crowd_ohh",
            "crowd_ooo",
            "crowd_wow"
        };

        curtains = FindObjectOfType<CurtainManager>();
        curtains.Initialize();
        curtains.Close(false);
        clock = GameObject.Find("r_Clock").GetComponent<Clock>();
        clock.Hide(false);

        pickerBase = GameObject.Find("r_PickerBase");
        picker = pickerBase.FindChildComponentByName<ElementPicker>("r_Picker");
        picker.OnPick += OnIndexPicked;
        pickerBase.transform.localScale = Vector3.zero;
        LeanTween.scale(pickerBase, Vector3.one, 0.06f).setEase(LeanTweenType.easeInCubic).setDelay(0.5f).setOnComplete(OnPickerShow);
        
        rexController = FindObjectOfType<RexController>();
        rexController.UpdateEnabled = false;
        playerController = rexController.GetComponent<PlayerController>();
        playerController.Initialize();

        Array scenarios = Enum.GetValues(typeof(Scenarios));

        foreach (Scenarios scen in scenarios) {
            playableScenarios.Add(scen);
        }

        hudGUI = new HUDGUIState();
        loadScenario = new LoadNewScenarioController();

        hudGUI.Initialize();
        loadScenario.Initialize(hudGUI);

        AudioManager.Instance.Play("BackgroundSound", 1f, true);

        isInit = true;
    }

    private void OnPickerShow() {
        picker.Pick();
    }
    
    private void OnIndexPicked(int index) {
        LeanTween.scale(pickerBase, Vector3.zero, 0.06f).setEase(LeanTweenType.easeOutCubic).setOnComplete(OnPickerDone);
        playerController.OnIndexPicked(index);
    }

    private void OnPickerDone() {
        NewScenario();
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.R)) {
            NewScenario();
        }
    }

    private void NewScenario() {
        if (!isActive) {
            return; }

        StartCoroutine(DoScenarioTransition());
    }

    private void OnTimerFinish() {
        clock.onFinish -= OnTimerFinish;
        OnScenarioFinish(false);
    }

    private void OnScenarioFinish(bool success) {
        if (success) {
            AudioManager.Instance.Play(crowdClips[UnityEngine.Random.Range(0, crowdClips.Count)], 1f, false);
        } else {
            AudioManager.Instance.Play("ScenarioFailed", 1f, false);
        }

        clock.Stop();
        clock.Hide();
        NewScenario();
    }

    private IEnumerator DoScenarioTransition() {
        yield return new WaitForSeconds(1f);
        curtains.Close();
        yield return new WaitForSeconds(1f);
        loadScenario.ClearOldScenario();

        rexController.UpdateEnabled = false;

        clock.onFinish += OnTimerFinish;

        yield return new WaitForSeconds(1f);

        Scenarios scenario = playableScenarios[UnityEngine.Random.Range(0, playableScenarios.Count)];
        List<GameObject> loadedObjects = loadScenario.LoadNewScenario(scenario);

        // Activate the scenario object
        foreach (GameObject obj in loadedObjects) {
            ScenarioObject scenarioObj = obj.GetComponentInChildren<ScenarioObject>();

            if (scenarioObj == null) {
                continue;
            }

            scenarioObj.OnScenarioFinish += OnScenarioFinish;

            scenarioObj.Start();
        }


        playedScenarios.Add(scenario);
        playableScenarios.Remove(scenario);

        if (playableScenarios.Count <= 0) {
            foreach (Scenarios scen in playedScenarios) {
                playableScenarios.Add(scen);
            }
            playedScenarios.Clear();
        }


        clock.Show();
        yield return new WaitForSeconds(1f);
        curtains.Open();
        rexController.UpdateEnabled = true;

        clock.StartClock(ScenarioLength);
        yield return new WaitForSeconds(1f);
    }
}
