preciso que quando eu clicar no togle button, os items que estão dentro dos containers que vção ser destruidos, sejam dropados no chão, seria melhor que eles votassem para os novos conteiners:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("IndustrialRecycler", "Marte6", "1.4.4")]
    [Description("Automate recycling by attaching storage and adapters to recyclers.")]
    class IndustrialRecycler : RustPlugin
    {
        #region Fields
        private static IndustrialRecycler _instance;
        private Configuration _config;
        private const string RecyclerPrefabPath = "assets/bundled/prefabs/static/recycler_static.prefab";
        private const string InputStoragePrefabPath = "assets/content/vehicles/boats/rowboat/subents/rowboat_storage.prefab";
        private const string OutputStoragePrefabPath = "assets/prefabs/deployable/hot air balloon/subents/hab_storage.prefab";
        private const string AdapterPrefabPath = "assets/prefabs/deployable/playerioents/industrialadaptors/storageadaptor.deployed.prefab";
        private const string ItemName = "box.wooden.large";
        private const string PermissionUseRecycler = "industrialrecycler.give";
        private const string PermissionVip = "industrialrecycler.vip";
        private const string PermissionAdmin = "industrialrecycler.admin";
        private const string UiOverlayName = "IndustrialRecyclerMainPanel";
        #endregion

        #region Cache
        private readonly Dictionary<ulong, ulong> _recyclerOwners = new();
        private readonly HashSet<ulong> _recyclerItemContainers = new();
        private readonly HashSet<ulong> _inputItemContainers = new();
        private readonly HashSet<ulong> _storageAdapters = new();
        private readonly HashSet<ulong> _playersWithUi = new();
        #endregion

        #region Game Hooks
        private void Init()
        {
            permission.RegisterPermission(PermissionUseRecycler, this);
            permission.RegisterPermission(PermissionVip, this);
            permission.RegisterPermission(PermissionAdmin, this);

            foreach (var command in _config.Commands)
            {
                cmd.AddChatCommand(command, this, nameof(CommandGetRecycler));
            }

            cmd.AddChatCommand("upgraderecycler", this, nameof(CommandUpgradeRecycler));
            cmd.AddChatCommand("togglerecycler", this, nameof(ToggleRecyclerConfig));
            cmd.AddConsoleCommand("industrialrecycler.openinput", this, nameof(OpenInputStorage));
            cmd.AddConsoleCommand("industrialrecycler.openoutput", this, nameof(OpenOutputStorage));
        }

        private void OnServerInitialized()
        {
            _instance = this;

            foreach (var recycler in UnityEngine.Object.FindObjectsOfType<Recycler>())
            {
                if (recycler.OwnerID != 0UL)
                {
                    recycler.gameObject.AddComponent<RecyclerComponent>();
                }
            }
        }

        private void Unload()
        {
            foreach (var recyclerComponent in UnityEngine.Object.FindObjectsOfType<RecyclerComponent>())
            {
                UnityEngine.Object.Destroy(recyclerComponent);
            }

            foreach (var player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, UiOverlayName);
            }
        }

        private void OnItemAddedToContainer(ItemContainer container, Item item)
        {
            Recycler recycler = container.entityOwner as Recycler ?? container.entityOwner?.GetParentEntity() as Recycler;
            if (recycler == null)
                return;

            var recyclerComponent = recycler.GetComponent<RecyclerComponent>();
            if (recyclerComponent == null)
                return;

            bool isMainRecycler = container.entityOwner is Recycler;
            ulong containerUid = container.uid.Value;

            if (isMainRecycler && _recyclerItemContainers.Contains(containerUid))
            {
                ProcessRecyclerItems(recyclerComponent, item);
            }
            else if (!isMainRecycler && _inputItemContainers.Contains(containerUid))
            {
                recyclerComponent.HandleItemTransfers();
            }
        }

        private void OnEntityBuilt(Planner planner, GameObject entityObject)
        {
            var player = planner?.GetOwnerPlayer();
            var baseEntity = entityObject.GetComponent<BaseEntity>();

            if (player == null || baseEntity == null || baseEntity.ShortPrefabName != ItemName || baseEntity.skinID != _config.RecyclerSkinId)
                return;

            int maxRecyclers = _config.MaxRecyclersPerPlayer;

            if (permission.UserHasPermission(player.UserIDString, PermissionAdmin))
            {
                maxRecyclers = int.MaxValue;
            }
            else if (permission.UserHasPermission(player.UserIDString, PermissionVip))
            {
                maxRecyclers = _config.MaxRecyclersVip;
            }

            if (_recyclerOwners.Count(entry => entry.Value == player.userID) >= maxRecyclers)
            {
                player.ChatMessage(lang.GetMessage("RecyclerLimitReached", this, player.UserIDString));
                timer.Once(1, () => GiveRecyclerItem(player));
                NextTick(() => baseEntity?.Kill());
                return;
            }

            if (!InitializeRecyclerPlacement(player, baseEntity))
            {
                player.ChatMessage(lang.GetMessage("InvalidPlacement", this, player.UserIDString));
                timer.Once(1, () => GiveRecyclerItem(player));
            }
            else
            {
                player.ChatMessage(lang.GetMessage("RecyclerPlaced", this, player.UserIDString));
            }

            NextTick(() => baseEntity?.Kill());
        }

        private object CanPickupEntity(BasePlayer player, IndustrialStorageAdaptor adapter)
        {
            if (adapter?.net?.ID.Value != null && _storageAdapters.Contains(adapter.net.ID.Value))
            {
                adapter.GetParentEntity()?.GetParentEntity()?.Kill();
                GiveRecyclerItem(player);
                player.ChatMessage(lang.GetMessage("RecyclerPickedUp", this, player.UserIDString));
                return false;
            }

            return null;
        }

        private object OnEntityKill(Recycler recycler)
        {
            if (!IsRecyclerOwned(recycler))
                return null;

            UnregisterRecyclerOwnership(recycler);
            DropRecyclerItems(recycler);

            return null;
        }

        private bool IsRecyclerOwned(Recycler recycler)
        {
            return recycler.OwnerID != 0UL && _recyclerOwners.ContainsKey(recycler.net.ID.Value);
        }

        private void UnregisterRecyclerOwnership(Recycler recycler)
        {
            _recyclerOwners.Remove(recycler.net.ID.Value);
        }

        private void DropRecyclerItems(Recycler recycler)
        {
            var recyclerComponent = recycler.GetComponent<RecyclerComponent>();
            recyclerComponent?.DropItems();
        }

        void OnLootEntity(BasePlayer player, Recycler recycler)
        {
            if (recycler == null || player == null)
                return;

            if (recycler.OwnerID != 0UL && _recyclerOwners.ContainsKey(recycler.net.ID.Value))
            {
                _playersWithUi.Add(player.userID);

                string recyclerId = recycler.net.ID.Value.ToString();
                CreateUi(player, recyclerId);
            }
        }

        private void OnPlayerLootEnd(PlayerLoot playerLoot)
        {
            BasePlayer player = playerLoot.GetComponentInParent<BasePlayer>();
            if (player == null)
                return;

            if (_playersWithUi.Contains(player.userID))
            {
                _playersWithUi.Remove(player.userID);
                CuiHelper.DestroyUi(player, UiOverlayName);
            }
        }
        #endregion

        #region UI
        private void CreateUi(BasePlayer player, string recyclerId)
        {
            var container = new CuiElementContainer();
            container.Add(
                new CuiPanel
                {
                    CursorEnabled = true,
                    Image =
                    {
                        Color = "1 1 1 0.15",
                        Sprite = "assets/content/ui/ui.background.transparent.radial.psd",
                        Material = "assets/content/ui/uibackgroundblur.mat",
                    },
                    RectTransform =
                    {
                        AnchorMin = _config.AnchorMin,
                        AnchorMax = _config.AnchorMax,
                        OffsetMin = "341.64 405.595",
                        OffsetMax = "554.76 505.605",
                    },
                },
                "Overlay",
                UiOverlayName
            );

            container.Add(
                new CuiElement
                {
                    Name = "Text",
                    Parent = UiOverlayName,
                    Components =
                    {
                        new CuiTextComponent
                        {
                            Text = "INDUSTRIAL RECYCLER",
                            Font = "robotocondensed-bold.ttf",
                            FontSize = 17,
                            Align = TextAnchor.MiddleCenter,
                            Color = "1 1 1 1",
                        },
                        new CuiOutlineComponent { Color = "0 0 0 1", Distance = "1 1" },
                        new CuiRectTransformComponent
                        {
                            AnchorMin = "0.5 0.5",
                            AnchorMax = "0.5 0.5",
                            OffsetMin = "-86.493 0",
                            OffsetMax = "86.492 34.875",
                        },
                    },
                }
            );

            container.Add(
                new CuiButton
                {
                    Button =
                    {
                        Color = "0.3960785 0.4666667 0.2627451 1",
                        Command = $"industrialrecycler.openinput {recyclerId}",
                        Close = UiOverlayName,
                    },
                    Text =
                    {
                        Text = lang.GetMessage("InputButton", this, player.UserIDString),
                        Font = "robotocondensed-regular.ttf",
                        FontSize = 18,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 1",
                    },
                    RectTransform =
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = "-104.206 -49.58",
                        OffsetMax = "-2.394 -17.22",
                    },
                },
                UiOverlayName,
                "Input"
            );

            container.Add(
                new CuiButton
                {
                    Button =
                    {
                        Color = "0.3960785 0.4666667 0.2627451 1",
                        Command = $"industrialrecycler.openoutput {recyclerId}",
                        Close = UiOverlayName,
                    },
                    Text =
                    {
                        Text = lang.GetMessage("OutputButton", this, player.UserIDString),
                        Font = "robotocondensed-regular.ttf",
                        FontSize = 18,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 1",
                    },
                    RectTransform =
                    {
                        AnchorMin = "0.5 0.5",
                        AnchorMax = "0.5 0.5",
                        OffsetMin = "1.994 -49.58",
                        OffsetMax = "103.806 -17.22",
                    },
                },
                UiOverlayName,
                "Output"
            );

            container.Add(
                new CuiButton
                {
                    Button =
                    {
                        Color = "0.3960785 0.7666667 0.2627451 1",
                        Command = $"chat.say /togglerecycler",
                        Close = "ToggleConfig",
                    },
                    Text =
                    {
                        Text = lang.GetMessage("ToggleConfig", this),
                        Font = "robotocondensed-regular.ttf",
                        FontSize = 14,
                        Align = TextAnchor.MiddleCenter,
                        Color = "1 1 1 1",
                    },
                    RectTransform =
                    {
                        AnchorMin = "1 1",
                        AnchorMax = "1 1",
                        OffsetMin = "-110 -20",
                        OffsetMax = "0 0",
                    },
                },
                UiOverlayName,
                "ToggleConfig"
            );

            CuiHelper.DestroyUi(player, UiOverlayName);
            CuiHelper.AddUi(player, container);
        }

        private void OpenInputStorage(ConsoleSystem.Arg arg)
        {
            OpenStorage(arg, true);
        }

        private void OpenOutputStorage(ConsoleSystem.Arg arg)
        {
            OpenStorage(arg, false);
        }

        private void OpenStorage(ConsoleSystem.Arg arg, bool isInput)
        {
            var player = arg.Player();
            if (player == null)
            {
                return;
            }

            if (arg.Args.Length == 0)
            {
                return;
            }

            if (!uint.TryParse(arg.Args[0], out uint recyclerId))
            {
                return;
            }

            var networkableId = new NetworkableId(recyclerId);
            var recycler = BaseNetworkable.serverEntities.Find(networkableId) as Recycler;

            if (recycler != null)
            {
                var recyclerComponent = recycler.GetComponent<RecyclerComponent>();
                if (recyclerComponent != null)
                {
                    var storage = isInput ? recyclerComponent.InputStorage : recyclerComponent.OutputStorage;
                    player.inventory.loot.StartLootingEntity(storage, true);
                    player.inventory.loot.AddContainer(storage.inventory);
                    player.inventory.loot.SendImmediate();
                    player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", storage.panelName);
                }
            }
        }
        #endregion

        #region Main
        private void CommandGetRecycler(BasePlayer player, string command, string[] args)
        {
            if (player == null)
                return;

            if (!permission.UserHasPermission(player.UserIDString, PermissionUseRecycler))
            {
                player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                return;
            }

            BasePlayer targetPlayer = player;

            if (args != null && args.Length > 0)
            {
                targetPlayer = BasePlayer.Find(args[0]);

                if (targetPlayer == null)
                {
                    player.ChatMessage(lang.GetMessage("PlayerNotFound", this, player.UserIDString));
                    return;
                }
            }

            if (GiveRecyclerItem(targetPlayer))
            {
                player.ChatMessage(lang.GetMessage("RecyclerGiven", this, player.UserIDString));
                if (targetPlayer != player)
                {
                    targetPlayer.ChatMessage(lang.GetMessage("RecyclerReceived", this, targetPlayer.UserIDString));
                }
            }
            else
            {
                player.ChatMessage(lang.GetMessage("RecyclerNotGiven", this, player.UserIDString));
                if (targetPlayer != player)
                {
                    targetPlayer.ChatMessage(lang.GetMessage("RecyclerNotReceived", this, targetPlayer.UserIDString));
                }
            }
        }

        private bool GiveRecyclerItem(BasePlayer player)
        {
            var recyclerItem = ItemManager.CreateByName(ItemName, 1, _config.RecyclerSkinId);
            if (recyclerItem == null)
                return false;

            recyclerItem.name = "Recycler";
            return player.inventory.GiveItem(recyclerItem);
        }

        private void CommandUpgradeRecycler(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, PermissionUseRecycler))
            {
                player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                return;
            }

            int maxRecyclers = _config.MaxRecyclersPerPlayer;

            if (permission.UserHasPermission(player.UserIDString, PermissionAdmin))
            {
                maxRecyclers = int.MaxValue;
            }
            else if (permission.UserHasPermission(player.UserIDString, PermissionVip))
            {
                maxRecyclers = _config.MaxRecyclersVip;
            }

            if (_recyclerOwners.Count(entry => entry.Value == player.userID) >= maxRecyclers)
            {
                player.ChatMessage(lang.GetMessage("RecyclerLimitReached", this, player.UserIDString));
                return;
            }

            if (!UpgradeToIndustrialRecycler(player))
            {
                player.ChatMessage(lang.GetMessage("NoRecyclerInView", this, player.UserIDString));
            }
            else
            {
                player.ChatMessage(lang.GetMessage("RecyclerUpgraded", this, player.UserIDString));
            }
        }

        private Recycler FindRecyclerInView(BasePlayer player)
        {
            if (Physics.Raycast(player.eyes.HeadRay(), out RaycastHit hit, 5f))
            {
                BaseEntity entity = hit.GetEntity();
                return entity as Recycler;
            }
            return null;
        }

        private bool InitializeRecyclerPlacement(BasePlayer player, BaseEntity baseEntity, int turn = 0)
        {
            var supportingFoundation = FindSupportingFoundation(baseEntity);
            if (supportingFoundation == null)
                return false;

            var spawnedRecycler = SpawnRecyclerWithComponents(player, baseEntity, supportingFoundation, turn);
            if (spawnedRecycler == null)
                return false;

            spawnedRecycler.gameObject.AddComponent<RecyclerComponent>();
            return true;
        }

        private bool InitializeUpgradeRecycler(BasePlayer player, Recycler recycler, int turn = 0)
        {
            var spawnedRecycler = UpgradeRecyclerWithComponents(player, recycler, turn);
            if (spawnedRecycler == null)
                return false;

            spawnedRecycler.gameObject.AddComponent<RecyclerComponent>();
            return true;
        }

        private BuildingBlock FindSupportingFoundation(BaseEntity baseEntity)
        {
            Vector3 origin = baseEntity.transform.position + Vector3.up * 0.1f;
            if (Physics.Raycast(origin, Vector3.down, out RaycastHit hitData, 4f, LayerMask.GetMask("Construction")))
            {
                return hitData.GetEntity() as BuildingBlock;
            }
            return null;
        }

        private Recycler SetupStorageAndAdapters(Recycler recycler, BasePlayer player)
        {
            Vector3 inputOffset,
                inputAdapterOffset,
                outputOffset,
                outputAdapterOffset;
            Quaternion inputRotation,
                outputRotation,
                inputAdapterRotation,
                outputAdapterRotation;

            if (_config.UseAlternativeAdapterConfig)
            {
                inputOffset = new Vector3(0.0f, 0.72f, 0.11f);
                inputAdapterOffset = new Vector3(0.32f, -0.6f, -0.03f);
                outputOffset = new Vector3(-0.4f, 0.8f, 0.2f);
                outputAdapterOffset = new Vector3(-0.07f, 0.535f, 0.397f);

                inputRotation = Quaternion.Euler(0, 180, 191);
                outputRotation = Quaternion.Euler(169, 90, 180);
                inputAdapterRotation = Quaternion.Euler(0, 0, 0);
                outputAdapterRotation = Quaternion.Euler(180, 90, 0);
            }
            else
            {
                inputOffset = new Vector3(-1.0f, 0.72f, 0.31f);
                inputAdapterOffset = new Vector3(0.00f, -0.15f, -0.25f);
                outputOffset = new Vector3(-0.9f, 0.72f, -0.09f);
                outputAdapterOffset = new Vector3(0.00f, 0.26f, -0.05f);

                inputRotation = Quaternion.Euler(90, 90, 180);
                outputRotation = Quaternion.Euler(180, 90, 180);
                inputAdapterRotation = Quaternion.Euler(180, 90, 270);
                outputAdapterRotation = Quaternion.Euler(0, 90, 0);
            }

            var inputStorage = SpawnEntity(InputStoragePrefabPath, recycler, player, inputOffset, inputRotation);
            SpawnEntity(AdapterPrefabPath, inputStorage, player, inputAdapterOffset, inputAdapterRotation);

            var outputStorage = SpawnEntity(OutputStoragePrefabPath, recycler, player, outputOffset, outputRotation);
            SpawnEntity(AdapterPrefabPath, outputStorage, player, outputAdapterOffset, outputAdapterRotation);

            return recycler;
        }

        private Recycler UpgradeRecyclerWithComponents(BasePlayer player, Recycler recycler, int turn = 0)
        {
            return SetupStorageAndAdapters(recycler, player);
        }

        private Recycler SpawnRecyclerWithComponents(BasePlayer player, BaseEntity baseEntity, BuildingBlock foundation, int turn = 0)
        {
            var recycler = SpawnEntity(RecyclerPrefabPath, foundation, player, baseEntity.transform.position, baseEntity.transform.rotation * Quaternion.Euler(0, turn, 0)) as Recycler;
            if (recycler == null)
                return null;

            return SetupStorageAndAdapters(recycler, player);
        }

        private BaseEntity SpawnEntity(string prefabPath, BaseEntity parent, BasePlayer player, Vector3 position, Quaternion rotation)
        {
            var entity = GameManager.server.CreateEntity(prefabPath, Vector3.zero, Quaternion.identity, true);
            if (entity == null)
                return null;

            entity.OwnerID = player.userID;

            if (parent != null)
            {
                entity.SetParent(parent, true);
            }

            if (parent is BuildingBlock)
            {
                entity.transform.position = position;
                entity.transform.rotation = rotation;
            }
            else
            {
                entity.transform.localPosition = position;
                entity.transform.localRotation = rotation;
            }

            entity.Spawn();
            entity.SendNetworkUpdateImmediate();
            return entity;
        }

        private void ProcessRecyclerItems(RecyclerComponent recyclerComponent, Item item)
        {
            if (item.position < 6)
            {
                recyclerComponent.Recycler.StartRecycling();
            }
            else
            {
                if (!item.MoveToContainer(recyclerComponent.OutputStorage.inventory))
                {
                    recyclerComponent.Recycler.StopRecycling();
                }
            }
        }

        private bool UpgradeToIndustrialRecycler(BasePlayer player)
        {
            if (Physics.Raycast(player.eyes.HeadRay(), out RaycastHit hit, 5f))
            {
                BaseEntity baseEntity = hit.GetEntity();
                if (baseEntity is Recycler recycler && recycler.OwnerID == player.userID)
                {
                    if (!InitializeUpgradeRecycler(player, baseEntity as Recycler, 90))
                    {
                        player.ChatMessage(lang.GetMessage("InvalidPlacement", this, player.UserIDString));
                        timer.Once(1, () => GiveRecyclerItem(player));
                        return false;
                    }
                    else
                    {
                        player.ChatMessage(lang.GetMessage("RecyclerPlaced", this, player.UserIDString));
                    }

                    return true;
                }
            }
            return false;
        }

        private void ToggleRecyclerConfig(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, PermissionUseRecycler))
            {
                player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                return;
            }

            Recycler recycler = FindRecyclerInView(player);
            if (recycler == null)
            {
                player.ChatMessage(lang.GetMessage("NoRecyclerInView", this, player.UserIDString));
                return;
            }

            var recyclerComponent = recycler.GetComponent<RecyclerComponent>();
            if (recyclerComponent == null)
            {
                player.ChatMessage(lang.GetMessage("RecyclerComponentNotFound", this, player.UserIDString));
                return;
            }

            recyclerComponent.ToggleConfig();
            player.ChatMessage(lang.GetMessage("RecyclerConfigToggled", this, player.UserIDString));
        }
        #endregion

        #region Configuration
        private class Configuration
        {
            [JsonProperty("Commands")]
            public List<string> Commands { get; set; }

            [JsonProperty("Max Recyclers Per Player")]
            public int MaxRecyclersPerPlayer { get; set; }

            [JsonProperty("Max Recyclers Vip (industrialrecycler.vip)")]
            public int MaxRecyclersVip { get; set; }

            [JsonProperty("Recycler Item SkinId")]
            public ulong RecyclerSkinId { get; set; }

            [JsonProperty("AnchorMin")]
            public string AnchorMin { get; set; }

            [JsonProperty("AnchorMax")]
            public string AnchorMax { get; set; }

            [JsonProperty("Alternative Adapter Configuration")]
            public bool UseAlternativeAdapterConfig { get; set; }

            [JsonProperty("Hide Storage Containers")]
            public bool HideStorageContainers { get; set; }

            [JsonProperty("Version")]
            public VersionNumber Version { get; set; }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>() ?? throw new Exception("Failed to read configuration file.");

                bool configChanged = false;

                if (_config.Version != Version)
                {
                    _config.Version = Version;
                    configChanged = true;
                }

                if (string.IsNullOrEmpty(_config.AnchorMin))
                {
                    _config.AnchorMin = "0.5 0";
                    configChanged = true;
                }
                if (string.IsNullOrEmpty(_config.AnchorMax))
                {
                    _config.AnchorMax = "0.5 0";
                    configChanged = true;
                }

                if (!_config.UseAlternativeAdapterConfig)
                {
                    _config.UseAlternativeAdapterConfig = false;
                    configChanged = true;
                }

                if (configChanged)
                {
                    SaveConfig();
                }
            }
            catch (Exception ex)
            {
                PrintError($"There was an error in your configuration file: {ex.Message}. Default values will be used.");
                LoadDefaultConfig();
            }
        }

        protected override void LoadDefaultConfig()
        {
            _config = GetDefaultConfig();
            SaveConfig();
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(_config, true);
        }

        private Configuration GetDefaultConfig()
        {
            return new Configuration
            {
                Commands = new List<string> { "getrecycler", "irecycler", "giverecycler" },
                MaxRecyclersPerPlayer = 1,
                MaxRecyclersVip = 2,
                RecyclerSkinId = 3357927081,
                AnchorMin = "0.5 0",
                AnchorMax = "0.5 0",
                UseAlternativeAdapterConfig = false,
                HideStorageContainers = false,
                Version = Version,
            };
        }
        #endregion

        #region Localization
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(
                new Dictionary<string, string>
                {
                    ["NoPermission"] = "You do not have permission to use this command.",
                    ["RecyclerLimitReached"] = "You have reached the recycler limit.",
                    ["InvalidPlacement"] = "The recycler must be placed on a construction block.",
                    ["RecyclerPlaced"] = "Recycler placed successfully.",
                    ["RecyclerPickedUp"] = "Recycler picked up, item returned to inventory.",
                    ["RecyclerGiven"] = "Recycler given to your inventory.",
                    ["RecyclerReceived"] = "You have received a recycler.",
                    ["RecyclerNotGiven"] = "Failed to give recycler.",
                    ["RecyclerNotReceived"] = "Failed to receive recycler.",
                    ["NoRecyclerInView"] = "No recycler in sight to upgrade.",
                    ["RecyclerComponentNotFound"] = "Recycler component not found.",
                    ["RecyclerConfigToggled"] = "Recycler configuration toggled successfully.",
                    ["PlayerNotFound"] = "The specified player could not be found.",
                    ["ToggleConfig"] = "Toggle",
                    ["InputButton"] = "Input",
                    ["OutputButton"] = "Output",
                },
                this
            );

            lang.RegisterMessages(
                new Dictionary<string, string>
                {
                    ["NoPermission"] = "Você não tem permissão para usar este comando.",
                    ["RecyclerLimitReached"] = "Você atingiu o limite de recicladores.",
                    ["InvalidPlacement"] = "O reciclador deve ser colocado sobre um bloco de construção.",
                    ["RecyclerPlaced"] = "Reciclador colocado com sucesso.",
                    ["RecyclerPickedUp"] = "Reciclador recolhido, item devolvido ao inventário.",
                    ["RecyclerGiven"] = "Reciclador fornecido ao seu inventário.",
                    ["RecyclerReceived"] = "Você recebeu um reciclador.",
                    ["RecyclerNotGiven"] = "Falha ao fornecer o reciclador.",
                    ["RecyclerNotReceived"] = "Falha ao receber o reciclador.",
                    ["NoRecyclerInView"] = "Nenhum reciclador à vista para atualizar.",
                    ["RecyclerComponentNotFound"] = "Componente de reciclador não encontrado.",
                    ["RecyclerConfigToggled"] = "Configuração do reciclador alternada com sucesso.",
                    ["PlayerNotFound"] = "O jogador especificado não pôde ser encontrado.",
                    ["ToggleConfig"] = "Alterar",
                    ["InputButton"] = "Entrada",
                    ["OutputButton"] = "Saída",
                },
                this,
                "pt-BR"
            );

            lang.RegisterMessages(
                new Dictionary<string, string>
                {
                    ["NoPermission"] = "Sie haben keine Erlaubnis, diesen Befehl zu verwenden.",
                    ["RecyclerLimitReached"] = "Sie haben die Grenze für Recycler erreicht.",
                    ["InvalidPlacement"] = "Der Recycler muss auf einem Baublock platziert werden.",
                    ["RecyclerPlaced"] = "Recycler erfolgreich platziert.",
                    ["RecyclerPickedUp"] = "Recycler aufgenommen, Artikel in das Inventar zurückgegeben.",
                    ["RecyclerGiven"] = "Recycler wurde Ihrem Inventar hinzugefügt.",
                    ["RecyclerReceived"] = "Sie haben einen Recycler erhalten.",
                    ["RecyclerNotGiven"] = "Recycle fehlerhaft vorhanden.",
                    ["RecyclerNotReceived"] = "Falschen Empfang des Recyclers.",
                    ["NoRecyclerInView"] = "Kein Recycler in Sicht, um aufzurüsten.",
                    ["RecyclerComponentNotFound"] = "Recycler-Komponente nicht gefunden.",
                    ["RecyclerConfigToggled"] = "Recycler-Konfiguration erfolgreich umgeschaltet.",
                    ["PlayerNotFound"] = "Der angegebene Spieler konnte nicht gefunden werden.",
                    ["ToggleConfig"] = "Umschalten",
                    ["InputButton"] = "Eingang",
                    ["OutputButton"] = "Ausgang",
                },
                this,
                "de"
            );

            lang.RegisterMessages(
                new Dictionary<string, string>
                {
                    ["NoPermission"] = "No tienes permiso para usar este comando.",
                    ["RecyclerLimitReached"] = "Has alcanzado el límite de recicladores.",
                    ["InvalidPlacement"] = "El reciclador debe colocarse en un bloque de construcción.",
                    ["RecyclerPlaced"] = "Reciclador colocado con éxito.",
                    ["RecyclerPickedUp"] = "Reciclador recogido, artículo devuelto al inventario.",
                    ["RecyclerGiven"] = "Reciclador dado a tu inventario.",
                    ["RecyclerReceived"] = "Has recibido un reciclador.",
                    ["RecyclerNotGiven"] = "Fallo al dar el reciclador.",
                    ["RecyclerNotReceived"] = "Fallo al recibir el reciclador.",
                    ["NoRecyclerInView"] = "No hay reciclador a la vista para mejorar.",
                    ["RecyclerComponentNotFound"] = "Componente de reciclador no encontrado.",
                    ["RecyclerConfigToggled"] = "Configuración del reciclador alternada con éxito.",
                    ["PlayerNotFound"] = "No se pudo encontrar al jugador especificado.",
                    ["ToggleConfig"] = "Alternar",
                    ["InputButton"] = "Entrada",
                    ["OutputButton"] = "Salida",
                },
                this,
                "es"
            );
        }
        #endregion

        #region Component
        private class RecyclerComponent : MonoBehaviour
        {
            public Recycler Recycler { get; private set; }
            public StorageContainer InputStorage { get; private set; }
            public StorageContainer OutputStorage { get; private set; }
            public int CurrentConfigState { get; private set; }

            private const int MaxStorageCapacity = 48;
            private const float TransferInterval = 10f;

            private enum RecyclerConfig
            {
                Default = 1,
                Alternative = 2,
            }

            private void Awake()
            {
                Recycler = GetComponent<Recycler>();
                if (Recycler == null)
                {
                    Debug.LogError("Recycler component is missing on this GameObject.");
                    enabled = false;
                    return;
                }

                // Start with a default known state
                CurrentConfigState = (int)RecyclerConfig.Default;
                InitializeRecyclerComponents();
            }

            private void InitializeRecyclerComponents()
            {
                foreach (MonoBehaviour mb in GetComponents<MonoBehaviour>())
                {
                    var type = mb.GetType();
                    if (type != typeof(Recycler) && type != typeof(RecyclerComponent) && type.Name != "Ground_Watch")
                    {
                        Destroy(mb);
                    }
                }

                if (!ValidateStorageContainers())
                {
                    Debug.LogError("Failed to validate storage containers.");
                    enabled = false;
                    return;
                }

                SetupRecycler();

                RegisterEntities();
                InvokeRepeating(nameof(HandleItemTransfers), 0f, TransferInterval);
            }

            private bool ValidateStorageContainers()
            {
                InputStorage = Recycler.children.OfType<StorageContainer>().FirstOrDefault(c => c?.name == InputStoragePrefabPath);
                OutputStorage = Recycler.children.OfType<StorageContainer>().FirstOrDefault(c => c?.name == OutputStoragePrefabPath);
                return InputStorage != null && OutputStorage != null;
            }

            private void RegisterEntities()
            {
                _instance._inputItemContainers.Add(InputStorage.inventory.uid.Value);
                _instance._recyclerItemContainers.Add(Recycler.inventory.uid.Value);

                var inputAdapter = InputStorage.children.OfType<IndustrialStorageAdaptor>().FirstOrDefault();
                if (inputAdapter != null)
                    _instance._storageAdapters.Add(inputAdapter.net.ID.Value);

                var outputAdapter = OutputStorage.children.OfType<IndustrialStorageAdaptor>().FirstOrDefault();
                if (outputAdapter != null)
                    _instance._storageAdapters.Add(outputAdapter.net.ID.Value);
            }

            private void SetupRecycler()
            {
                if (Recycler == null || InputStorage == null || OutputStorage == null)
                {
                    Debug.LogError("Attempted to setup recycler with null components.");
                    return;
                }

                _instance._recyclerOwners[Recycler.net.ID.Value] = Recycler.OwnerID;
                InputStorage.inventory.capacity = MaxStorageCapacity;
                OutputStorage.inventory.capacity = MaxStorageCapacity;
            }

            public void HandleItemTransfers()
            {
                int availableRecyclerSlots = 6 - Recycler.inventory.itemList.Count;

                if (OutputStorage.inventory.IsFull())
                {
                    Recycler.StopRecycling();
                    return;
                }

                TransferItemsFromRecyclerToOutput(ref availableRecyclerSlots);
                TransferItemsFromInputToRecycler(ref availableRecyclerSlots);

                if (availableRecyclerSlots < 6 && Recycler.inventory.itemList.Count > 0)
                {
                    Recycler.StartRecycling();
                }
            }

            private void TransferItemsFromRecyclerToOutput(ref int availableRecyclerSlots)
            {
                for (int slot = 6; slot < Recycler.inventory.capacity; slot++)
                {
                    var itemInRecycler = Recycler.inventory.GetSlot(slot);
                    if (itemInRecycler != null && itemInRecycler.MoveToContainer(OutputStorage.inventory))
                    {
                        availableRecyclerSlots++;
                    }
                }
            }

            private void TransferItemsFromInputToRecycler(ref int availableRecyclerSlots)
            {
                var inputItems = new List<Item>(InputStorage.inventory.itemList);

                foreach (var item in inputItems)
                {
                    if (item.info.Blueprint != null)
                    {
                        MoveItemToRecycler(item, ref availableRecyclerSlots);
                    }
                    else
                    {
                        item.MoveToContainer(OutputStorage.inventory);
                    }
                }
            }

            private void MoveItemToRecycler(Item item, ref int availableRecyclerSlots)
            {
                if (availableRecyclerSlots <= 0)
                    return;

                for (int slot = 0; slot < 6; slot++)
                {
                    if (Recycler.inventory.GetSlot(slot) == null && item.MoveToContainer(Recycler.inventory, slot))
                    {
                        availableRecyclerSlots--;
                        break;
                    }
                }
            }

            public void ToggleConfig()
            {
                CancelInvoke(nameof(HandleItemTransfers));

                CurrentConfigState = (int)(CurrentConfigState == (int)RecyclerConfig.Default ? RecyclerConfig.Alternative : RecyclerConfig.Default);

                UpdateAdapterPositions();
                InitializeRecyclerComponents();
            }

            private void UpdateAdapterPositions()
            {
                ClearExistingComponents();

                Vector3 inputOffset,
                    outputOffset,
                    inputAdapterOffset,
                    outputAdapterOffset;
                Quaternion inputRotation,
                    outputRotation,
                    inputAdapterRotation,
                    outputAdapterRotation;

                if (CurrentConfigState == (int)RecyclerConfig.Default)
                {
                    inputOffset = new Vector3(0.0f, 0.72f, 0.11f);
                    outputOffset = new Vector3(-0.4f, 0.8f, 0.2f);
                    inputAdapterOffset = new Vector3(0.32f, -0.6f, -0.03f);
                    outputAdapterOffset = new Vector3(-0.07f, 0.535f, 0.397f);

                    inputRotation = Quaternion.Euler(0, 180, 191);
                    outputRotation = Quaternion.Euler(169, 90, 180);
                    inputAdapterRotation = Quaternion.Euler(0, 0, 0);
                    outputAdapterRotation = Quaternion.Euler(180, 90, 0);
                }
                else
                {
                    if (_instance._config.HideStorageContainers)
                    {
                        inputOffset = new Vector3(0.0f, 0.72f, 0.11f);
                        outputOffset = new Vector3(-0.4f, 0.72f, 0.2f);
                        inputAdapterOffset = new Vector3(0.836f, -0.3301f, 0.18f);
                        outputAdapterOffset = new Vector3(-0.227f, 0.33f, 0.434f);

                        inputRotation = Quaternion.Euler(0, 0, 180);
                        outputRotation = Quaternion.Euler(180, 90, 180);
                        inputAdapterRotation = Quaternion.Euler(0, 0, 0);
                        outputAdapterRotation = Quaternion.Euler(180, 90, 0);
                    }
                    else
                    {
                        inputOffset = new Vector3(-1.0f, 0.72f, 0.31f);
                        outputOffset = new Vector3(-0.9f, 0.72f, -0.09f);
                        inputAdapterOffset = new Vector3(0.00f, -0.15f, -0.25f);
                        outputAdapterOffset = new Vector3(0.00f, 0.26f, -0.05f);

                        inputRotation = Quaternion.Euler(90, 90, 180);
                        outputRotation = Quaternion.Euler(180, 90, 180);
                        inputAdapterRotation = Quaternion.Euler(180, 90, 270);
                        outputAdapterRotation = Quaternion.Euler(0, 90, 0);
                    }
                }

                BasePlayer ownerPlayer = BasePlayer.FindByID(Recycler.OwnerID);
                if (ownerPlayer != null)
                {
                    var inputStorage = _instance.SpawnEntity(InputStoragePrefabPath, Recycler, ownerPlayer, inputOffset, inputRotation) as StorageContainer;
                    if (inputStorage == null)
                    {
                        Debug.LogError("Failed to spawn input storage.");
                        return;
                    }
                    _instance.SpawnEntity(AdapterPrefabPath, inputStorage, ownerPlayer, inputAdapterOffset, inputAdapterRotation);

                    var outputStorage = _instance.SpawnEntity(OutputStoragePrefabPath, Recycler, ownerPlayer, outputOffset, outputRotation) as StorageContainer;
                    if (outputStorage == null)
                    {
                        Debug.LogError("Failed to spawn output storage.");
                        return;
                    }
                    _instance.SpawnEntity(AdapterPrefabPath, outputStorage, ownerPlayer, outputAdapterOffset, outputAdapterRotation);
                }
            }

            private void ClearExistingComponents()
            {
                foreach (var child in Recycler.children.ToList())
                {
                    if (child is StorageContainer || child is IndustrialStorageAdaptor)
                    {
                        child.Kill();
                    }
                }
            }

            internal void DropItems()
            {
                var allItems = GatherAllItems();
                DropItemsInBatches(allItems, MaxStorageCapacity);
            }

            private List<Item> GatherAllItems()
            {
                return InputStorage.inventory.itemList.Concat(OutputStorage.inventory.itemList).Concat(Recycler.inventory.itemList).ToList();
            }

            private void DropItemsInBatches(List<Item> items, int batchSize)
            {
                var recyclerPosition = Recycler.transform.position;
                var recyclerRotation = Recycler.transform.rotation;

                for (int i = 0; i < items.Count; i += batchSize)
                {
                    var itemBatch = items.Skip(i).Take(batchSize).ToList();
                    SpawnDroppedItemContainer(recyclerPosition, recyclerRotation, itemBatch);
                }
            }

            private DroppedItemContainer SpawnDroppedItemContainer(Vector3 position, Quaternion rotation, List<Item> itemsToDrop)
            {
                var containerPrefabPath = "assets/prefabs/misc/item drop/item_drop.prefab";
                var droppedItemContainer = GameManager.server.CreateEntity(containerPrefabPath, position, rotation) as DroppedItemContainer;

                if (droppedItemContainer == null)
                    return null;

                InitializeItemContainer(droppedItemContainer, itemsToDrop);
                droppedItemContainer.Spawn();

                return droppedItemContainer;
            }

            private void InitializeItemContainer(DroppedItemContainer container, List<Item> items)
            {
                container.inventory = new ItemContainer();
                container.inventory.ServerInitialize(null, items.Count);
                container.inventory.GiveUID();
                container.inventory.entityOwner = container;

                foreach (var item in items)
                {
                    item.MoveToContainer(container.inventory);
                }
            }

            private void OnDestroy()
            {
                CancelInvoke(nameof(HandleItemTransfers));
            }
        }
        #endregion
    }
}