using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;

public class ModelManager : MonoBehaviour
{
    private Dictionary<string, HashSet<ChildModel>> portDict; //port mapped on 
    private Dictionary<string, ChildModel> childModelDict; //childModels by their ID

    public List<BaseModel> baseModelList; //available BaseModels

    public GameObject baseModel; //current baseModel

    HashSet<ChildModel>.Enumerator enumerator;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        Debug.Log("ModelManager: " + this.gameObject.name);
        portDict = new Dictionary<string, HashSet<ChildModel>>();
        childModelDict = new Dictionary<string, ChildModel>();
        baseModelList = new List<BaseModel>();
        foreach (var baseModel in ModelList.BaseModels)
        {
            registerBaseModel(baseModel);
        }
        foreach (var childModel in ModelList.ChildModels)
        {
            registerChildModel(childModel);
        }
        if (baseModel == null) //set in the editor
        {
            //TODO: send into model selection
            Debug.LogError("baseModel is null, fix the configuration");
        }
        baseModel.GetComponent<BaseModelBehaviour>().UpdateModel(baseModelList[0]); //TODO: change later when there is a model selection

        enumerator = getChildModelsForPort("bikeB").GetEnumerator(); //TODO: implement GUI later
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) //TODO: remove after testing
        {
            Debug.Log($"Space key was pressed {enumerator.Current}");
            baseModel.GetComponent<BaseModelBehaviour>().setFirstWithPort("bikeB", enumerator.Current);
            enumerator.MoveNext();
        }
    }

    void registerChildModel(ChildModel model)
    {
        //childModelDict
        if (childModelDict.ContainsKey(model.nameId))
        {
            Debug.LogWarning("Model " + model.nameId + " already registered! [childModelDict] Skipping...");
            return;
        }
        childModelDict[model.nameId] = model;

        //portDict
        if (!portDict.ContainsKey(model.port))
        {
            portDict.Add(model.port, new HashSet<ChildModel>());
        }
        if (portDict[model.port].Contains(model))
        {
            Debug.LogWarning("Model " + model.nameId + " already registered! [portDict] Skipping...");
            return;
        }
        portDict[model.port].Add(model);
    }

    void registerBaseModel(BaseModel baseModel)
    {
        if (baseModel == null)
        {
            return;
        }
        baseModelList ??= new List<BaseModel>();
        baseModelList.Add(baseModel);
    }

    public HashSet<ChildModel> getChildModelsForPort(string port)
    {
        return portDict[port];
    }

    public ChildModel getById(string id)
    {
        return childModelDict[id];
    }
}
