using System;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("CorrosionTeleportGUI", "Corrosion", "1.0.0")]
    [Description("Beautiful in-game teleport GUI that integrates with NTeleportation")]
    public class CorrosionTeleportGUI : RustPlugin
    {
        #region Constants

        private const string MainPanel = "CorrosionTP_Main";
        private const string PopupPanel = "CorrosionTP_Popup";

        private const int GridColumns = 4;
        private const int GridRows = 5;
        private const int PlayersPerPage = GridColumns * GridRows;
        private const float PopupTimeout = 30f;

        // Color scheme
        private const string ColorOverlay = "0.05 0.05 0.05 0.95";
        private const string ColorPanel = "0.1 0.1 0.1 0.98";
        private const string ColorTabActive = "0.8 0.4 0.2 1";
        private const string ColorTabInactive = "0.2 0.2 0.2 1";
        private const string ColorButtonHover = "0.3 0.3 0.3 1";
        private const string ColorText = "1 1 1 1";
        private const string ColorTextMuted = "0.7 0.7 0.7 1";
        private const string ColorAccept = "0.2 0.6 0.2 0.9";
        private const string ColorDeny = "0.6 0.2 0.2 0.9";
        private const string ColorClose = "0.6 0.2 0.2 0.8";
        private const string ColorTransparent = "0 0 0 0";
        private const string ColorInputBg = "0.15 0.15 0.15 1";
        private const string ColorCardBg = "0.14 0.14 0.14 1";
        private const string ColorDivider = "0.25 0.25 0.25 1";
        private const string ColorSettingLabel = "0.5 0.5 0.5 1";

        #endregion

        #region Fields

        [PluginReference]
        private Plugin NTeleportation;

        private Dictionary<ulong, int> playerPages = new Dictionary<ulong, int>();
        private Dictionary<ulong, string> playerSearches = new Dictionary<ulong, string>();
        private Dictionary<ulong, string> playerTabs = new Dictionary<ulong, string>();
        private Dictionary<ulong, Timer> popupTimers = new Dictionary<ulong, Timer>();
        private List<BasePlayer> cachedPlayers = new List<BasePlayer>();

        #endregion

        #region Lifecycle Hooks

        private void OnServerInitialized()
        {
            if (NTeleportation == null)
            {
                PrintWarning("NTeleportation plugin not found! Teleport functionality will be limited.");
                PrintWarning("Install NTeleportation from uMod for full functionality.");
            }
            else
            {
                Puts("NTeleportation detected — full integration enabled.");
            }

            RefreshPlayerCache();
            Puts("CorrosionTeleportGUI initialized.");
        }

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                DestroyUI(player);
                DestroyPopupUI(player);
            }

            foreach (var kvp in popupTimers)
            {
                kvp.Value?.Destroy();
            }

            popupTimers.Clear();
            playerPages.Clear();
            playerSearches.Clear();
            playerTabs.Clear();
            cachedPlayers.Clear();
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null) return;
            if (!cachedPlayers.Contains(player))
                cachedPlayers.Add(player);
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (player == null) return;
            cachedPlayers.Remove(player);
            playerPages.Remove(player.userID);
            playerSearches.Remove(player.userID);
            playerTabs.Remove(player.userID);

            if (popupTimers.TryGetValue(player.userID, out var popupTimer))
            {
                popupTimer?.Destroy();
                popupTimers.Remove(player.userID);
            }
        }

        #endregion

        #region Chat Command

        [ChatCommand("tpgui")]
        private void CmdTeleportGUI(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            playerPages[player.userID] = 0;
            playerSearches[player.userID] = string.Empty;
            playerTabs[player.userID] = "teleport";

            ShowMainPanel(player);
        }

        #endregion

        #region Console Commands

        [ConsoleCommand("tpgui.close")]
        private void CmdClose(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            DestroyUI(player);
            playerPages.Remove(player.userID);
            playerSearches.Remove(player.userID);
            playerTabs.Remove(player.userID);
        }

        [ConsoleCommand("tpgui.tab")]
        private void CmdTab(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string tab = arg.GetString(0, "teleport");
            playerTabs[player.userID] = tab;
            playerPages[player.userID] = 0;
            playerSearches[player.userID] = string.Empty;

            ShowMainPanel(player);
        }

        [ConsoleCommand("tpgui.search")]
        private void CmdSearch(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string search = arg.GetString(0, string.Empty);
            playerSearches[player.userID] = search;
            playerPages[player.userID] = 0;

            ShowMainPanel(player);
        }

        [ConsoleCommand("tpgui.page")]
        private void CmdPage(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string direction = arg.GetString(0, "next");
            int currentPage = GetPlayerPage(player);

            if (direction == "next")
                playerPages[player.userID] = currentPage + 1;
            else if (direction == "prev" && currentPage > 0)
                playerPages[player.userID] = currentPage - 1;

            ShowMainPanel(player);
        }

        [ConsoleCommand("tpgui.tpr")]
        private void CmdTPR(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string targetName = arg.GetString(0, string.Empty);
            if (string.IsNullOrEmpty(targetName))
            {
                player.ChatMessage("<color=#CD6632>[Corrosion TP]</color> No target specified.");
                return;
            }

            DestroyUI(player);
            player.SendConsoleCommand("chat.say", "/tpr " + targetName);
            player.ChatMessage($"<color=#CD6632>[Corrosion TP]</color> Teleport request sent to <color=#FFFFFF>{targetName}</color>.");
        }

        [ConsoleCommand("tpgui.home")]
        private void CmdHome(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string homeName = arg.GetString(0, string.Empty);
            if (string.IsNullOrEmpty(homeName))
            {
                player.ChatMessage("<color=#CD6632>[Corrosion TP]</color> No home specified.");
                return;
            }

            DestroyUI(player);
            player.SendConsoleCommand("chat.say", "/home " + homeName);
        }

        [ConsoleCommand("tpgui.sethome")]
        private void CmdSetHome(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string homeName = arg.GetString(0, "home");
            DestroyUI(player);
            player.SendConsoleCommand("chat.say", "/sethome " + homeName);
            player.ChatMessage($"<color=#CD6632>[Corrosion TP]</color> Setting home '<color=#FFFFFF>{homeName}</color>' at current position...");
        }

        [ConsoleCommand("tpgui.removehome")]
        private void CmdRemoveHome(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string homeName = arg.GetString(0, string.Empty);
            if (string.IsNullOrEmpty(homeName))
            {
                player.ChatMessage("<color=#CD6632>[Corrosion TP]</color> No home specified.");
                return;
            }

            player.SendConsoleCommand("chat.say", "/removehome " + homeName);
            player.ChatMessage($"<color=#CD6632>[Corrosion TP]</color> Removing home '<color=#FFFFFF>{homeName}</color>'...");

            // Refresh the panel after a short delay to allow NTeleportation to process
            timer.Once(0.5f, () =>
            {
                if (player != null && player.IsConnected)
                    ShowMainPanel(player);
            });
        }

        [ConsoleCommand("tpgui.warp")]
        private void CmdWarp(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            string warpName = arg.GetString(0, string.Empty);
            if (string.IsNullOrEmpty(warpName))
            {
                player.ChatMessage("<color=#CD6632>[Corrosion TP]</color> No warp specified.");
                return;
            }

            DestroyUI(player);
            player.SendConsoleCommand("chat.say", "/warp " + warpName);
        }

        [ConsoleCommand("tpgui.accept")]
        private void CmdAccept(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            DestroyPopupUI(player);
            player.SendConsoleCommand("chat.say", "/tpa");
        }

        [ConsoleCommand("tpgui.deny")]
        private void CmdDeny(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            DestroyPopupUI(player);
            player.SendConsoleCommand("chat.say", "/tpc");
        }

        [ConsoleCommand("tpgui.popup.close")]
        private void CmdPopupClose(ConsoleSystem.Arg arg)
        {
            var player = arg.Connection?.player as BasePlayer;
            if (player == null) return;

            DestroyPopupUI(player);
        }

        #endregion

        #region NTeleportation Hooks

        /// <summary>
        /// Hook called by NTeleportation when a player receives a teleport request.
        /// Shows the accept/deny popup to the target player.
        /// </summary>
        private void OnTeleportRequested(BasePlayer target, BasePlayer requester)
        {
            if (target == null || requester == null) return;
            ShowTPRPopup(target, requester.displayName);
        }

        #endregion

        #region Main Panel

        private void ShowMainPanel(BasePlayer player)
        {
            DestroyUI(player);
            RefreshPlayerCache();

            string activeTab = GetPlayerTab(player);
            var container = new CuiElementContainer();

            // Full-screen overlay background
            container.Add(new CuiPanel
            {
                Image = { Color = ColorOverlay },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                CursorEnabled = true
            }, "Overlay", MainPanel);

            // Main panel body
            container.Add(new CuiPanel
            {
                Image = { Color = ColorPanel },
                RectTransform = { AnchorMin = "0.15 0.1", AnchorMax = "0.85 0.9" }
            }, MainPanel, MainPanel + "_Body");

            // --- Header ---
            AddHeader(ref container, player, activeTab);

            // --- Tab Content ---
            switch (activeTab)
            {
                case "teleport":
                    ShowTeleportTab(ref container, player);
                    break;
                case "homes":
                    ShowHomesTab(ref container, player);
                    break;
                case "warps":
                    ShowWarpsTab(ref container, player);
                    break;
                case "settings":
                    ShowSettingsTab(ref container, player);
                    break;
            }

            CuiHelper.AddUi(player, container);
        }

        private void AddHeader(ref CuiElementContainer container, BasePlayer player, string activeTab)
        {
            string body = MainPanel + "_Body";

            // Header background
            container.Add(new CuiPanel
            {
                Image = { Color = "0.08 0.08 0.08 1" },
                RectTransform = { AnchorMin = "0 0.88", AnchorMax = "1 1" }
            }, body, body + "_Header");

            // Title
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "CORROSION TELEPORT",
                    FontSize = 18,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorTabActive,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.03 0", AnchorMax = "0.3 1" }
            }, body + "_Header");

            // Tab buttons
            float tabStart = 0.32f;
            float tabWidth = 0.12f;
            float tabGap = 0.005f;

            string[] tabs = { "teleport", "homes", "warps" };
            string[] tabLabels = { "TELEPORT", "HOMES", "WARPS" };

            for (int i = 0; i < tabs.Length; i++)
            {
                float xMin = tabStart + i * (tabWidth + tabGap);
                float xMax = xMin + tabWidth;
                string color = activeTab == tabs[i] ? ColorTabActive : ColorTabInactive;

                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = color,
                        Command = $"tpgui.tab {tabs[i]}"
                    },
                    Text =
                    {
                        Text = tabLabels[i],
                        FontSize = 12,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = $"{xMin} 0.2", AnchorMax = $"{xMax} 0.8" }
                }, body + "_Header");
            }

            // Settings gear button
            float settingsX = tabStart + tabs.Length * (tabWidth + tabGap);
            string settingsColor = activeTab == "settings" ? ColorTabActive : ColorTabInactive;
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = settingsColor,
                    Command = "tpgui.tab settings"
                },
                Text =
                {
                    Text = "⚙",
                    FontSize = 16,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText
                },
                RectTransform = { AnchorMin = $"{settingsX} 0.2", AnchorMax = $"{settingsX + 0.05f} 0.8" }
            }, body + "_Header");

            // Close button
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = ColorClose,
                    Command = "tpgui.close"
                },
                Text =
                {
                    Text = "✕",
                    FontSize = 16,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.93 0.2", AnchorMax = "0.98 0.8" }
            }, body + "_Header");

            // Divider line below header
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTabActive },
                RectTransform = { AnchorMin = "0 0.875", AnchorMax = "1 0.878" }
            }, body);
        }

        #endregion

        #region Teleport Tab

        private void ShowTeleportTab(ref CuiElementContainer container, BasePlayer player)
        {
            string body = MainPanel + "_Body";

            // Content area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0.02 0.02", AnchorMax = "0.98 0.86" }
            }, body, body + "_TeleportContent");

            string content = body + "_TeleportContent";

            // Search bar background
            container.Add(new CuiPanel
            {
                Image = { Color = ColorInputBg },
                RectTransform = { AnchorMin = "0 0.9", AnchorMax = "0.75 0.98" }
            }, content, content + "_SearchBg");

            // Search label
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "  🔍 Search players...",
                    FontSize = 12,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorTextMuted,
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
            }, content + "_SearchBg");

            // Search input field
            container.Add(new CuiElement
            {
                Name = content + "_SearchInput",
                Parent = content + "_SearchBg",
                Components =
                {
                    new CuiInputFieldComponent
                    {
                        Text = GetPlayerSearch(player),
                        FontSize = 12,
                        Color = ColorText,
                        Command = "tpgui.search",
                        Font = "robotocondensed-regular.ttf",
                        Align = TextAnchor.MiddleLeft
                    },
                    new CuiRectTransformComponent
                    {
                        AnchorMin = "0.03 0",
                        AnchorMax = "0.97 1"
                    }
                }
            });

            // Online count label
            int totalOnline = cachedPlayers.Count(p => p != null && p.IsConnected && p.userID != player.userID);
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = $"{totalOnline} ONLINE",
                    FontSize = 11,
                    Align = TextAnchor.MiddleRight,
                    Color = ColorTextMuted,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.78 0.9", AnchorMax = "0.98 0.98" }
            }, content);

            // Filter and paginate players
            string search = GetPlayerSearch(player);
            var filteredPlayers = cachedPlayers
                .Where(p => p != null && p.IsConnected && p.userID != player.userID)
                .Where(p => string.IsNullOrEmpty(search) ||
                            p.displayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0)
                .OrderBy(p => p.displayName)
                .ToList();

            int currentPage = GetPlayerPage(player);
            int totalPages = Math.Max(1, (int)Math.Ceiling((double)filteredPlayers.Count / PlayersPerPage));

            // Clamp page
            if (currentPage >= totalPages) currentPage = totalPages - 1;
            if (currentPage < 0) currentPage = 0;
            playerPages[player.userID] = currentPage;

            var pagePlayers = filteredPlayers
                .Skip(currentPage * PlayersPerPage)
                .Take(PlayersPerPage)
                .ToList();

            // Player grid area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0 0.08", AnchorMax = "1 0.88" }
            }, content, content + "_Grid");

            // Render player cards
            float cardGap = 0.01f;
            float cardWidth = (1f - (GridColumns + 1) * cardGap) / GridColumns;
            float cardHeight = (1f - (GridRows + 1) * cardGap) / GridRows;

            for (int i = 0; i < pagePlayers.Count; i++)
            {
                var target = pagePlayers[i];
                int col = i % GridColumns;
                int row = i / GridColumns;

                // Invert row so first player appears at top-left
                float xMin = cardGap + col * (cardWidth + cardGap);
                float xMax = xMin + cardWidth;
                float yMax = 1f - (cardGap + row * (cardHeight + cardGap));
                float yMin = yMax - cardHeight;

                string cardName = content + $"_Card_{i}";

                // Card background
                container.Add(new CuiPanel
                {
                    Image = { Color = ColorCardBg },
                    RectTransform = { AnchorMin = $"{xMin} {yMin}", AnchorMax = $"{xMax} {yMax}" }
                }, content + "_Grid", cardName);

                // Player name
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = TruncateString(target.displayName, 16),
                        FontSize = 11,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.05 0.5", AnchorMax = "0.95 0.9" }
                }, cardName);

                // Request button
                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = ColorTabActive,
                        Command = $"tpgui.tpr {target.displayName}"
                    },
                    Text =
                    {
                        Text = "REQUEST",
                        FontSize = 10,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.1 0.08", AnchorMax = "0.9 0.42" }
                }, cardName);
            }

            // Empty state
            if (pagePlayers.Count == 0)
            {
                string emptyMsg = string.IsNullOrEmpty(search)
                    ? "No other players online"
                    : $"No players found matching '{search}'";

                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = emptyMsg,
                        FontSize = 14,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorTextMuted,
                        Font = "robotocondensed-regular.ttf"
                    },
                    RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 0.7" }
                }, content + "_Grid");
            }

            // --- Pagination controls ---
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.07" }
            }, content, content + "_Pagination");

            // Previous button
            string prevColor = currentPage > 0 ? ColorTabInactive : "0.15 0.15 0.15 0.5";
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = prevColor,
                    Command = currentPage > 0 ? "tpgui.page prev" : ""
                },
                Text =
                {
                    Text = "◀ PREV",
                    FontSize = 11,
                    Align = TextAnchor.MiddleCenter,
                    Color = currentPage > 0 ? ColorText : ColorTextMuted,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.3 0", AnchorMax = "0.42 1" }
            }, content + "_Pagination");

            // Page indicator
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = $"Page {currentPage + 1} / {totalPages}",
                    FontSize = 11,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorTextMuted,
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = "0.43 0", AnchorMax = "0.57 1" }
            }, content + "_Pagination");

            // Next button
            string nextColor = currentPage < totalPages - 1 ? ColorTabInactive : "0.15 0.15 0.15 0.5";
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = nextColor,
                    Command = currentPage < totalPages - 1 ? "tpgui.page next" : ""
                },
                Text =
                {
                    Text = "NEXT ▶",
                    FontSize = 11,
                    Align = TextAnchor.MiddleCenter,
                    Color = currentPage < totalPages - 1 ? ColorText : ColorTextMuted,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.58 0", AnchorMax = "0.7 1" }
            }, content + "_Pagination");
        }

        #endregion

        #region Homes Tab

        private void ShowHomesTab(ref CuiElementContainer container, BasePlayer player)
        {
            string body = MainPanel + "_Body";

            // Content area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0.02 0.02", AnchorMax = "0.98 0.86" }
            }, body, body + "_HomesContent");

            string content = body + "_HomesContent";

            // Header row
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0 0.9", AnchorMax = "1 0.98" }
            }, content, content + "_HomeHeader");

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "YOUR HOMES",
                    FontSize = 14,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "0.5 1" }
            }, content + "_HomeHeader");

            // Set Home button
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = ColorAccept,
                    Command = "tpgui.sethome"
                },
                Text =
                {
                    Text = "+ SET HOME",
                    FontSize = 11,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.78 0.1", AnchorMax = "0.98 0.9" }
            }, content + "_HomeHeader");

            // Divider
            container.Add(new CuiPanel
            {
                Image = { Color = ColorDivider },
                RectTransform = { AnchorMin = "0 0.885", AnchorMax = "1 0.888" }
            }, content);

            // Get homes from NTeleportation
            var homes = GetPlayerHomes(player);

            if (homes == null || homes.Count == 0)
            {
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = "You have no homes set.\nUse the '+ SET HOME' button to save your current location.",
                        FontSize = 13,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorTextMuted,
                        Font = "robotocondensed-regular.ttf"
                    },
                    RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 0.7" }
                }, content);
                return;
            }

            // Scrollable home list area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.87" }
            }, content, content + "_HomeList");

            float rowHeight = 0.08f;
            float rowGap = 0.01f;
            int index = 0;

            foreach (var home in homes)
            {
                if (index >= 10) break; // Max 10 visible homes

                float yMax = 1f - index * (rowHeight + rowGap);
                float yMin = yMax - rowHeight;
                string rowName = content + $"_HomeRow_{index}";

                // Row background
                container.Add(new CuiPanel
                {
                    Image = { Color = ColorCardBg },
                    RectTransform = { AnchorMin = $"0 {yMin}", AnchorMax = $"1 {yMax}" }
                }, content + "_HomeList", rowName);

                // Home name
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = home.Key,
                        FontSize = 13,
                        Align = TextAnchor.MiddleLeft,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.03 0", AnchorMax = "0.4 1" }
                }, rowName);

                // Coordinates
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = $"({home.Value.x:F0}, {home.Value.y:F0}, {home.Value.z:F0})",
                        FontSize = 10,
                        Align = TextAnchor.MiddleLeft,
                        Color = ColorTextMuted,
                        Font = "robotocondensed-regular.ttf"
                    },
                    RectTransform = { AnchorMin = "0.4 0", AnchorMax = "0.65 1" }
                }, rowName);

                // Teleport button
                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = ColorTabActive,
                        Command = $"tpgui.home {home.Key}"
                    },
                    Text =
                    {
                        Text = "TELEPORT",
                        FontSize = 10,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.68 0.15", AnchorMax = "0.83 0.85" }
                }, rowName);

                // Delete button
                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = ColorDeny,
                        Command = $"tpgui.removehome {home.Key}"
                    },
                    Text =
                    {
                        Text = "DELETE",
                        FontSize = 10,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.85 0.15", AnchorMax = "0.98 0.85" }
                }, rowName);

                index++;
            }
        }

        #endregion

        #region Warps Tab

        private void ShowWarpsTab(ref CuiElementContainer container, BasePlayer player)
        {
            string body = MainPanel + "_Body";

            // Content area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0.02 0.02", AnchorMax = "0.98 0.86" }
            }, body, body + "_WarpsContent");

            string content = body + "_WarpsContent";

            // Header
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "SERVER WARPS",
                    FontSize = 14,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0 0.9", AnchorMax = "0.5 0.98" }
            }, content);

            // Divider
            container.Add(new CuiPanel
            {
                Image = { Color = ColorDivider },
                RectTransform = { AnchorMin = "0 0.885", AnchorMax = "1 0.888" }
            }, content);

            // Get warps from NTeleportation
            var warps = GetWarps();

            if (warps == null || warps.Count == 0)
            {
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = "No warps available on this server.",
                        FontSize = 13,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorTextMuted,
                        Font = "robotocondensed-regular.ttf"
                    },
                    RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 0.7" }
                }, content);
                return;
            }

            // Warp list area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.87" }
            }, content, content + "_WarpList");

            float rowHeight = 0.08f;
            float rowGap = 0.01f;
            int index = 0;

            foreach (var warp in warps)
            {
                if (index >= 10) break; // Max 10 visible warps

                float yMax = 1f - index * (rowHeight + rowGap);
                float yMin = yMax - rowHeight;
                string rowName = content + $"_WarpRow_{index}";

                // Row background
                container.Add(new CuiPanel
                {
                    Image = { Color = ColorCardBg },
                    RectTransform = { AnchorMin = $"0 {yMin}", AnchorMax = $"1 {yMax}" }
                }, content + "_WarpList", rowName);

                // Warp name
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = warp.Key,
                        FontSize = 13,
                        Align = TextAnchor.MiddleLeft,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.03 0", AnchorMax = "0.5 1" }
                }, rowName);

                // Coordinates
                container.Add(new CuiLabel
                {
                    Text =
                    {
                        Text = $"({warp.Value.x:F0}, {warp.Value.y:F0}, {warp.Value.z:F0})",
                        FontSize = 10,
                        Align = TextAnchor.MiddleLeft,
                        Color = ColorTextMuted,
                        Font = "robotocondensed-regular.ttf"
                    },
                    RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.75 1" }
                }, rowName);

                // Teleport button
                container.Add(new CuiButton
                {
                    Button =
                    {
                        Color = ColorTabActive,
                        Command = $"tpgui.warp {warp.Key}"
                    },
                    Text =
                    {
                        Text = "TELEPORT",
                        FontSize = 10,
                        Align = TextAnchor.MiddleCenter,
                        Color = ColorText,
                        Font = "robotocondensed-bold.ttf"
                    },
                    RectTransform = { AnchorMin = "0.82 0.15", AnchorMax = "0.98 0.85" }
                }, rowName);

                index++;
            }
        }

        #endregion

        #region Settings Tab

        private void ShowSettingsTab(ref CuiElementContainer container, BasePlayer player)
        {
            string body = MainPanel + "_Body";

            // Content area
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTransparent },
                RectTransform = { AnchorMin = "0.02 0.02", AnchorMax = "0.98 0.86" }
            }, body, body + "_SettingsContent");

            string content = body + "_SettingsContent";

            // Header
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "TELEPORT SETTINGS",
                    FontSize = 14,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0 0.9", AnchorMax = "0.5 0.98" }
            }, content);

            // Divider
            container.Add(new CuiPanel
            {
                Image = { Color = ColorDivider },
                RectTransform = { AnchorMin = "0 0.885", AnchorMax = "1 0.888" }
            }, content);

            // Player info card
            container.Add(new CuiPanel
            {
                Image = { Color = ColorCardBg },
                RectTransform = { AnchorMin = "0 0.6", AnchorMax = "1 0.87" }
            }, content, content + "_InfoCard");

            // Player name
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = player.displayName,
                    FontSize = 16,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.03 0.55", AnchorMax = "0.7 0.95" }
            }, content + "_InfoCard");

            // Steam ID
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = $"Steam ID: {player.UserIDString}",
                    FontSize = 10,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorTextMuted,
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = "0.03 0.1", AnchorMax = "0.7 0.5" }
            }, content + "_InfoCard");

            // NTeleportation status badge
            string ntpStatus = NTeleportation != null ? "CONNECTED" : "NOT FOUND";
            string ntpColor = NTeleportation != null ? ColorAccept : ColorDeny;

            container.Add(new CuiPanel
            {
                Image = { Color = ntpColor },
                RectTransform = { AnchorMin = "0.75 0.3", AnchorMax = "0.97 0.7" }
            }, content + "_InfoCard", content + "_StatusBadge");

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = ntpStatus,
                    FontSize = 10,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
            }, content + "_StatusBadge");

            // Teleport info section
            container.Add(new CuiPanel
            {
                Image = { Color = ColorCardBg },
                RectTransform = { AnchorMin = "0 0.15", AnchorMax = "0.48 0.57" }
            }, content, content + "_TprInfo");

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "TELEPORT REQUESTS",
                    FontSize = 12,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorTabActive,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.04 0.78", AnchorMax = "0.96 0.96" }
            }, content + "_TprInfo");

            // TPR info rows
            AddSettingRow(ref container, content + "_TprInfo", "Cooldown", GetNTPSetting("TPRCooldown", "300s"), 0.55f);
            AddSettingRow(ref container, content + "_TprInfo", "Daily Limit", GetNTPSetting("TPRDailyLimit", "5"), 0.33f);
            AddSettingRow(ref container, content + "_TprInfo", "Countdown", GetNTPSetting("TPRCountdown", "15s"), 0.11f);

            // Homes info section
            container.Add(new CuiPanel
            {
                Image = { Color = ColorCardBg },
                RectTransform = { AnchorMin = "0.52 0.15", AnchorMax = "1 0.57" }
            }, content, content + "_HomesInfo");

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "HOME TELEPORTS",
                    FontSize = 12,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorTabActive,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.04 0.78", AnchorMax = "0.96 0.96" }
            }, content + "_HomesInfo");

            var homes = GetPlayerHomes(player);
            int homeCount = homes?.Count ?? 0;

            AddSettingRow(ref container, content + "_HomesInfo", "Homes Set", $"{homeCount}", 0.55f);
            AddSettingRow(ref container, content + "_HomesInfo", "Max Homes", GetNTPSetting("HomeMaxHomes", "3"), 0.33f);
            AddSettingRow(ref container, content + "_HomesInfo", "Cooldown", GetNTPSetting("HomeCooldown", "300s"), 0.11f);

            // Plugin version footer
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "CorrosionTeleportGUI v1.0.0 — corrosionmgmt.com",
                    FontSize = 9,
                    Align = TextAnchor.MiddleCenter,
                    Color = "0.3 0.3 0.3 1",
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.08" }
            }, content);
        }

        private void AddSettingRow(ref CuiElementContainer container, string parent, string label, string value, float yCenter)
        {
            float rowHeight = 0.16f;
            float yMin = yCenter - rowHeight / 2f;
            float yMax = yCenter + rowHeight / 2f;

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = label,
                    FontSize = 11,
                    Align = TextAnchor.MiddleLeft,
                    Color = ColorSettingLabel,
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = $"0.04 {yMin}", AnchorMax = $"0.55 {yMax}" }
            }, parent);

            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = value,
                    FontSize = 11,
                    Align = TextAnchor.MiddleRight,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = $"0.55 {yMin}", AnchorMax = $"0.96 {yMax}" }
            }, parent);
        }

        #endregion

        #region TPR Popup

        private void ShowTPRPopup(BasePlayer target, string requesterName)
        {
            if (target == null) return;

            DestroyPopupUI(target);

            var container = new CuiElementContainer();

            // Popup overlay (smaller, positioned at top-center)
            container.Add(new CuiPanel
            {
                Image = { Color = "0.05 0.05 0.05 0.92" },
                RectTransform = { AnchorMin = "0.3 0.75", AnchorMax = "0.7 0.95" },
                CursorEnabled = true
            }, "Overlay", PopupPanel);

            // Inner panel
            container.Add(new CuiPanel
            {
                Image = { Color = ColorPanel },
                RectTransform = { AnchorMin = "0.02 0.04", AnchorMax = "0.98 0.96" }
            }, PopupPanel, PopupPanel + "_Inner");

            string inner = PopupPanel + "_Inner";

            // Accent bar at top
            container.Add(new CuiPanel
            {
                Image = { Color = ColorTabActive },
                RectTransform = { AnchorMin = "0 0.92", AnchorMax = "1 1" }
            }, inner);

            // Title
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = "INCOMING TELEPORT REQUEST",
                    FontSize = 13,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorTabActive,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0 0.62", AnchorMax = "1 0.88" }
            }, inner);

            // Requester name
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = $"<b>{requesterName}</b> wants to teleport to you",
                    FontSize = 12,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-regular.ttf"
                },
                RectTransform = { AnchorMin = "0 0.38", AnchorMax = "1 0.62" }
            }, inner);

            // Accept button
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = ColorAccept,
                    Command = "tpgui.accept"
                },
                Text =
                {
                    Text = "ACCEPT",
                    FontSize = 13,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.05 0.06", AnchorMax = "0.35 0.34" }
            }, inner);

            // Deny button
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = ColorDeny,
                    Command = "tpgui.deny"
                },
                Text =
                {
                    Text = "DENY",
                    FontSize = 13,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.4 0.06", AnchorMax = "0.7 0.34" }
            }, inner);

            // Close button (X)
            container.Add(new CuiButton
            {
                Button =
                {
                    Color = ColorClose,
                    Command = "tpgui.popup.close"
                },
                Text =
                {
                    Text = "✕",
                    FontSize = 12,
                    Align = TextAnchor.MiddleCenter,
                    Color = ColorText,
                    Font = "robotocondensed-bold.ttf"
                },
                RectTransform = { AnchorMin = "0.78 0.06", AnchorMax = "0.95 0.34" }
            }, inner);

            CuiHelper.AddUi(target, container);

            // Auto-dismiss after timeout
            if (popupTimers.TryGetValue(target.userID, out var existingTimer))
            {
                existingTimer?.Destroy();
            }

            popupTimers[target.userID] = timer.Once(PopupTimeout, () =>
            {
                if (target != null && target.IsConnected)
                {
                    DestroyPopupUI(target);
                    target.ChatMessage("<color=#CD6632>[Corrosion TP]</color> Teleport request timed out.");
                }
                popupTimers.Remove(target.userID);
            });
        }

        #endregion

        #region Helpers

        private void DestroyUI(BasePlayer player)
        {
            if (player == null) return;
            CuiHelper.DestroyUi(player, MainPanel);
        }

        private void DestroyPopupUI(BasePlayer player)
        {
            if (player == null) return;
            CuiHelper.DestroyUi(player, PopupPanel);

            if (popupTimers.TryGetValue(player.userID, out var popupTimer))
            {
                popupTimer?.Destroy();
                popupTimers.Remove(player.userID);
            }
        }

        private void RefreshPlayerCache()
        {
            cachedPlayers = BasePlayer.activePlayerList?.ToList() ?? new List<BasePlayer>();
        }

        private int GetPlayerPage(BasePlayer player)
        {
            int page;
            if (playerPages.TryGetValue(player.userID, out page))
                return page;
            return 0;
        }

        private string GetPlayerSearch(BasePlayer player)
        {
            string search;
            if (playerSearches.TryGetValue(player.userID, out search))
                return search;
            return string.Empty;
        }

        private string GetPlayerTab(BasePlayer player)
        {
            string tab;
            if (playerTabs.TryGetValue(player.userID, out tab))
                return tab;
            return "teleport";
        }

        /// <summary>
        /// Retrieves the player's homes from NTeleportation via its API.
        /// Returns an empty dictionary if NTeleportation is not loaded or data is unavailable.
        /// </summary>
        private Dictionary<string, Vector3> GetPlayerHomes(BasePlayer player)
        {
            if (NTeleportation == null || player == null)
                return new Dictionary<string, Vector3>();

            try
            {
                var result = NTeleportation.Call("API_GetHomes", player);
                if (result is Dictionary<string, Vector3> homes)
                    return homes;

                // Some versions may return a different type — attempt generic dictionary conversion
                if (result != null)
                {
                    var dict = new Dictionary<string, Vector3>();
                    var objDict = result as Dictionary<string, object>;
                    if (objDict != null)
                    {
                        foreach (var kvp in objDict)
                        {
                            if (kvp.Value is Vector3 vec)
                                dict[kvp.Key] = vec;
                        }
                        return dict;
                    }
                }
            }
            catch (Exception ex)
            {
                PrintError($"Failed to get homes for {player.displayName}: {ex.Message}");
            }

            return new Dictionary<string, Vector3>();
        }

        /// <summary>
        /// Retrieves server warps from NTeleportation data files.
        /// Returns an empty dictionary if unavailable.
        /// </summary>
        private Dictionary<string, Vector3> GetWarps()
        {
            if (NTeleportation == null)
                return new Dictionary<string, Vector3>();

            try
            {
                var result = NTeleportation.Call("API_GetWarps");
                if (result is Dictionary<string, Vector3> warps)
                    return warps;

                // Attempt to read from NTeleportation data file directly as fallback
                var dataFile = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, object>>("NTeleportation");
                if (dataFile != null && dataFile.ContainsKey("Warps"))
                {
                    var warpsObj = dataFile["Warps"];
                    if (warpsObj is Dictionary<string, object> warpsDict)
                    {
                        var parsed = new Dictionary<string, Vector3>();
                        foreach (var kvp in warpsDict)
                        {
                            try
                            {
                                if (kvp.Value is Dictionary<string, object> posData)
                                {
                                    float x = Convert.ToSingle(posData.ContainsKey("x") ? posData["x"] : 0);
                                    float y = Convert.ToSingle(posData.ContainsKey("y") ? posData["y"] : 0);
                                    float z = Convert.ToSingle(posData.ContainsKey("z") ? posData["z"] : 0);
                                    parsed[kvp.Key] = new Vector3(x, y, z);
                                }
                            }
                            catch
                            {
                                // Skip malformed warp entries
                            }
                        }
                        return parsed;
                    }
                }
            }
            catch (Exception ex)
            {
                PrintError($"Failed to get warps: {ex.Message}");
            }

            return new Dictionary<string, Vector3>();
        }

        /// <summary>
        /// Gets NTeleportation configuration values for display in settings.
        /// Returns the default value if NTeleportation is not available or the setting can't be read.
        /// </summary>
        private string GetNTPSetting(string key, string defaultValue)
        {
            if (NTeleportation == null)
                return defaultValue;

            try
            {
                var result = NTeleportation.Call("API_GetConfig", key);
                if (result != null)
                    return result.ToString();
            }
            catch
            {
                // Silently fall back to default — this is a cosmetic read
            }

            return defaultValue;
        }

        /// <summary>
        /// Truncates a string to the specified max length, appending "..." if truncated.
        /// </summary>
        private string TruncateString(string input, int maxLength)
        {
            if (string.IsNullOrEmpty(input) || input.Length <= maxLength)
                return input;
            return input.Substring(0, maxLength - 3) + "...";
        }

        #endregion
    }
}
