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

public class QuestRegistry : MonoBehaviour
{
    // This will keep a register of all quest data and status
    public static QuestRegistry Instance { get; private set; }
    public Dictionary<int, QuestBool[]> QuestBoolMap;
    public List<int> CompletedQuests;
    public List<int> ActiveQuests;

    private void Awake()
    {
        // If there is an instance, and it's not me, delete myself.

        if (Instance != null && Instance != this)
        {
            Destroy(this);
        }
        else
        {
            Instance = this;
            Instance.QuestBoolMap = PopulateQuestData();

            PopulateQuestData();
            DontDestroyOnLoad(gameObject);
        }
    }

    private Dictionary<int, QuestBool[]> PopulateQuestData()
    {
        Dictionary<int, QuestBool[]> questBoolMap = new Dictionary<int, QuestBool[]>();

        // Quest Bool Structure: QID<QuestID>_<Bool Number>_<descriptiveName>
        // Example: QID11_4_landBurgerGreaseCleared
        #region 1 - Sam's Plea
        QuestBool[] QID1_List = new QuestBool[2];

        // QID1_1_hasEnoughStarshards
        QID1_List[0] = new QuestBool(() =>
        {
            return GameManager.Instance.Inventory.GetItemQuantity(ItemIdEnum.STAR_SHARD) > 2;
        });

        // QID1_2_hasHelpedSam
        QID1_List[1] = new QuestBool(() =>
        {
            return GameManager.Instance.Storybools.hasHelpedSam;
        });

        questBoolMap.Add(1, QID1_List);
        #endregion

        #region 2 - (Story Quest #1) No More Freeloading
        // This is the first time we talk to grandma. She wants help around the house.
        // Quest is complete after we talk to the shop keeper and complete quest 3.

        QuestBool[] QID2_List = new QuestBool[1];

        // QID2_1_completedQuest3
        QID2_List[0] = new QuestBool(() =>
        {
            return CompletedQuests.Contains(3);
        });

        questBoolMap.Add(2, QID2_List);
        #endregion

        #region 3 - (Story Quest #1.5) First Paycheck
        // This is the first time we talk to the shopkeeper. He tells us to find a star
        // shard and bring it to him. 

        QuestBool[] QID3_List = new QuestBool[1];

        // QID3_1_hasEnoughStarshards
        QID3_List[0] = new QuestBool(() =>
        {
            return GameManager.Instance.Inventory.GetItemQuantity(ItemIdEnum.STAR_SHARD) > 0;
        });

        questBoolMap.Add(3, QID3_List);
        #endregion

        return questBoolMap;
    }

    #region Save/Load Quest Data
    // Save completed quests to disk
    public void SaveQuestData(ref QuestSaveData data)
    {
        data.ActiveQuests = Instance.ActiveQuests;
        data.CompletedQuests = Instance.CompletedQuests;
    }

    public void LoadQuestData(QuestSaveData data)
    {
        if (data.ActiveQuests != null)
        {
            Instance.ActiveQuests = data.ActiveQuests;
        }
        else
        {
            Instance.ActiveQuests = new List<int>();
        }

        if (data.CompletedQuests != null)
        {
            Instance.CompletedQuests = data.CompletedQuests;
        }
        else
        {
            Instance.CompletedQuests = new List<int>();
        }
    }
    #endregion
}

public class QuestBool
{
    // This let's us define complex behavior for quests. We can also store
    // raw booleans for this if we have story beats we want to keep track of.
    public Func<bool> getValue;

    public QuestBool(Func<bool> getValue)
    {
        this.getValue = getValue;
    }
}

[System.Serializable]
public struct QuestSaveData
{
    public List<int> CompletedQuests;
    public List<int> ActiveQuests;
}

