using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.UIElements;

namespace LiveOpsExamples
{
  public static class UiDebugProbe
  {
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    private static void Install()
    {
      new GameObject("UiDebugProbe").AddComponent<Probe>();
    }

    private sealed class Probe : MonoBehaviour
    {
      private PanelRenderer _panelRenderer;
      private VisualElement _root;

      private IEnumerator Start()
      {
        yield return null;
        yield return null;

        _panelRenderer = FindFirstObjectByType<PanelRenderer>();
        if (_panelRenderer == null)
        {
          Debug.Log("[UiProbe] PanelRenderer: NOT FOUND");
        }
        else
        {
          _panelRenderer.RegisterUIReloadCallback(OnUIReload);
        }

        if (_root == null)
        {
          Dump("after-scene-load");
        }

        while (true)
        {
          yield return new WaitForSecondsRealtime(10f);
          Dump("periodic");
        }
      }

      private void OnDestroy()
      {
        if (_panelRenderer != null)
        {
          _panelRenderer.UnregisterUIReloadCallback(OnUIReload);
        }
      }

      private void OnUIReload(PanelRenderer renderer, VisualElement root)
      {
        _root = root;
        Dump("ui-reload");
      }

      private void Dump(string tag)
      {
        var sb = new StringBuilder();
        sb.AppendLine($"[UiProbe] --- {tag} ---");
        sb.AppendLine($"screen={Screen.width}x{Screen.height}");

        if (_panelRenderer == null)
        {
          sb.AppendLine("PanelRenderer: NOT FOUND");
          Debug.Log(sb.ToString());
          return;
        }

        var ps = _panelRenderer.panelSettings;
        sb.AppendLine(ps == null
          ? "panelSettings: NULL"
          : $"panelSettings={ps.name} scaleMode={ps.scaleMode} ref={ps.referenceResolution.x}x{ps.referenceResolution.y} match={ps.match} scale={ps.scale}");

        if (_root == null)
        {
          sb.AppendLine("root: NULL (reload callback not fired yet)");
          Debug.Log(sb.ToString());
          return;
        }

        sb.AppendLine($"root worldBound={_root.worldBound} children={_root.childCount}");
        var uiRoot = _root.childCount > 0 ? _root[0] : null;
        sb.AppendLine($"uiRoot={uiRoot?.name} children={uiRoot?.childCount}");
        if (uiRoot != null)
        {
          foreach (var child in uiRoot.Children())
          {
            Describe(sb, child);
          }
        }

        var renderers = FindObjectsByType<PanelRenderer>(FindObjectsSortMode.None);
        sb.AppendLine($"panelRenderers={renderers.Length} panel={(_root.panel == null ? "null" : "ok")}");

        Describe(sb, _root.Q("hud-score"));
        Describe(sb, _root.Q("hud-timer-fill"));
        Describe(sb, _root.Q("session-card"));
        Describe(sb, _root.Q("remote-config"));
        Describe(sb, _root.Q("event-log-scroll"));

        var controller = FindFirstObjectByType<CozyCollectorController>();
        sb.AppendLine(controller == null
          ? "controller: NOT FOUND"
          : $"controller phase={controller.Phase} activeModal={controller.ActiveModal} status='{controller.StatusMessage}'");

        var cam = Camera.main;
        sb.AppendLine(cam == null
          ? "camera: NOT FOUND"
          : $"camera rect={cam.rect} targetTexture={(cam.targetTexture == null ? "null" : cam.targetTexture.name)} enabled={cam.enabled} clearFlags={cam.clearFlags} time={Time.time:0.#} timeScale={Time.timeScale}");

        Debug.Log(sb.ToString());
      }

      private static void Describe(StringBuilder sb, VisualElement element)
      {
        if (element == null)
        {
          sb.AppendLine("  <element not found>");
          return;
        }

        var r = element.resolvedStyle;
        sb.AppendLine($"  {element.name}: display={r.display} visibility={r.visibility} opacity={r.opacity} " +
                      $"size={r.width:0.#}x{r.height:0.#} worldBound={element.worldBound} classes='{string.Join(",", element.GetClasses())}'");
      }
    }
  }
}
