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

//[Serializable]

//[CreateAssetMenu(fileName = "New Mission", menuName = "Mission/New Mission")]
public class NpcMissionManager : DialogueManager // ScriptableObject
{
    [SerializeField]
    public Mission MissionTemplate;

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

    public bool OpenMissionInDefaultWay = true;

    [SerializeField]
    public DialogueStepModel FreeDialogue;

    // List<Key<mission No, mission step No>, Value : UnityEvent>
    //public List<IndexValuePair<IndexValuePair<int, int>, MissionCondition>> EndactionEventList;
    private void Awake()
    {
        CanBeOpened = false;
        OpenInDefaultWay = false;
    }

    public override void Start()
    {
        //base.Start();

        CreateInstanceBasedOnLanguage();

        // UPDATE DIALOGUE 
        // search in scene manager list
        if (Mission != null)
        {
            var machedDialogueData = ((MissionDataManager)MissionDataManager.Instance).GetMission(Mission);

            if (machedDialogueData != null)
            {
                UpdateMissionState(machedDialogueData);
            }
            else
            {
                Debug.Log("Start - UpdateProggres");
                UpdateProggres();
            }
        }

        Mission.BuildMission();

        if (FreeDialogue != null)
            FreeDialogue.Build();
    }

    public override void Update()
    {
        if (!OpenInDefaultWay && Input.GetKeyDown(keyToOpen) && OpenPanelCondition())
        {
            if (languageDetector.InstanceTemplates.Count() > 0)
            {
                // create and config dailogue 
                CreateInstanceBasedOnLanguage();

                Mission.BuildMission();
            }

            Mission.StartDialogue();
        }
    }

    public override void OnTriggerEnter2D(Collider2D collision)
    {
        // don't listen when component is disabled
        if (ComponentEnabledCondition() || collision.tag != "Player")
            return;

        Debug.Log("OnTriggerEnter2D");
        if (collision.gameObject.tag == "Player" && !GetCurrentDialoguePanelStatus())
        {
            CanBeOpened = true;

            CreateInstanceBasedOnLanguage();


            // UPDATE DIALOGUE 
            // search in scene manager list
            if (Mission != null)
            {
                var machedDialogueData = ((MissionDataManager)MissionDataManager.Instance).GetMission(Mission);

                if (machedDialogueData != null)
                {
                    UpdateMissionState(machedDialogueData);
                }
                else
                {
                    UpdateProggres();
                }
            }

            Mission.BuildMission();

            if (!OpenInDefaultWay)
                return;

            Mission.StartDialogue();
        }
    }

    public override void OnTriggerExit2D(Collider2D collision)
    {
        // don't listen when component is disabled
        if (ComponentEnabledCondition())
            return;

        if (collision.gameObject.tag == "Player")
        {
            CanBeOpened = false;

            // dont depend on OpenInDefaultWay flag - colse alway if were opened and player move foward
            if (Mission != null && GetCurrentDialoguePanelStatus())
            {
                Debug.Log("BreakDialogueStep");
                Mission.BreakDialogueStep();
            }
        }
    }

    public override void CreateInstanceBasedOnLanguage()
    {
        // DONT CLONE TO HAVE CONSTANT DATA - init - deep copy - to prevent overwritting chil;dern :D
        Mission = MissionTemplate;

        Mission.ResetMission();
        /*        var cloneDialogues = new List<IndexValuePair<int, Dialogue>>(Dialogue.Dialogues);

                Dialogue.Dialogues.Clear();
                foreach (var dial in cloneDialogues)
                {
                    Dialogue.Dialogues.Add(new IndexValuePair<int, Dialogue>(dial.Key, Instantiate(dial.Value)));
                }*/

        Mission.SetSpeakerName(gameObject.GetComponent<NPC>().Name);

        // update dial state - sync in order to prepare to save
        Mission.MissionStepsList.ForEach(dial => dial.DialogueStep.SetActionAfterEachDialogueStep(UpdateProggres));

        // Add one more action - to reset proggress
        //Dialogue.Dialogues.ForEach(dial => dial.Value.SetActionAfterEachDialogueStep(dial.Value.ResetDialogue));  // reset dial 
    }

    public void UpdateMissionState(MissionData missionState)
    {
        // 1 Rule - speaker name shouldnt change !!! its our 'key'

        Mission.UpdateMissionState(missionState);
    }

    /// <summary>
    /// Function to sync local dialogue state with remote one
    /// Handled in Scene Manager
    /// </summary>
    public void UpdateProggres()
    {
        ((MissionDataManager)MissionDataManager.Instance).RegisterMission(Mission);
    }




    protected override bool ComponentEnabledCondition()
    {
        return !gameObject.GetComponent<NpcMissionManager>().enabled;
    }

    public override bool GetCurrentDialoguePanelStatus()
    {
        if (Mission.CurrentStep >= Mission.MissionStepsList.Count())
            return false;

        return Mission
            .GetCurrentStep()
            .DialogueStep
            .GetCurrentStep()
            ?.DialogueController
            .CurrentPanel != null;
    }
}