using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Base for BaseModelBehaviour and ChildModelBehaviour
/// </summary>
public class ModelBehaviour : MonoBehaviour
{
    internal Model model; //should be verified 
    internal List<GameObject> children;
    internal MeshFilter meshFilter;
    internal MeshRenderer meshRenderer;

    void Start()
    {
        var filter = gameObject.GetComponent<MeshFilter>();
        if (filter == null)
        {
            filter = gameObject.AddComponent<MeshFilter>();
        }
        meshFilter = filter;
        
        var renderer = gameObject.GetComponent<MeshRenderer>();
        if (renderer == null)
        {
            renderer = gameObject.AddComponent<MeshRenderer>();
        }
        meshRenderer = renderer;
    }

    internal void UpdateModel(Model _model)
    {
        //kill old children
        foreach (var go in GetComponentsInChildren<ChildModelBehaviour>())
        {
            Debug.Log($"Destroying {go.name}");
            Destroy(go); // will be destroyed next frame
        }
        model = _model;
        //spawn new childPorts
        if (model.hasPorts())
        {
            Debug.Log($"Spawning {gameObject.name}'s ports");
            children = model.spawnAllPorts(gameObject);
        }
        //change ourselves
        meshFilter.mesh = _model.mesh;
        meshFilter.sharedMesh = _model.mesh;
        meshRenderer.material = _model.material;
        meshRenderer.sharedMaterial = _model.material;
    }
    
    public void UpdateChild(int childNum, string id)
    {
        var newChildModel = FindAnyObjectByType<ModelManager>().getById(id);
        children[childNum].GetComponent<ChildModelBehaviour>().UpdateModel(newChildModel);
    }

    public List<int> getChildrenWithPort(string port)
    {
        List<int> list = new List<int>();
        for (int i = 0; i < children.Count; i++)
        {
            if (children[i].GetComponent<ChildModelBehaviour>().childModel.port == port)
            {
                list.Add(i);
            }
        }
        return list;
    }

    public bool setFirstWithPort(string port, ChildModel _childModel)
    {
        Debug.Log($"{this.name}: has {children.Count} children");
        for (int i = 0; i < children.Count; i++)
        {
            var cmb = children[i].GetComponent<ChildModelBehaviour>();
            Debug.Log($"{this.name}: {i} name {children[i].name} -  port {cmb.childModel.port}");
            if(cmb.childModel.port == port)
            {
                if (_childModel == null)
                {
                    Debug.LogWarning($"{this.name}: Cant replace port {port} with model, model is null");
                    return false;
                }
                cmb.UpdateModel(model);
                return true;
            }
        }
        Debug.LogWarning($"{this.name}: Didnt find port {port}");
        return false;
    }
}
