using System;
using System.Reflection;
using LiveOpsExamples;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;

namespace LiveOpsExamples.Editor
{
  /// <summary>
  /// Builds the Cozy Collector UI: a GameObject with a PanelRenderer (PanelSettings +
  /// CozyCollectorUI.uxml) and all panel components wired through serialized
  /// references. The PanelSettings asset is created programmatically when missing.
  /// Called from <see cref="CozyCollectorBake.BakeScene"/>.
  /// </summary>
  public static partial class CozyCollectorBake
  {
    private const string UiFolderPath = "Assets/LiveOpsExamples/UI";
    private const string UiPanelSettingsPath = UiFolderPath + "/CozyCollectorPanelSettings.asset";
    private const string UiDocumentAssetPath = UiFolderPath + "/CozyCollectorUI.uxml";
    private const string UiLogRowTemplatePath = UiFolderPath + "/LogRow.uxml";
    private const string UiToastTemplatePath = UiFolderPath + "/ToastRow.uxml";
    private const string UiShopOfferRowTemplatePath = UiFolderPath + "/ShopOfferRow.uxml";
    private const string UiBackpackItemRowTemplatePath = UiFolderPath + "/BackpackItemRow.uxml";
    private const string UiLeaderboardRowTemplatePath = UiFolderPath + "/LeaderboardRow.uxml";

    private static void BuildUi(CozyCollectorController controller, GameWorld world)
    {
      var panelSettings = GetOrCreatePanelSettings();
      var visualTree = LoadUiAsset<VisualTreeAsset>(UiDocumentAssetPath);

      var uiGo = new GameObject("UI");
      var panelRenderer = uiGo.AddComponent<PanelRenderer>();
      panelRenderer.panelSettings = panelSettings;
      if (visualTree != null)
      {
        panelRenderer.visualTreeAsset = visualTree;
      }

      WirePanel(uiGo.AddComponent<SessionCardPanel>(), panelRenderer, controller);
      WirePanel(uiGo.AddComponent<RemoteConfigPanel>(), panelRenderer, controller);

      var eventInspector = uiGo.AddComponent<EventInspectorPanel>();
      WirePanel(eventInspector, panelRenderer, controller);
      WireTemplate(eventInspector, "logRowTemplate", UiLogRowTemplatePath);

      var hud = uiGo.AddComponent<HudPanel>();
      WirePanel(hud, panelRenderer, controller);
      SetSceneReference(hud, "world", world);

      var toasts = uiGo.AddComponent<ToastsPanel>();
      WirePanel(toasts, panelRenderer, controller);
      WireTemplate(toasts, "toastTemplate", UiToastTemplatePath);

      WirePanel(uiGo.AddComponent<BootOverlayPanel>(), panelRenderer, controller);
      WirePanel(uiGo.AddComponent<SetupOverlayPanel>(), panelRenderer, controller);

      var shop = uiGo.AddComponent<ShopModalPanel>();
      WirePanel(shop, panelRenderer, controller);
      WireTemplate(shop, "shopOfferRowTemplate", UiShopOfferRowTemplatePath);

      var backpack = uiGo.AddComponent<BackpackModalPanel>();
      WirePanel(backpack, panelRenderer, controller);
      WireTemplate(backpack, "backpackItemRowTemplate", UiBackpackItemRowTemplatePath);
      var spriteLibrary = AssetDatabase.LoadAssetAtPath<CozyCollectorSpriteLibrary>(SpriteLibraryPath);
      if (spriteLibrary == null)
      {
        Debug.LogError($"[CozyCollectorBake] Sprite library not found at {SpriteLibraryPath}. " +
                       "Run Tools/LiveOps/Bake Cozy Collector (All) first.");
      }
      else
      {
        SetSceneReference(backpack, "spriteLibrary", spriteLibrary);
      }

      WirePanel(uiGo.AddComponent<OfferModalPanel>(), panelRenderer, controller);

      var roundResult = uiGo.AddComponent<RoundResultModalPanel>();
      WirePanel(roundResult, panelRenderer, controller);
      WireTemplate(roundResult, "leaderboardRowTemplate", UiLeaderboardRowTemplatePath);
    }

    private static void WirePanel(MonoBehaviour panel, PanelRenderer panelRenderer, CozyCollectorController controller)
    {
      SetSceneReference(panel, "panelRenderer", panelRenderer);
      SetSceneReference(panel, "controller", controller);
    }

    private static void WireTemplate(MonoBehaviour panel, string fieldName, string templatePath)
    {
      var template = LoadUiAsset<VisualTreeAsset>(templatePath);
      if (template != null)
      {
        SetSceneReference(panel, fieldName, template);
      }
    }

    private static T LoadUiAsset<T>(string path) where T : Object
    {
      var asset = AssetDatabase.LoadAssetAtPath<T>(path);
      if (asset == null)
      {
        Debug.LogError($"[CozyCollectorBake] {typeof(T).Name} not found at {path}. " +
                       "The scene is saved with an empty reference.");
      }

      return asset;
    }

    private static PanelSettings GetOrCreatePanelSettings()
    {
      var settings = AssetDatabase.LoadAssetAtPath<PanelSettings>(UiPanelSettingsPath);
      if (settings != null)
      {
        return settings;
      }

      EnsureAssetFolder(UiFolderPath);

      settings = ScriptableObject.CreateInstance<PanelSettings>();
      settings.scaleMode = PanelScaleMode.ScaleWithScreenSize;
      settings.referenceResolution = new Vector2Int(1600, 900);
      settings.screenMatchMode = PanelScreenMatchMode.MatchWidthOrHeight;
      settings.match = 0.5f;

      var defaultTheme = LoadDefaultRuntimeTheme();
      if (defaultTheme != null)
      {
        settings.themeStyleSheet = defaultTheme;
      }

      AssetDatabase.CreateAsset(settings, UiPanelSettingsPath);
      return settings;
    }

    private static ThemeStyleSheet LoadDefaultRuntimeTheme()
    {
      var themeUtility = Type.GetType("UnityEditor.UIElements.ThemeUtility, UnityEditor.UIElementsModule");
      var property = themeUtility?.GetProperty("builtInDefaultRuntimeTheme", BindingFlags.Static | BindingFlags.NonPublic);
      return property?.GetValue(null) as ThemeStyleSheet;
    }
  }
}
