using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.InputSystem;
using UnityEngine.UI;


public class NPC : Interactable
{
    public GameObject dialogueBox;
    public GameObject buttons;
    public GameObject button;
    public TextMeshProUGUI dialogueText;
    public Transform player;
    public InputActionReference interact;
    public bool dialogueStarted;
    public bool typing;
    public Queue<DialogueSentence> sentences = new Queue<DialogueSentence>();
    public DialogueBranch dialogueBranch;
    public DialogueSentence currentDialogueSentence;
    public int branchesDone = 0;

    void OnEnable()
    {
        interact.action.started += Interact;
    }
    void OnDisable()
    {
        interact.action.started -= Interact;
    }
    
    public void Interact(InputAction.CallbackContext obj)
    {
        if(!playerInRange) 
        {
            return;
        }
        if(!dialogueStarted)
        {
            StartDialogue();
        }
        else if(dialogueStarted)
        {
            ContinueDialogue();
        }
    }

    public void StartDialogue()
    {
        sentences.Clear();
        foreach(DialogueSentence dialogueSentence in dialogueBranch.dialogues[branchesDone].sentences)
        {
            sentences.Enqueue(dialogueSentence);
        }
        dialogueBox.SetActive(true); 
        player.gameObject.GetComponent<PlayerMovement>().animator.SetBool("Moving", false);
        player.gameObject.GetComponent<PlayerMovement>().currentState = PlayerState.interact;
        dialogueStarted = true;
        
        ContinueDialogue();
    }

    public void ContinueDialogue()
    {
        if(sentences.Count == 0 && !typing)
        {
            // if last sentence and typing is over, end dialogue
            if(currentDialogueSentence.question)
            {
                DisplayChoices();
                return;
            }
            EndDialogue();
            return;
        }
        else if(sentences.Count == 0 && typing)
        { 
            //finish typing
            StopAllCoroutines();
            dialogueText.text = currentDialogueSentence.sentence;
            typing = false;
            return;
        }
        
        if(!typing)
        {
            //go to next sentence
            if(currentDialogueSentence.question)
            {
                DisplayChoices();
                return;
            }
            StopAllCoroutines();
            currentDialogueSentence = sentences.Dequeue();
            StartCoroutine(TypeSentence(currentDialogueSentence.sentence));
        }
        else
        { 
            //finish typing
            StopAllCoroutines();
            dialogueText.text = currentDialogueSentence.sentence;
            typing = false;
        }
    }

    public void DisplayChoices()
    {
        if(currentDialogueSentence.choices.Length == 2)
        {
            buttons.GetComponent<GridLayoutGroup>().spacing = new Vector2(0, 40);
        }
        else
        {
            buttons.GetComponent<GridLayoutGroup>().spacing = new Vector2(0, 10);
        }
        dialogueText.text = "";
        for(int i = 0; i < currentDialogueSentence.choices.Length; i++)
        {
            GameObject newChoice = Instantiate(button, new Vector2 (0, 0), Quaternion.identity);
            newChoice.transform.SetParent(buttons.transform, false);
            newChoice.GetComponentInChildren<TextMeshProUGUI>().text = currentDialogueSentence.choices[i].choice;
            int branchToSwitch = currentDialogueSentence.choices[i].branchToSwitch;
            newChoice.GetComponent<Button>().onClick.AddListener(() => SwitchBranch(branchToSwitch));
            if(i = 0)
            {
                eventSystem.firstSelected = newChoice;
            }
        }
    }

    public void SwitchBranch(int branch)
    {
        branchesDone = branch;
        while (buttons.transform.childCount > 0) 
        {
            DestroyImmediate(buttons.transform.GetChild(0).gameObject);
        }   
        currentDialogueSentence = new DialogueSentence();
        StartDialogue();
    }

    public IEnumerator TypeSentence(string sentence)
    {
        dialogueText.text = "";
        typing = true;
        foreach(char letter in sentence.ToCharArray())
        {
            dialogueText.text += letter;
            yield return new WaitForSeconds(1/30f);
        }
        typing = false;
    }

    public void EndDialogue()
    {
        dialogueBox.SetActive(false);
        player.gameObject.GetComponent<PlayerMovement>().currentState = PlayerState.idle;
        dialogueStarted = false;
        if(!dialogueBranch.dialogues[branchesDone].finalDialogue)
        {
            //if it is not the final dialogue go to the next one
            branchesDone++;
        }
    }
}