using System;
using System.Collections.Generic;
using Intrepid.Gameplay.Codex.Knowledge;
using Intrepid.Utilities;
using UnityEngine;

namespace Intrepid.Gameplay.Codex.Perception
{
    /// <summary>
    /// Minimal trigger-based reading field. Shape/orientation should be authored by the collider on the GameObject.
    /// Later this can become a true forward cone/frustum query.
    /// </summary>
    [RequireComponent(typeof(Collider))]
    public class CodexReadingField : MonoBehaviour
    {
        [GroupConfigurations, SerializeField] private CodexRuntime knowledge;
        [GroupDebug, SerializeField] private List<CodexReadable> readablesInside = new();

        private CodexSemanticClassifier classifier;

        public IReadOnlyList<CodexReadable> ReadablesInside => readablesInside;
        public event Action<CodexInterpretationResult> ReadableDetected;

        private void Awake()
        {
            classifier = new CodexSemanticClassifier(knowledge);
        }

        private void OnTriggerEnter(Collider other)
        {
            var readable = other.GetComponentInParent<CodexReadable>();
            if (readable.IsNull()) return;
            if (readablesInside.Contains(readable)) return;

            readablesInside.Add(readable);
            readable.SetReadingState(CodexReadingState.Detected);

            if (knowledge.IsNull()) return;
            var result = classifier.Classify(new CodexInterpretationRequest(readable, readable.ReadingState));
            ReadableDetected?.Invoke(result);
        }

        private void OnTriggerExit(Collider other)
        {
            var readable = other.GetComponentInParent<CodexReadable>();
            if (readable.IsNull()) return;
            readablesInside.Remove(readable);
            readable.SetReadingState(CodexReadingState.Unseen);
        }
    }
}
