using CompanionServer;
using Facepunch;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using UnityEngine;
using static BaseEntity;

namespace Oxide.Plugins
{
    [Info("Master Switch", "Lincoln", "2.0.0")]
    [Description("Toggle things on or off with a command or GUI.")]
    public class MasterSwitch : RustPlugin
    {
        private const float MaxValue = 500;
        private const float MinValue = 0f;
        private const string PermUse = "MasterSwitch.use";
        private float radius;
        private readonly List<Timer> doorTimerList = new List<Timer>();
        private readonly Dictionary<ulong, float> playerRadiusSettings = new Dictionary<ulong, float>();
        private readonly List<ulong> playersWithMenuOpen = new List<ulong>();

        #region Permissions

        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
        }

        #endregion

        #region Checks

        private bool HasPermission(BasePlayer player)
        {
            if (!permission.UserHasPermission(player.UserIDString, PermUse))
            {
                player.ChatMessage(lang.GetMessage("NoPerm", this, player.UserIDString));
                return false;
            }

            return true;
        }

        private bool HasArgs(BasePlayer player, string[] args)
        {
            if (args == null || args.Length < 2 || !float.TryParse(args[1], out radius))
            {
                player.ChatMessage(lang.GetMessage("Syntax", this, player.UserIDString));
                return false;
            }

            return true;
        }

        private bool HasRadius(BasePlayer player, float radius)
        {
            if (radius <= MinValue || radius > MaxValue)
            {
                player.ChatMessage(lang.GetMessage("Radius", this, player.UserIDString));
                return false;
            }

            return true;
        }

        #endregion

        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["LightTurnOn"] = "<color=#ffc34d>MasterSwitch</color>: {0} Lights/electric items turned on within a {1}f radius.",
                ["LightTurnOff"] = "<color=#ffc34d>MasterSwitch</color>: {0} Lights/electric items turned off within a {1}f radius.",
                ["DoorOpen"] = "<color=#ffc34d>MasterSwitch</color>: {0} Doors opened within a {1}f radius.",
                ["DoorClose"] = "<color=#ffc34d>MasterSwitch</color>: {0} Doors closed within a {1}f radius.",
                ["TurretStart"] = "<color=#ffc34d>MasterSwitch</color>: {0} Turrets started within a {1}f radius.",
                ["TurretStop"] = "<color=#ffc34d>MasterSwitch</color>: {0} Turrets stopped within a {1}f radius.",
                ["BearTrapArm"] = "<color=#ffc34d>MasterSwitch</color>: {0} Bear traps have been armed within a {1}f radius.",
                ["BearTrapDisArm"] = "<color=#ffc34d>MasterSwitch</color>: {0} Bear traps have been disarmed within a {1}f radius.",
                ["MineExplode"] = "<color=#ffc34d>MasterSwitch</color>: {0} Mines have exploded within a {1}f radius.",
                ["IgnitableLit"] = "<color=#ffc34d>MasterSwitch</color>: {0} Ignitables have been lit within a {1}f radius.",
                ["MachinesOn"] = "<color=#ffc34d>MasterSwitch</color>: {0} Fog/snow machines activated within a {1}f radius.",
                ["MachinesOff"] = "<color=#ffc34d>MasterSwitch</color>: {0} Fog/snow machines de-activated within a {1}f radius.",
                ["NoPerm"] = "<color=#ffc34d>MasterSwitch</color>: You do not have permissions to use this.",
                ["Syntax"] = "<color=#ffc34d>MasterSwitch</color>: Incorrect syntax. Example: /ms <command> <radius> or use /msmenu for GUI",
                ["Radius"] = "<color=#ffc34d>MasterSwitch</color>: Radius out of bounds, choose 1 - 500",
            }, this);
        }

        #endregion

        #region GUI

        [ChatCommand("msmenu")]
        private void OpenMenuCommand(BasePlayer player, string command, string[] args)
        {
            if (player == null || !HasPermission(player)) return;
            
            // Check if menu is already open
            if (playersWithMenuOpen.Contains(player.userID))
            {
                SendReply(player, "Menu is already open. Close it first.");
                return;
            }
            
            // Set default radius if not set
            if (!playerRadiusSettings.ContainsKey(player.userID))
                playerRadiusSettings[player.userID] = 50f;
            
            OpenMainMenu(player);
        }

        private void OpenMainMenu(BasePlayer player)
        {
            var container = new CuiElementContainer();
            var mainPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.95" },
                RectTransform = { AnchorMin = "0.35 0.25", AnchorMax = "0.65 0.75" },
                CursorEnabled = true
            }, "Overlay", "MasterSwitchMain");

            // Title
            container.Add(new CuiLabel
            {
                Text = {
                    Text = "MASTER SWITCH CONTROL",
                    FontSize = 20,
                    Align = TextAnchor.MiddleCenter,
                    Color = "1 0.8 0.3 1"
                },
                RectTransform = { AnchorMin = "0.05 0.90", AnchorMax = "0.95 0.98" }
            }, mainPanel);

            // Current radius display
            float currentRadius = playerRadiusSettings[player.userID];
            container.Add(new CuiLabel
            {
                Text = {
                    Text = $"Current Radius: {currentRadius}m",
                    FontSize = 14,
                    Align = TextAnchor.MiddleCenter,
                    Color = "0.8 0.8 0.8 1"
                },
                RectTransform = { AnchorMin = "0.05 0.83", AnchorMax = "0.95 0.89" }
            }, mainPanel);

            // Radius adjustment buttons
            AddButton(container, mainPanel, "- 10m", "0.05 0.75", "0.23 0.82", "masterswitch.radius -10", 12);
            AddButton(container, mainPanel, "- 50m", "0.25 0.75", "0.43 0.82", "masterswitch.radius -50", 12);
            AddButton(container, mainPanel, "+ 50m", "0.57 0.75", "0.75 0.82", "masterswitch.radius 50", 12);
            AddButton(container, mainPanel, "+ 10m", "0.77 0.75", "0.95 0.82", "masterswitch.radius 10", 12);

            // Category buttons - arranged in a grid
            float startY = 0.65f;
            float buttonHeight = 0.09f;
            float spacing = 0.015f;

            // Row 1: Doors and Lights
            AddCategoryButton(container, mainPanel, "🚪 DOORS", "0.05", startY, "0.48", startY + buttonHeight, "masterswitch.category doors");
            AddCategoryButton(container, mainPanel, "💡 LIGHTS", "0.52", startY, "0.95", startY + buttonHeight, "masterswitch.category lights");

            startY -= (buttonHeight + spacing);

            // Row 2: Turrets and Traps
            AddCategoryButton(container, mainPanel, "🔫 TURRETS", "0.05", startY, "0.48", startY + buttonHeight, "masterswitch.category turrets");
            AddCategoryButton(container, mainPanel, "⚠️ TRAPS", "0.52", startY, "0.95", startY + buttonHeight, "masterswitch.category traps");

            startY -= (buttonHeight + spacing);

            // Row 3: Machines and Special
            AddCategoryButton(container, mainPanel, "⚙️ MACHINES", "0.05", startY, "0.48", startY + buttonHeight, "masterswitch.category machines");
            AddCategoryButton(container, mainPanel, "🔥 SPECIAL", "0.52", startY, "0.95", startY + buttonHeight, "masterswitch.category special");

            // Close button
            AddButton(container, mainPanel, "✖ CLOSE", "0.35 0.02", "0.65 0.10", "masterswitch.close", 14, "0.8 0.2 0.2 1");

            CuiHelper.DestroyUi(player, "MasterSwitchMain");
            CuiHelper.AddUi(player, container);
            
            // Track that this player has menu open
            if (!playersWithMenuOpen.Contains(player.userID))
                playersWithMenuOpen.Add(player.userID);
        }

        private void OpenCategoryMenu(BasePlayer player, string category)
        {
            var container = new CuiElementContainer();
            var mainPanel = container.Add(new CuiPanel
            {
                Image = { Color = "0.1 0.1 0.1 0.95" },
                RectTransform = { AnchorMin = "0.35 0.30", AnchorMax = "0.65 0.70" },
                CursorEnabled = true
            }, "Overlay", "MasterSwitchCategory");

            string title = "";
            float startY = 0.75f;
            float buttonHeight = 0.12f;
            float spacing = 0.02f;

            switch (category)
            {
                case "doors":
                    title = "🚪 DOOR CONTROLS";
                    AddActionButton(container, mainPanel, "Open All Doors", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action open");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Close All Doors", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action close");
                    break;

                case "lights":
                    title = "💡 LIGHT CONTROLS";
                    AddActionButton(container, mainPanel, "Turn All Lights ON", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action on");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Turn All Lights OFF", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action off");
                    break;

                case "turrets":
                    title = "🔫 TURRET CONTROLS";
                    AddActionButton(container, mainPanel, "Start All Turrets", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action start");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Stop All Turrets", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action stop");
                    break;

                case "traps":
                    title = "⚠️ TRAP CONTROLS";
                    AddActionButton(container, mainPanel, "Arm Bear Traps", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action arm");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Disarm Bear Traps", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action disarm");
                    break;

                case "machines":
                    title = "⚙️ MACHINE CONTROLS";
                    AddActionButton(container, mainPanel, "Activate Machines", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action activate");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Deactivate Machines", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action deactivate");
                    break;

                case "special":
                    title = "🔥 SPECIAL ACTIONS";
                    AddActionButton(container, mainPanel, "Ignite Fireworks", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action ignite");
                    startY -= (buttonHeight + spacing);
                    AddActionButton(container, mainPanel, "Explode Mines", "0.1", startY, "0.9", startY + buttonHeight, "masterswitch.action explode");
                    break;
            }

            // Title
            container.Add(new CuiLabel
            {
                Text = {
                    Text = title,
                    FontSize = 18,
                    Align = TextAnchor.MiddleCenter,
                    Color = "1 0.8 0.3 1"
                },
                RectTransform = { AnchorMin = "0.05 0.88", AnchorMax = "0.95 0.96" }
            }, mainPanel);

            // Back button
            AddButton(container, mainPanel, "← BACK", "0.1 0.05", "0.45 0.13", "masterswitch.back", 14, "0.3 0.3 0.8 1");
            
            // Close button
            AddButton(container, mainPanel, "✖ CLOSE", "0.55 0.05", "0.9 0.13", "masterswitch.close", 14, "0.8 0.2 0.2 1");

            CuiHelper.DestroyUi(player, "MasterSwitchCategory");
            CuiHelper.AddUi(player, container);
        }

        private void AddButton(CuiElementContainer container, string parent, string text, string anchorMin, string anchorMax, string command, int fontSize, string color = "0.4 0.4 0.4 1")
        {
            container.Add(new CuiButton
            {
                Button = { Command = command, Color = color },
                RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax },
                Text = { Text = text, FontSize = fontSize, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
            }, parent);
        }

        private void AddCategoryButton(CuiElementContainer container, string parent, string text, string minX, float minY, string maxX, float maxY, string command)
        {
            container.Add(new CuiButton
            {
                Button = { Command = command, Color = "0.3 0.5 0.7 1" },
                RectTransform = { AnchorMin = $"{minX} {minY}", AnchorMax = $"{maxX} {maxY}" },
                Text = { Text = text, FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
            }, parent);
        }

        private void AddActionButton(CuiElementContainer container, string parent, string text, string minX, float minY, string maxX, float maxY, string command)
        {
            container.Add(new CuiButton
            {
                Button = { Command = command, Color = "0.2 0.6 0.3 1" },
                RectTransform = { AnchorMin = $"{minX} {minY}", AnchorMax = $"{maxX} {maxY}" },
                Text = { Text = text, FontSize = 16, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1" }
            }, parent);
        }

        [ConsoleCommand("masterswitch.radius")]
        private void RadiusCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || !HasPermission(player)) return;

            if (arg.Args == null || arg.Args.Length == 0) return;

            if (!float.TryParse(arg.Args[0], out float adjustment)) return;

            if (!playerRadiusSettings.ContainsKey(player.userID))
                playerRadiusSettings[player.userID] = 50f;

            playerRadiusSettings[player.userID] += adjustment;
            playerRadiusSettings[player.userID] = Mathf.Clamp(playerRadiusSettings[player.userID], MinValue + 1, MaxValue);

            OpenMainMenu(player);
        }

        [ConsoleCommand("masterswitch.category")]
        private void CategoryCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || !HasPermission(player)) return;

            if (arg.Args == null || arg.Args.Length == 0) return;

            OpenCategoryMenu(player, arg.Args[0]);
        }

        [ConsoleCommand("masterswitch.action")]
        private void ActionCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null || !HasPermission(player)) return;

            if (arg.Args == null || arg.Args.Length == 0) return;

            string action = arg.Args[0];
            float radius = playerRadiusSettings.ContainsKey(player.userID) ? playerRadiusSettings[player.userID] : 50f;

            var baseEntityList = FindBaseEntity(player.transform.position, radius);
            var entityCount = new List<string>();

            switch (action)
            {
                case "open":
                    ToggleDoors(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("DoorOpen", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "close":
                    ToggleDoors(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("DoorClose", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "on":
                    ToggleLightsAndDevices(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("LightTurnOn", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "off":
                    ToggleLightsAndDevices(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("LightTurnOff", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "start":
                    ToggleTurrets(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("TurretStart", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "stop":
                    ToggleTurrets(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("TurretStop", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "arm":
                    ToggleBearTraps(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("BearTrapArm", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "disarm":
                    ToggleBearTraps(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("BearTrapDisArm", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "ignite":
                    IgniteEntities(baseEntityList, entityCount);
                    player.ChatMessage(string.Format(lang.GetMessage("IgnitableLit", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "explode":
                    ExplodeEntities(baseEntityList, entityCount);
                    player.ChatMessage(string.Format(lang.GetMessage("MineExplode", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "activate":
                    ToggleMachines(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("MachinesOn", this, player.UserIDString), entityCount.Count, radius));
                    break;
                case "deactivate":
                    ToggleMachines(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("MachinesOff", this, player.UserIDString), entityCount.Count, radius));
                    break;
            }

            timer.Once(0.2f, () => OpenCategoryMenu(player, GetCategoryForAction(action)));
        }

        private string GetCategoryForAction(string action)
        {
            switch (action)
            {
                case "open":
                case "close":
                    return "doors";
                case "on":
                case "off":
                    return "lights";
                case "start":
                case "stop":
                    return "turrets";
                case "arm":
                case "disarm":
                    return "traps";
                case "activate":
                case "deactivate":
                    return "machines";
                case "ignite":
                case "explode":
                    return "special";
                default:
                    return "doors";
            }
        }

        [ConsoleCommand("masterswitch.back")]
        private void BackCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;

            CuiHelper.DestroyUi(player, "MasterSwitchCategory");
            OpenMainMenu(player);
        }

        [ConsoleCommand("masterswitch.close")]
        private void CloseCommand(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player == null) return;

            CuiHelper.DestroyUi(player, "MasterSwitchMain");
            CuiHelper.DestroyUi(player, "MasterSwitchCategory");
            
            // Remove from open menu tracking
            playersWithMenuOpen.Remove(player.userID);
        }

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, "MasterSwitchMain");
                CuiHelper.DestroyUi(player, "MasterSwitchCategory");
            }
            
            // Clear tracking list
            playersWithMenuOpen.Clear();
        }

        #endregion

        #region Unity

        private List<BaseEntity> FindBaseEntity(Vector3 pos, float radius)
        {
            var colliders = Physics.OverlapSphere(pos, radius);
            var entities = new List<BaseEntity>();
            foreach (var collider in colliders)
            {
                var entity = collider.GetComponentInParent<BaseEntity>();
                if (entity != null && !entities.Contains(entity))
                    entities.Add(entity);
            }

            return entities;
        }

        #endregion

        #region Commands

        [ChatCommand("ms")]
        private void ToggleCommand(BasePlayer player, string command, string[] args)
        {
            if (player == null || !HasPermission(player) || !HasArgs(player, args) || !HasRadius(player, radius)) return;

            var baseEntityList = FindBaseEntity(player.transform.position, radius);
            var entityCount = new List<string>();

            switch (args[0].ToLower())
            {
                case "open":
                    ToggleDoors(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("DoorOpen", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "timer":
                    Puts($"{doorTimerList.Count} active timers running.");
                    break;

                case "close":
                    ToggleDoors(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("DoorClose", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "on":
                    ToggleLightsAndDevices(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("LightTurnOn", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "off":
                    ToggleLightsAndDevices(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("LightTurnOff", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "start":
                    ToggleTurrets(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("TurretStart", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "stop":
                    ToggleTurrets(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("TurretStop", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "arm":
                    ToggleBearTraps(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("BearTrapArm", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "disarm":
                    ToggleBearTraps(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("BearTrapDisArm", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "ignite":
                    IgniteEntities(baseEntityList, entityCount);
                    player.ChatMessage(string.Format(lang.GetMessage("IgnitableLit", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "explode":
                    ExplodeEntities(baseEntityList, entityCount);
                    player.ChatMessage(string.Format(lang.GetMessage("MineExplode", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "activate":
                    ToggleMachines(baseEntityList, entityCount, true);
                    player.ChatMessage(string.Format(lang.GetMessage("MachinesOn", this, player.UserIDString), entityCount.Count, radius));
                    break;

                case "deactivate":
                    ToggleMachines(baseEntityList, entityCount, false);
                    player.ChatMessage(string.Format(lang.GetMessage("MachinesOff", this, player.UserIDString), entityCount.Count, radius));
                    break;

                default:
                    player.ChatMessage("Not a valid command type");
                    break;
            }
        }

        private void ToggleDoors(List<BaseEntity> entities, List<string> entityCount, bool open)
        {
            foreach (var entity in entities)
            {
                if (entity is Door door)
                {
                    if (door.IsOpen() == open) continue;
                    door.SetOpen(open);
                    entityCount.Add(door.ToString());
                }
                else if (entity is ProgressDoor progressDoor)
                {
                    if (open)
                    {
                        var doorTimer = timer.Every(0.1f, () =>
                        {
                            if (progressDoor == null) return;
                            progressDoor.AddEnergy(1f);
                            progressDoor.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                        });
                        doorTimerList.Add(doorTimer);
                    }
                    else
                    {
                        foreach (var timer in doorTimerList)
                        {
                            timer.Destroy();
                        }
                        doorTimerList.Clear();
                    }
                    entityCount.Add(progressDoor.ToString());
                }
            }
        }

        [Obsolete]
        private void ToggleLightsAndDevices(List<BaseEntity> entities, List<string> entityCount, bool on)
        {
            foreach (var entity in entities)
            {
                if (entity is BaseOven baseOven)
                {
                    if (baseOven.IsOn() == on) continue;
                    if (on) baseOven.StartCooking();
                    else baseOven.StopCooking();
                    entityCount.Add(baseOven.ToString());
                }
                else if (entity is SirenLight sirenLight)
                {
                    if (sirenLight.IsPowered() == on) continue;
                    sirenLight.SetFlag(BaseEntity.Flags.Reserved8, on, true, true);
                    entityCount.Add(sirenLight.ToString());
                }
                else if (entity is CeilingLight ceilingLight)
                {
                    if (ceilingLight.IsOn() == on) continue;
                    ceilingLight.SetFlag(BaseEntity.Flags.On, on);
                    entityCount.Add(ceilingLight.ToString());
                }
                else if (entity is SearchLight searchLight)
                {
                    if (searchLight.IsPowered() == on) continue;
                    searchLight.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    searchLight.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(searchLight.ToString());
                }
                else if (entity is Candle candle)
                {
                    if (candle.IsOn() == on) continue;
                    candle.SetFlag(BaseEntity.Flags.On, on);
                    entityCount.Add(candle.ToString());
                }
                else if (entity is FlasherLight flasherLight)
                {
                    if (flasherLight.IsPowered() == on || flasherLight.IsOn() == on) continue;
                    flasherLight.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    flasherLight.SetFlag(BaseEntity.Flags.On, on, false, true);
                    flasherLight.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(flasherLight.ToString());
                }
                else if (entity is SimpleLight simpleLight)
                {
                    if (simpleLight.IsOn() == on) continue;
                    simpleLight.SetFlag(BaseEntity.Flags.On, on, true);
                    simpleLight.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(simpleLight.ToString());
                }
                else if (entity is ElectricalHeater heater)
                {
                    if (heater.IsPowered() == on) continue;
                    heater.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    heater.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(heater.ToString());
                }
                else if (entity is FuelGenerator fuelGenerator)
                {
                    if (fuelGenerator.IsOn() == on) continue;
                    if (on)
                    {
                        //fuelGenerator.currentEnergy = 40;
                        fuelGenerator.outputEnergy = 40;
                        fuelGenerator.fuelPerSec = 0f;
                        fuelGenerator.Init();
                        fuelGenerator.SetFlag(BaseEntity.Flags.On, true, true);
                        var itemDef = ItemManager.FindItemDefinition("lowgradefuel");
                        fuelGenerator.InvokeRepeating(fuelGenerator.UpdateCurrentEnergy, 0f, 1f);
                        fuelGenerator.inventory.AddItem(itemDef, 1);
                    }
                    else
                    {
                        fuelGenerator.SetFlag(BaseEntity.Flags.On, false, true);
                        fuelGenerator.Init();
                    }
                    fuelGenerator.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(fuelGenerator.ToString());
                }
                else if (entity is ElectricFurnaceIO electricFurnaceIO)
                {
                    var parentEntity = electricFurnaceIO.GetParentEntity();
                    if (parentEntity is ElectricOven electricOven)
                    {
                        if (on)
                        {
                            electricFurnaceIO.UpdateHasPower(electricFurnaceIO.PowerConsumption, 0);
                        }
                        else
                        {
                            electricFurnaceIO.UpdateHasPower(0, 0);
                        }
                        entityCount.Add(electricOven.ToString());
                    }
                }
                else if (entity is DeployableBoomBox boomBox)
                {
                    if (boomBox.IsOn() == on) continue;
                    boomBox.SetFlag(BaseEntity.Flags.On, on, true);
                    boomBox.SetFlag(BaseEntity.Flags.Reserved8, on, true, true);
                    boomBox.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(boomBox.ToString());
                }
                else if (entity is IndustrialConveyor conveyor)
                {
                    if (conveyor.IsOn() == on) continue;
                    conveyor.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    conveyor.SetFlag(BaseEntity.Flags.On, on, true);
                    conveyor.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(conveyor.ToString());
                }
                else if (entity is NeonSign neonSign)
                {
                    if (neonSign.IsOn() == on) continue;
                    neonSign.SetFlag(BaseEntity.Flags.On, on, true);
                    neonSign.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    if (on) neonSign.InvokeRepeating(neonSign.animationLoopAction, neonSign.animationSpeed, neonSign.animationSpeed);
                    else neonSign.CancelInvoke(neonSign.animationLoopAction);
                    neonSign.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(neonSign.ToString());
                }
                else if (entity is WaterPump waterPump)
                {
                    if (waterPump.IsOn() == on) continue;
                    waterPump.SetFlag(BaseEntity.Flags.On, on, true);
                    waterPump.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    waterPump.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(waterPump.ToString());
                }
                else if (entity is StrobeLight strobeLight)
                {
                    if (strobeLight.IsOn() == on) continue;
                    if (on) strobeLight.frequency = 20f;
                    strobeLight.SetFlag(BaseEntity.Flags.On, on, true);
                    strobeLight.SetFlag(BaseEntity.Flags.Reserved8, on, false, true);
                    strobeLight.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(strobeLight.ToString());
                }
                else if (entity is FishMount fishMount)
                {
                    if (on)
                    {
                        Effect.server.Run(fishMount.FishInteractSound.resourcePath, fishMount.transform.position, Vector3.zero, null, false);
                        fishMount.SetFlag(BaseEntity.Flags.Busy, true, false, true);
                        fishMount.Invoke(() =>
                        {
                            fishMount.SetFlag(BaseEntity.Flags.Busy, false, false, true);
                        }, fishMount.UseCooldown);
                        fishMount.ClientRPC(null, "PlayAnimation");
                    }
                    fishMount.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                    entityCount.Add(fishMount.ToString());
                }

            }
        }


        private void ToggleTurrets(List<BaseEntity> entities, List<string> entityCount, bool on)
        {
            foreach (var entity in entities)
            {
                if (entity is AutoTurret turret)
                {
                    if (turret.IsOn() == on) continue;
                    if (on) turret.InitiateStartup();
                    else turret.InitiateShutdown();
                    entityCount.Add(turret.ToString());
                }
            }
        }

        private void ToggleBearTraps(List<BaseEntity> entities, List<string> entityCount, bool arm)
        {
            foreach (var entity in entities)
            {
                if (entity is BearTrap bearTrap)
                {
                    if (bearTrap.IsOn() == arm) continue;
                    if (arm) bearTrap.Arm();
                    else bearTrap.Fire();
                    entityCount.Add(bearTrap.ToString());
                }
            }
        }

        private void IgniteEntities(List<BaseEntity> entities, List<string> entityCount)
        {
            foreach (var entity in entities)
            {
                if (entity is BaseFirework firework && !firework.IsLit())
                {
                    firework.SetFlag(BaseEntity.Flags.OnFire, true, false, true);
                    firework.Invoke(firework.Begin, firework.fuseLength);
                    entityCount.Add(firework.ToString());
                }
                else if (entity is Igniter igniter)
                {
                    igniter.IgniteRange = 5f;
                    igniter.IgniteStartDelay = 0;
                    igniter.UpdateHasPower(1, 1);
                    igniter.SetFlag(BaseEntity.Flags.Reserved8, true, true, true);
                    entityCount.Add(igniter.ToString());
                }
                else if (entity is ConfettiCannon confettiCannon)
                {
                    confettiCannon.SetFlag(BaseEntity.Flags.OnFire, true, false, true);
                    confettiCannon.Ignite(confettiCannon.transform.position);
                    confettiCannon.DamagePerBlast = 0f;
                    confettiCannon.BlastCooldown = 0f;
                    entityCount.Add(confettiCannon.ToString());
                }
            }
        }

        private void ExplodeEntities(List<BaseEntity> entities, List<string> entityCount)
        {
            foreach (var entity in entities)
            {
                if (entity is Landmine landmine)
                {
                    landmine.Explode();
                    entityCount.Add(landmine.ToString());
                }
            }
        }

        private void ToggleMachines(List<BaseEntity> entities, List<string> entityCount, bool on)
        {
            foreach (var entity in entities)
            {
                if (entity is FogMachine fogMachine)
                {
                    if (fogMachine.IsOn() == on) continue;
                    if (on)
                    {
                        fogMachine.EnableFogField();
                        fogMachine.StartFogging();
                    }
                    else
                    {
                        fogMachine.FinishFogging();
                        fogMachine.DisableNozzle();
                    }
                    fogMachine.SetFlag(BaseEntity.Flags.On, on);
                    entityCount.Add(fogMachine.ToString());
                }
                else if (entity is SnowMachine snowMachine)
                {
                    if (snowMachine.IsOn() == on) continue;
                    if (on)
                    {
                        snowMachine.EnableFogField();
                        snowMachine.StartFogging();
                    }
                    else
                    {
                        snowMachine.FinishFogging();
                        snowMachine.DisableNozzle();
                    }
                    snowMachine.SetFlag(BaseEntity.Flags.On, on);
                    entityCount.Add(snowMachine.ToString());
                }
            }
        }

        #endregion
    }
}
