using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;

[Serializable]
class ConditionManager : MonoBehaviour
{
    public static ConditionManager Instance { get; protected set; }

    [SerializeField]
    public string CurrentScene;

    /// <summary>
    /// Key: missionUniqueName || old -> map name && npc name
    /// </summary>
    [SerializeField]
    public List<IndexValuePair<string, List<MissionCondition>>> Conditions;

    public void Awake()
    {

        if (Instance == null)
        {
            CurrentScene = SceneManager.GetActiveScene().name;

            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }
   


    public void RegisterCondition(string missionName, List<MissionCondition> conditionsToContinue)
    {
        if(HasMissionActiveCondition(missionName))
        {
            // Npc mission manager may try to register current condition - but player may have registered and saved it ealier
            // and after loiading game system will read this condition and pass to list from memory files
            Debug.LogError($"Mission '{missionName}' has currently active Condition");

            return;
        }

        Conditions.Add(
            new IndexValuePair<string, List<MissionCondition>>(
                missionName,
                conditionsToContinue
            )
        );
    }

    /// <summary>
    /// Update all regfistered conditions (for all missions) which refer to passed object (item, enemy) name 
    /// </summary>
    public void UpdateKillCondition(string objectName)
    {
        Debug.Log($"UpdateKillCondition - {objectName}");

        Conditions
            .SelectMany(conditions => conditions.Value)
            .Where(missionCondition => missionCondition.Type == MissionTypeEnum.Kill)
            .ToList()
            .ForEach(killCondition => killCondition.RequiredElements
                .Where(element => element.RequiredObject.GetComponent<Enemy>().MinionName == objectName)
                .ToList()
                .ForEach(element => ((KillRequiredSubject)element).IncreaseAmount())
            );

        // SaveChanges
        // SaveConditions();
    }

    /// <summary>
    /// If mission step has no condition (nothing registered) return TRUE defaultly
    /// </summary>
    /// <param name="missionName"></param>
    /// <returns></returns>
    public bool CheckCondition(string missionName)
    {
        if(!HasMissionActiveCondition(missionName))
        {
            Debug.LogError($"Data inconsistency!!! Mission dont have any registered condition to check");
            return false;
        }

        int unmeetedConditions = Conditions
            .Where(condition => condition.Key == missionName)
            .FirstOrDefault()
            .Value
            .ToList()
                .SelectMany(missionCondition => missionCondition.RequiredElements)
                .ToList()
                .Where(el => !el.CheckCondition())
                .Count()
        ;

        return !(unmeetedConditions > 0);
    }

    public void RemoveCondition(string missionName)
    {
        Conditions.RemoveAll(condition => condition.Key == missionName);
    }

    /// <summary>
    /// Function to check if lists contain any condition for selected mission
    /// If contain - reject - prev condition must be removed after his fulified! ! !
    /// If dont contain - add
    /// 
    /// </summary>
    /// <param name="npc"></param>
    /// <returns></returns>
    public bool HasMissionActiveCondition(string missionName)
    {
        return Conditions.Where(conditon => conditon.Key == missionName).Any();
    }
}