﻿using Newtonsoft.Json;
using System.Linq;
using System.Collections.Generic;

namespace Oxide.Plugins
{
    [Info("NoWorkbench", "k1lly0u", "0.1.52")]
    [Description("Eliminates the requirement of being near a bench to craft")]
    class NoWorkbench : RustPlugin
    {        
        private Dictionary<int, int> _defaultBlueprints;

        #region Oxide Hooks  
        private void OnServerInitialized()
        {
            LoadVariables();
            _defaultBlueprints = ItemManager.GetBlueprints().ToDictionary(x => x.targetItem.itemid, y => y.workbenchLevelRequired);

            foreach (ItemBlueprint bp in ItemManager.GetBlueprints())            
                bp.workbenchLevelRequired = 0;            

            foreach (BasePlayer player in BasePlayer.activePlayerList)
                OnPlayerConnected(player);
        }
       
        private void OnPlayerConnected(BasePlayer player)
        {
            if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot))
            {
                timer.In(3, () => OnPlayerConnected(player));
                return;
            }

            player.ClientRPC(RpcTarget.Player("craftMode", player), 1);

            if (_configData.NoBlueprints)
                UnlockAllBlueprints(player);             
        }        

        private void UnlockAllBlueprints(BasePlayer player)
        {
            ProtoBuf.PersistantPlayer playerInfo = SingletonComponent<ServerMgr>.Instance.persistance.GetPlayerInfo(player.userID);
            foreach (ItemBlueprint itemBlueprint in ItemManager.bpList)
            {
                if (!itemBlueprint.userCraftable || itemBlueprint.defaultBlueprint) 
                    continue;
                
                if (!playerInfo.unlockedItems.Contains(itemBlueprint.targetItem.itemid))                   
                    playerInfo.unlockedItems.Add(itemBlueprint.targetItem.itemid);
            }
            
            SingletonComponent<ServerMgr>.Instance.persistance.SetPlayerInfo(player.userID, playerInfo);
            player.SendNetworkUpdateImmediate();
            player.ClientRPC(RpcTarget.Player("UnlockedBlueprint", player), 0);
        }

        private void Unload()
        {
            foreach (ItemBlueprint bp in ItemManager.GetBlueprints())
                bp.workbenchLevelRequired = _defaultBlueprints[bp.targetItem.itemid];
        }
        #endregion
       
        #region Config        
        private ConfigData _configData;
        
        private class ConfigData
        {
            [JsonProperty(PropertyName = "Disable the need for blueprints")]
            public bool NoBlueprints { get; set; }            
        }

        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            ConfigData config = new ConfigData
            {
                NoBlueprints = false
            };
            SaveConfig(config);
        }

        private void LoadConfigVariables() => _configData = Config.ReadObject<ConfigData>();

        private void SaveConfig(ConfigData config) => Config.WriteObject(config, true);
        #endregion
    }
}
