﻿using UnityEngine;
using UnityEditor;
using UnityEngine.UIElements;
using FrameDoctor.Editor.Config;
using FrameDoctor.Editor.Logic;

namespace FrameDoctor.Editor.Components
{
    // Static helper to handle play mode transitions - survives domain reload
    [InitializeOnLoad]
    public static class FrameDoctorPlayModeHandler
    {
        private const string PendingCaptureKey = "FrameDoctor_PendingCaptureStart";
        private const string AutoAnalyseKey = "FrameDoctor_AutoAnalyse";

        public static bool PendingCaptureStart
        {
            get => EditorPrefs.GetBool(PendingCaptureKey, false);
            set => EditorPrefs.SetBool(PendingCaptureKey, value);
        }

        public static bool AutoAnalyse
        {
            get => EditorPrefs.GetBool(AutoAnalyseKey, true);
            set => EditorPrefs.SetBool(AutoAnalyseKey, value);
        }

        static FrameDoctorPlayModeHandler()
        {
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
        }

        private static void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            if (state == PlayModeStateChange.EnteredPlayMode && PendingCaptureStart)
            {
                PendingCaptureStart = false;
                var window = EditorWindow.GetWindow<FrameDoctorWindow>("FrameDoctor");
                if (window != null)
                {
                    window.BeginCaptureFromPlayMode();
                }
            }
        }
    }

    // Main editor window for FrameDoctor using UI Toolkit.
    // Provides UI for capturing and exporting profiler data.
    public class FrameDoctorWindow : EditorWindow
    {
        [SerializeField]
        [Tooltip("UXML layout asset for the window")]
        private VisualTreeAsset _windowLayout;

        [SerializeField]
        [Tooltip("USS stylesheet for the window")]
        private StyleSheet _windowStyles;

        private ProfilerCaptureService _captureService;
        private AuthService _authService;
        private UploadService _uploadService;
        private bool _isUploading;
        private string _lastSessionId;
        private bool _isCapturing;
        private float _captureStartTime;
        private string _lastExportPath;

        // UI Elements
        private VisualElement _statusContainer;
        private Label _statusLabel;
        private Button _startCaptureBtn;
        private VisualElement _captureButtonsContainer;
        private Button _stopCaptureBtn;
        private Button _cancelCaptureBtn;
        private VisualElement _exportInfo;
        private Label _exportPathLabel;
        private Button _openFolderBtn;
        private Button _settingsBtn;
        private Button _websiteBtn;
        private Button _docsBtn;

        private Button _getAnalysisBtn;
        private Button _analyzeBtn;
        private Toggle _autoAnalyzeToggle;
        private Label _analyzeHint;
        private VisualElement _uploadProgressContainer;
        private ProgressBar _uploadProgressBar;
        private Label _uploadStatusLabel;
        private VisualElement _uploadCompleteContainer;
        private Button _viewResultsBtn;

        [MenuItem("Window/FrameDoctor")]
        public static void ShowWindow()
        {
            var window = GetWindow<FrameDoctorWindow>("FrameDoctor");
            window.minSize = new Vector2(320, 400);
        }

        private int _framesCaptured;

        private void OnEnable()
        {
            _captureService = new ProfilerCaptureService();
            _captureService.OnFrameCaptured += OnFrameCaptured;

            _authService = new AuthService();
            _uploadService = new UploadService();
            _uploadService.OnProgress += OnUploadProgress;
            _uploadService.OnComplete += OnUploadComplete;
            _uploadService.OnError += OnUploadError;

            EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
        }

        private void OnFrameCaptured(FrameData frame)
        {
            _framesCaptured++;
        }

        private void CreateGUI()
        {
            var root = rootVisualElement;

            LoadAssets();

            if (_windowLayout != null)
            {
                _windowLayout.CloneTree(root);
                InjectCloudUI(root);
            }
            else
            {
                CreateFallbackUI(root);
            }

            if (_windowStyles != null)
            {
                root.styleSheets.Add(_windowStyles);
            }

            QueryUIElements(root);
            BindEvents();
            UpdateUI();
        }

        // Injects cloud-only UI elements into the UXML-loaded tree.
        // The base UXML is shared between Asset Store and Direct builds.
        // This method adds the analysis, upload, and AI elements that only
        // exist in the Direct (FRAMEDOCTOR_CLOUD) version.
        private void InjectCloudUI(VisualElement root)
        {
            // Update subtitle to reflect cloud capabilities
            var subtitle = root.Q<Label>(className: "subtitle");
            if (subtitle != null)
            {
                subtitle.text = "AI-Powered Profiler Analysis";
            }

            // Find the footer to insert cloud sections before it
            var footer = root.Q<VisualElement>(className: "footer");
            if (footer == null) return;
            var parent = footer.parent;
            var footerIndex = parent.IndexOf(footer);

            // Analysis section
            var analysisSection = new VisualElement();
            analysisSection.AddToClassList("section");

            var analysisTitle = new Label("Analysis");
            analysisTitle.AddToClassList("section-title");
            analysisSection.Add(analysisTitle);

            var analyzeBtn = new Button { name = "analyze-btn", text = "Analyse with FrameDoctor" };
            analyzeBtn.AddToClassList("button");
            analyzeBtn.AddToClassList("accent");
            analyzeBtn.AddToClassList("full-width");
            analysisSection.Add(analyzeBtn);

            var autoToggle = new Toggle("Auto Analyse") { name = "auto-analyze-toggle", value = true };
            autoToggle.AddToClassList("auto-analyze-toggle");
            analysisSection.Add(autoToggle);

            var hint = new Label("Capture profiler data first") { name = "analyze-hint" };
            hint.AddToClassList("hint");
            analysisSection.Add(hint);

            parent.Insert(footerIndex, analysisSection);
            footerIndex++;

            // Upload progress section
            var uploadProgress = new VisualElement { name = "upload-progress" };
            uploadProgress.AddToClassList("section");
            uploadProgress.AddToClassList("upload-progress");
            uploadProgress.AddToClassList("hidden");

            var progressBar = new ProgressBar { name = "upload-progress-bar" };
            progressBar.value = 0;
            uploadProgress.Add(progressBar);

            var uploadStatus = new Label("Uploading...") { name = "upload-status" };
            uploadStatus.AddToClassList("upload-status");
            uploadProgress.Add(uploadStatus);

            parent.Insert(footerIndex, uploadProgress);
            footerIndex++;

            // Upload complete section
            var uploadComplete = new VisualElement { name = "upload-complete" };
            uploadComplete.AddToClassList("section");
            uploadComplete.AddToClassList("upload-complete");
            uploadComplete.AddToClassList("hidden");

            var successLabel = new Label("Analysis submitted!");
            successLabel.AddToClassList("success-label");
            uploadComplete.Add(successLabel);

            var viewBtn = new Button { name = "view-results-btn", text = "View in Browser" };
            viewBtn.AddToClassList("button");
            viewBtn.AddToClassList("accent");
            viewBtn.AddToClassList("full-width");
            uploadComplete.Add(viewBtn);

            parent.Insert(footerIndex, uploadComplete);
        }

        private void LoadAssets()
        {
            // Try to load from package path
            if (_windowLayout == null)
            {
                _windowLayout = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
                    "Packages/com.framedoctor.profiler/Editor/UI/FrameDoctorWindow.uxml"
                );
            }

            if (_windowStyles == null)
            {
                _windowStyles = AssetDatabase.LoadAssetAtPath<StyleSheet>(
                    "Packages/com.framedoctor.profiler/Editor/UI/FrameDoctorWindow.uss"
                );
            }

            // Fallback: search by asset name
            if (_windowLayout == null)
            {
                var guids = AssetDatabase.FindAssets("FrameDoctorWindow t:VisualTreeAsset");
                if (guids.Length > 0)
                {
                    _windowLayout = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
                        AssetDatabase.GUIDToAssetPath(guids[0])
                    );
                }
            }

            if (_windowStyles == null)
            {
                var guids = AssetDatabase.FindAssets("FrameDoctorWindow t:StyleSheet");
                if (guids.Length > 0)
                {
                    _windowStyles = AssetDatabase.LoadAssetAtPath<StyleSheet>(
                        AssetDatabase.GUIDToAssetPath(guids[0])
                    );
                }
            }
        }

        private void QueryUIElements(VisualElement root)
        {
            _statusContainer = root.Q<VisualElement>("status-container");
            _statusLabel = root.Q<Label>("status-label");
            _startCaptureBtn = root.Q<Button>("start-capture-btn");
            _captureButtonsContainer = root.Q<VisualElement>("capture-buttons");
            _stopCaptureBtn = root.Q<Button>("stop-capture-btn");
            _cancelCaptureBtn = root.Q<Button>("cancel-capture-btn");
            _exportInfo = root.Q<VisualElement>("export-info");
            _exportPathLabel = root.Q<Label>("export-path");
            _openFolderBtn = root.Q<Button>("open-folder-btn");
            _settingsBtn = root.Q<Button>("settings-btn");
            _websiteBtn = root.Q<Button>("website-btn");
            _docsBtn = root.Q<Button>("docs-btn");

            _getAnalysisBtn = root.Q<Button>("get-analysis-btn");
            _analyzeBtn = root.Q<Button>("analyze-btn");
            _autoAnalyzeToggle = root.Q<Toggle>("auto-analyze-toggle");
            _analyzeHint = root.Q<Label>("analyze-hint");
            _uploadProgressContainer = root.Q<VisualElement>("upload-progress");
            _uploadProgressBar = root.Q<ProgressBar>("upload-progress-bar");
            _uploadStatusLabel = root.Q<Label>("upload-status");
            _uploadCompleteContainer = root.Q<VisualElement>("upload-complete");
            _viewResultsBtn = root.Q<Button>("view-results-btn");
        }

        private void BindEvents()
        {
            _startCaptureBtn?.RegisterCallback<ClickEvent>(evt => StartCapture());
            _stopCaptureBtn?.RegisterCallback<ClickEvent>(evt => StopAndExport());
            _cancelCaptureBtn?.RegisterCallback<ClickEvent>(evt => CancelCapture());
            _openFolderBtn?.RegisterCallback<ClickEvent>(evt => OpenExportFolder());
            _settingsBtn?.RegisterCallback<ClickEvent>(evt => OpenSettings());
            _websiteBtn?.RegisterCallback<ClickEvent>(evt => Application.OpenURL("https://framedoctor.dev"));
            _docsBtn?.RegisterCallback<ClickEvent>(evt => Application.OpenURL("https://docs.framedoctor.dev/unity-plugin"));

            _getAnalysisBtn?.RegisterCallback<ClickEvent>(evt => Application.OpenURL("https://framedoctor.dev/upload"));
            _analyzeBtn?.RegisterCallback<ClickEvent>(evt => UploadAndAnalyse());
            _viewResultsBtn?.RegisterCallback<ClickEvent>(evt => OpenSessionInBrowser());

            if (_autoAnalyzeToggle != null)
            {
                _autoAnalyzeToggle.value = FrameDoctorPlayModeHandler.AutoAnalyse;
                _autoAnalyzeToggle.RegisterValueChangedCallback(evt =>
                {
                    FrameDoctorPlayModeHandler.AutoAnalyse = evt.newValue;
                });
            }
        }

        private void UpdateUI()
        {
            if (_startCaptureBtn == null)
            {
                return;
            }

            // Update start button text based on play state
            _startCaptureBtn.text = EditorApplication.isPlaying ? "Start Capture" : "\u25B6 Play & Capture";

            // Show start button when not capturing, show stop/cancel buttons when capturing
            _startCaptureBtn.style.display = _isCapturing ? DisplayStyle.None : DisplayStyle.Flex;

            if (_captureButtonsContainer != null)
            {
                _captureButtonsContainer.style.display = _isCapturing ? DisplayStyle.Flex : DisplayStyle.None;
            }

            if (_statusContainer != null)
            {
                _statusContainer.EnableInClassList("hidden", !_isCapturing);
            }

            var hasExport = !string.IsNullOrEmpty(_lastExportPath);

            if (_exportInfo != null)
            {
                _exportInfo.EnableInClassList("hidden", !hasExport);
            }

            if (_exportPathLabel != null && hasExport)
            {
                _exportPathLabel.text = TruncatePath(_lastExportPath, 40);
                _exportPathLabel.tooltip = _lastExportPath;
            }


            _getAnalysisBtn?.SetEnabled(hasExport);
            _analyzeBtn?.SetEnabled(hasExport);

            if (_analyzeHint != null)
            {
                _analyzeHint.EnableInClassList("hidden", hasExport);
            }

            if (_uploadProgressContainer != null)
            {
                _uploadProgressContainer.EnableInClassList("hidden", !_isUploading);
            }

            var hasSession = !string.IsNullOrEmpty(_lastSessionId);
            if (_uploadCompleteContainer != null)
            {
                _uploadCompleteContainer.EnableInClassList("hidden", !hasSession || _isUploading);
            }

            if (_isUploading)
            {
                _analyzeBtn?.SetEnabled(false);
            }
        }

        private string TruncatePath(string path, int maxLength)
        {
            if (string.IsNullOrEmpty(path) || path.Length <= maxLength)
            {
                return path;
            }

            var fileName = System.IO.Path.GetFileName(path);
            if (fileName.Length >= maxLength - 3)
            {
                return "..." + fileName.Substring(fileName.Length - maxLength + 3);
            }

            var remaining = maxLength - fileName.Length - 4;
            return path.Substring(0, remaining) + ".../" + fileName;
        }

        private void StartCapture()
        {
            // If game isn't playing, start play mode first
            if (!EditorApplication.isPlaying)
            {
                FrameDoctorPlayModeHandler.PendingCaptureStart = true;
                EditorApplication.isPlaying = true;
                return;
            }

            BeginCapture();
        }

        // Called by FrameDoctorPlayModeHandler when play mode starts with pending capture
        public void BeginCaptureFromPlayMode()
        {
            // Small delay to ensure window is fully initialized
            EditorApplication.delayCall += BeginCapture;
        }

        private void BeginCapture()
        {
            _captureService.StartCapture();
            _isCapturing = true;
            _framesCaptured = 0;
            _captureStartTime = Time.realtimeSinceStartup;
            UpdateUI();

            EditorApplication.update += OnEditorUpdate;
        }

        private void OnPlayModeStateChanged(PlayModeStateChange state)
        {
            if (state == PlayModeStateChange.ExitingPlayMode && _isCapturing)
            {
                // Auto-stop and export when exiting play mode
                StopAndExport();
            }

            // Update button text when play state changes
            UpdateUI();
        }

        private void StopAndExport()
        {
            // Guard against double execution
            if (!_isCapturing)
            {
                return;
            }

            EditorApplication.update -= OnEditorUpdate;

            _captureService.StopCapture();
            _isCapturing = false;

            // Check if any frames were captured
            if (_framesCaptured == 0)
            {
                EditorUtility.DisplayDialog(
                    "No Frames Captured",
                    "No frames were captured. Make sure to play your game while capturing.",
                    "OK"
                );
                UpdateUI();
                return;
            }

            var exporter = new DataExporter();
            _lastExportPath = exporter.Export(_captureService.GetCaptureData());

            if (!string.IsNullOrEmpty(_lastExportPath) && FrameDoctorPlayModeHandler.AutoAnalyse)
            {
                UploadAndAnalyse();
            }

            UpdateUI();
        }

        private void CancelCapture()
        {
            EditorApplication.update -= OnEditorUpdate;

            _captureService.StopCapture();
            _isCapturing = false;
            _framesCaptured = 0;
            FrameDoctorPlayModeHandler.PendingCaptureStart = false;

            FrameDoctor.Editor.Config.FrameDoctorSettings.Log("[FrameDoctor] Capture cancelled");
            UpdateUI();
        }

        private void OnEditorUpdate()
        {
            if (_isCapturing && _statusLabel != null)
            {
                var elapsed = Time.realtimeSinceStartup - _captureStartTime;
                _statusLabel.text = $"Recording... {_framesCaptured} frames ({elapsed:F1}s)";

                // Repaint to show updated frame count
                Repaint();
            }
        }

        private async void UploadAndAnalyse()
        {
            if (string.IsNullOrEmpty(_lastExportPath))
            {
                Debug.LogWarning("[FrameDoctor] No export data to upload");
                return;
            }

            if (_isUploading)
            {
                return;
            }

            // Check authentication
            if (!_authService.IsAuthenticated)
            {
                var authenticated = await _authService.LoginAsync();
                if (!authenticated)
                {
                    return;
                }
            }

            // Start upload
            _isUploading = true;
            _lastSessionId = null;
            UpdateUI();

            if (_uploadProgressBar != null)
            {
                _uploadProgressBar.value = 0;
            }
            if (_uploadStatusLabel != null)
            {
                _uploadStatusLabel.text = "Uploading...";
            }

            var sessionId = await _uploadService.UploadAsync(_lastExportPath, _authService.GetToken());

            _isUploading = false;

            if (!string.IsNullOrEmpty(sessionId))
            {
                _lastSessionId = sessionId;

                if (FrameDoctorSettings.Instance.AutoOpenBrowserAfterUpload)
                {
                    OpenSessionInBrowser();
                }
            }

            UpdateUI();
        }

        private void OnUploadProgress(float progress)
        {
            if (_uploadProgressBar != null)
            {
                _uploadProgressBar.value = progress * 100f;
            }
            if (_uploadStatusLabel != null)
            {
                _uploadStatusLabel.text = $"Uploading... {(progress * 100f):F0}%";
            }
            Repaint();
        }

        private void OnUploadComplete(string sessionId)
        {
            if (_uploadStatusLabel != null)
            {
                _uploadStatusLabel.text = "Upload complete!";
            }
        }

        private void OnUploadError(string error)
        {
            Debug.LogError($"[FrameDoctor] Upload error: {error}");

            if (_uploadStatusLabel != null)
            {
                _uploadStatusLabel.text = $"Error: {error}";
            }

            if (error.Contains("Authentication expired"))
            {
                _authService.ClearToken();
            }
        }

        private void OpenSessionInBrowser()
        {
            if (!string.IsNullOrEmpty(_lastSessionId))
            {
                var url = $"{FrameDoctorConstants.WebServiceUrl}{FrameDoctorConstants.SessionPath}/{_lastSessionId}";
                Application.OpenURL(url);
            }
        }

        private void OpenExportFolder()
        {
            if (!string.IsNullOrEmpty(_lastExportPath))
            {
                EditorUtility.RevealInFinder(_lastExportPath);
            }
        }

        private void OpenSettings()
        {
            SettingsService.OpenUserPreferences("Preferences/FrameDoctor");
        }

        private void OnDisable()
        {
            EditorApplication.update -= OnEditorUpdate;
            EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;

            if (_captureService != null)
            {
                _captureService.OnFrameCaptured -= OnFrameCaptured;
                _captureService.Dispose();
                _captureService = null;
            }

            if (_uploadService != null)
            {
                _uploadService.OnProgress -= OnUploadProgress;
                _uploadService.OnComplete -= OnUploadComplete;
                _uploadService.OnError -= OnUploadError;
                _uploadService.Cancel();
                _uploadService = null;
            }

            if (_authService != null)
            {
                _authService.CancelLogin();
                _authService.Dispose();
                _authService = null;
            }

            _isUploading = false;

            _isCapturing = false;
            // Don't clear pending capture flag here - it needs to survive domain reload
        }

        // Fallback UI creation if UXML cannot be loaded.
        private void CreateFallbackUI(VisualElement root)
        {
            root.style.paddingTop = 16;
            root.style.paddingRight = 16;
            root.style.paddingBottom = 16;
            root.style.paddingLeft = 16;

            var title = new Label("FrameDoctor");
            title.style.fontSize = 20;
            title.style.unityFontStyleAndWeight = FontStyle.Bold;
            root.Add(title);

            var subtitle = new Label("Profiler Capture & Export");
            subtitle.style.color = new Color(0.5f, 0.5f, 0.5f);
            subtitle.style.marginBottom = 20;
            root.Add(subtitle);

            _statusContainer = new VisualElement();
            _statusContainer.name = "status-container";
            _statusContainer.style.flexDirection = FlexDirection.Row;
            _statusContainer.style.backgroundColor = new Color(0.1f, 0.23f, 0.36f);
            _statusContainer.style.borderTopLeftRadius = 4;
            _statusContainer.style.borderTopRightRadius = 4;
            _statusContainer.style.borderBottomLeftRadius = 4;
            _statusContainer.style.borderBottomRightRadius = 4;
            _statusContainer.style.paddingTop = 12;
            _statusContainer.style.paddingRight = 12;
            _statusContainer.style.paddingBottom = 12;
            _statusContainer.style.paddingLeft = 12;
            _statusContainer.style.marginBottom = 16;
            _statusContainer.style.display = DisplayStyle.None;

            _statusLabel = new Label("Capturing...");
            _statusLabel.name = "status-label";
            _statusContainer.Add(_statusLabel);
            root.Add(_statusContainer);

            // Start Capture button (shown when not capturing)
            _startCaptureBtn = new Button(StartCapture) { text = "\u25B6 Play & Capture" };
            _startCaptureBtn.name = "start-capture-btn";
            _startCaptureBtn.style.flexGrow = 1;
            _startCaptureBtn.style.height = 32;
            _startCaptureBtn.style.marginBottom = 16;
            _startCaptureBtn.style.backgroundColor = new Color(0.23f, 0.53f, 1f);
            _startCaptureBtn.style.color = Color.white;
            root.Add(_startCaptureBtn);

            // Capture buttons container (shown when capturing)
            _captureButtonsContainer = new VisualElement();
            _captureButtonsContainer.name = "capture-buttons";
            _captureButtonsContainer.style.flexDirection = FlexDirection.Row;
            _captureButtonsContainer.style.marginBottom = 16;
            _captureButtonsContainer.style.display = DisplayStyle.None;

            _stopCaptureBtn = new Button(StopAndExport) { text = "Stop Capture & Export" };
            _stopCaptureBtn.name = "stop-capture-btn";
            _stopCaptureBtn.style.flexGrow = 1;
            _stopCaptureBtn.style.height = 32;
            _stopCaptureBtn.style.marginRight = 8;
            _stopCaptureBtn.style.backgroundColor = new Color(0.23f, 0.53f, 1f);
            _stopCaptureBtn.style.color = Color.white;
            _captureButtonsContainer.Add(_stopCaptureBtn);

            _cancelCaptureBtn = new Button(CancelCapture) { text = "Cancel" };
            _cancelCaptureBtn.name = "cancel-capture-btn";
            _cancelCaptureBtn.style.flexGrow = 1;
            _cancelCaptureBtn.style.height = 32;
            _cancelCaptureBtn.style.backgroundColor = new Color(0.25f, 0.25f, 0.25f);
            _cancelCaptureBtn.style.color = new Color(0.88f, 0.88f, 0.88f);
            _captureButtonsContainer.Add(_cancelCaptureBtn);

            root.Add(_captureButtonsContainer);

            _exportInfo = new VisualElement();
            _exportInfo.name = "export-info";
            _exportInfo.style.backgroundColor = new Color(0.15f, 0.15f, 0.15f);
            _exportInfo.style.borderTopLeftRadius = 4;
            _exportInfo.style.borderTopRightRadius = 4;
            _exportInfo.style.borderBottomLeftRadius = 4;
            _exportInfo.style.borderBottomRightRadius = 4;
            _exportInfo.style.paddingTop = 12;
            _exportInfo.style.paddingRight = 12;
            _exportInfo.style.paddingBottom = 12;
            _exportInfo.style.paddingLeft = 12;
            _exportInfo.style.marginBottom = 16;
            _exportInfo.style.display = DisplayStyle.None;

            var exportTitle = new Label("Last Export");
            exportTitle.style.fontSize = 11;
            exportTitle.style.unityFontStyleAndWeight = FontStyle.Bold;
            exportTitle.style.color = new Color(0.5f, 0.5f, 0.5f);
            exportTitle.style.marginBottom = 8;
            _exportInfo.Add(exportTitle);

            _exportPathLabel = new Label();
            _exportPathLabel.name = "export-path";
            _exportPathLabel.style.fontSize = 11;
            _exportPathLabel.style.marginBottom = 8;
            _exportInfo.Add(_exportPathLabel);

            _openFolderBtn = new Button(OpenExportFolder) { text = "Open Export Folder" };
            _openFolderBtn.name = "open-folder-btn";
            _openFolderBtn.style.height = 28;
            _exportInfo.Add(_openFolderBtn);

            root.Add(_exportInfo);

            // AI Analysis info section (Direct version only)
            var analysisInfo = new VisualElement();
            analysisInfo.style.backgroundColor = new Color(0.13f, 0.17f, 0.21f);
            analysisInfo.style.borderTopLeftRadius = 4;
            analysisInfo.style.borderTopRightRadius = 4;
            analysisInfo.style.borderBottomLeftRadius = 4;
            analysisInfo.style.borderBottomRightRadius = 4;
            analysisInfo.style.paddingTop = 12;
            analysisInfo.style.paddingRight = 12;
            analysisInfo.style.paddingBottom = 12;
            analysisInfo.style.paddingLeft = 12;
            analysisInfo.style.marginBottom = 16;

            var analysisLabel = new Label("Want AI-powered analysis of your profiler data?");
            analysisLabel.style.fontSize = 11;
            analysisLabel.style.color = new Color(0.6f, 0.6f, 0.6f);
            analysisLabel.style.marginBottom = 8;
            analysisLabel.style.whiteSpace = WhiteSpace.Normal;
            analysisInfo.Add(analysisLabel);

            _getAnalysisBtn = new Button(() => Application.OpenURL("https://framedoctor.dev/upload")) { text = "Get AI Analysis \u2192 framedoctor.dev" };
            _getAnalysisBtn.name = "get-analysis-btn";
            _getAnalysisBtn.style.height = 28;
            _getAnalysisBtn.style.backgroundColor = new Color(0.02f, 0.84f, 0.63f);
            _getAnalysisBtn.style.color = new Color(0.1f, 0.1f, 0.1f);
            analysisInfo.Add(_getAnalysisBtn);

            root.Add(analysisInfo);

            var spacer = new VisualElement();
            spacer.style.flexGrow = 1;
            root.Add(spacer);

            var footer = new VisualElement();
            footer.style.flexDirection = FlexDirection.Row;
            footer.style.justifyContent = Justify.SpaceBetween;
            footer.style.alignItems = Align.Center;
            footer.style.paddingTop = 16;
            footer.style.borderTopWidth = 1;
            footer.style.borderTopColor = new Color(0.24f, 0.24f, 0.24f);

            _settingsBtn = new Button(OpenSettings) { text = "\u2699" };
            _settingsBtn.name = "settings-btn";
            _settingsBtn.tooltip = "Open Settings";
            _settingsBtn.style.width = 28;
            _settingsBtn.style.height = 28;
            _settingsBtn.style.backgroundColor = Color.clear;
            _settingsBtn.style.borderTopWidth = 0;
            _settingsBtn.style.borderRightWidth = 0;
            _settingsBtn.style.borderBottomWidth = 0;
            _settingsBtn.style.borderLeftWidth = 0;
            _settingsBtn.style.borderTopLeftRadius = 4;
            _settingsBtn.style.borderTopRightRadius = 4;
            _settingsBtn.style.borderBottomLeftRadius = 4;
            _settingsBtn.style.borderBottomRightRadius = 4;
            _settingsBtn.style.color = new Color(0.5f, 0.5f, 0.5f);
            _settingsBtn.style.fontSize = 16;
            _settingsBtn.style.unityTextAlign = TextAnchor.MiddleCenter;
            footer.Add(_settingsBtn);

            var versionLabel = new Label($"v{FrameDoctorConstants.Version}");
            versionLabel.style.fontSize = 10;
            versionLabel.style.color = new Color(0.31f, 0.31f, 0.31f);
            footer.Add(versionLabel);

            root.Add(footer);
        }
    }
}
