using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;

[Serializable]
public class NpcDialogueManager : MonoBehaviour
{
    [SerializeField]
    public string SpeakerName;

    [SerializeField]
    public MultiDialogue DialogueTemplate;

    /* We user object CLONED TO PREVENT overwritting changes in main object inassets */
    [SerializeField]
    public MultiDialogue Dialogue;

    // List<Key<dialogue No, dialogue step No>, Value : UnityEvent>
    public List<IndexValuePair<IndexValuePair<int, int>, UnityEvent>> EndactionEventList;

    public void Start()
    {
        Dialogue = Instantiate(DialogueTemplate);
        Dialogue.SetSpeakerName(SpeakerName);
    }

    public void Update() { }

    /// <summary>
    /// Function to invoke actions declared in manager on object from scene not onto asset
    /// 
    /// Used in Dialogue ScriptableObject Template
    /// </summary>
    /// <param name="dialogueIndex"></param>
    public void DialogueEndAction(int dialogueIndex)
    {
        GameObject.FindObjectsOfType<NpcDialogueManager>().Where(obj => obj.name == gameObject.name).First().GetComponent<NpcDialogueManager>().InvokeDialogueEndAction(dialogueIndex);
    }

    /// <summary>
    /// Function to invoke actions declared in manager (on current object)
    /// 
    /// Use this to invoke actions which we want to occured after specific Dialogue
    /// </summary>
    /// <param name="dialogueIndex"></param>
    protected void InvokeDialogueEndAction(int dialogueIndex)
    {
        EndactionEventList.Where(el => el.Key.Key == dialogueIndex).ToList().ForEach(el => el.Value.Invoke());
    }

    /// <summary>
    /// Function to invoke actions declared in manager on object from scene not onto asset
    /// 
    /// Used in Dialogue ScriptableObject Template
    /// </summary>
    public void StepEndAction()
    {
        GameObject.FindObjectsOfType<NpcDialogueManager>().Where(obj => obj.name == gameObject.name).First().GetComponent<NpcDialogueManager>().InvokeStepEndAction();
    }

    /// <summary>
    /// Function to invoke actions declared in manager (on current object)
    /// 
    /// Use this to invoke actions which we want to occured after specific Dialogue Step
    /// </summary>
    protected void InvokeStepEndAction()
    {
        var dialogueProgress = Dialogue.DialogueStepStatus();

        EndactionEventList.Where(el => el.Key.Key == dialogueProgress.Item1 & el.Key.Value == dialogueProgress.Item2).ToList().ForEach(el => el.Value.Invoke());
    }
}