using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PillarData
{
    public GameObject pillarObject;
    public GameObject connectedWall1;
    public GameObject connectedWall2;
}

public class RoomVisibilityController : MonoBehaviour
{
    [Header("Центр комнаты")]
    public Transform roomCenter;
    
    [Header("Стены (Просто перетащите 4 стены)")]
    public GameObject[] walls;

    [Header("Столбики")]
    public PillarData[] pillars;

    [Header("Настройки видимости")]
    [Range(-0.5f, 0.5f)]
    public float hideThreshold = 0.1f;

    private Camera _mainCamera;
    private Dictionary<GameObject, bool> _wallHiddenStates = new Dictionary<GameObject, bool>();
    
    // Кэшируем Renderer'ы для оптимизации (чтобы не делать GetComponent каждый кадр)
    private Dictionary<GameObject, Renderer[]> _objectRenderers = new Dictionary<GameObject, Renderer[]>();

    void Start()
    {
        _mainCamera = Camera.main;

        // При старте игры находим и запоминаем все Renderer'ы
        foreach (var wall in walls) { CacheRenderers(wall); }
        foreach (var pillar in pillars) { CacheRenderers(pillar.pillarObject); }
    }

    private void CacheRenderers(GameObject obj)
    {
        if (obj != null && !_objectRenderers.ContainsKey(obj))
        {
            _objectRenderers[obj] = obj.GetComponentsInChildren<Renderer>();
        }
    }

    void LateUpdate()
    {
        if (_mainCamera == null || roomCenter == null) return;

        Vector3 dirToCamera = _mainCamera.transform.position - roomCenter.position;
        dirToCamera.y = 0; // Игнорируем высоту

        // 1. СТЕНЫ
        foreach (var wall in walls)
        {
            if (wall == null) continue;

            Vector3 targetPos = GetRealCenter(wall);
            Vector3 dirToWall = targetPos - roomCenter.position;
            dirToWall.y = 0;

            bool isHidden = Vector3.Dot(dirToCamera.normalized, dirToWall.normalized) > hideThreshold;
            
            // Включаем или выключаем графику стены моментально
            SetVisibility(wall, !isHidden);
            _wallHiddenStates[wall] = isHidden;
            
            Debug.DrawLine(roomCenter.position, targetPos, isHidden ? Color.red : Color.green);
        }

        // 2. СТОЛБИКИ
        foreach (var pillar in pillars)
        {
            if (pillar.pillarObject == null || pillar.connectedWall1 == null || pillar.connectedWall2 == null) 
                continue;

            bool isWall1Hidden = _wallHiddenStates.ContainsKey(pillar.connectedWall1) && _wallHiddenStates[pillar.connectedWall1];
            bool isWall2Hidden = _wallHiddenStates.ContainsKey(pillar.connectedWall2) && _wallHiddenStates[pillar.connectedWall2];

            // Прячем столбик только если ОБЕ подключенные стены спрятаны
            bool shouldHidePillar = isWall1Hidden && isWall2Hidden;
            
            SetVisibility(pillar.pillarObject, !shouldHidePillar);
        }
    }

    // Метод для быстрого включения/выключения отрисовки объекта
    private void SetVisibility(GameObject obj, bool isVisible)
    {
        if (obj == null || !_objectRenderers.ContainsKey(obj)) return;

        Renderer[] renderers = _objectRenderers[obj];
        foreach (Renderer r in renderers)
        {
            if (r.enabled != isVisible)
            {
                r.enabled = isVisible;
            }
        }
    }

    private Vector3 GetRealCenter(GameObject obj)
    {
        Renderer r = obj.GetComponentInChildren<Renderer>();
        if (r != null)
        {
            return r.bounds.center;
        }
        return obj.transform.position; 
    }
}