/***********************************************************************************************************************/
/*** DO NOT edit this file! Edit the files under `oxide/config` and/or `oxide/lang`, created once plugin has loaded. ***/
/*** Please note, support cannot be provided if the plugin has been modified. Please use a fresh copy if modified.   ***/
/***********************************************************************************************************************/

using System.Collections.Generic;

namespace Oxide.Plugins
{
    [Info("Code Sync", "Wulf", "2.0.4")]
    [Description("Automatically allows players access to code locks based on tool cupboard authorization")]
    public class CodeSync : CovalencePlugin
    {
        #region Localization

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>()
            {
                ["CodeSynced"] = "Code will be the same code as the tool cupboard lock"
            }, this);
        }

        #endregion Localization

        #region Lock Handling

        private BuildingManager.Building GetBuilding(BaseEntity entity)
        {
            var parent = entity.GetParentEntity();

            if (parent == null)
            {
                return null;
            }

            BuildingManager.Building building;
            if (parent.prefabID == 4211374971 || parent.prefabID == 95147612)
            {
                building = parent.GetBuildingPrivilege()?.GetBuilding();
            }
            else building = (parent as DecayEntity)?.GetBuilding();

            if (building == null || building.buildingPrivileges == null || building.buildingPrivileges.Count == 0)
            {
                //Log($"Could not find building for {codeLock.GetParentEntity()?.PrefabName}");
                return null;
            }

            return building;
        }

        private CodeLock GetCupboardLock(BuildingManager.Building building)
        {
            return building.buildingPrivileges[0].GetSlot(BaseEntity.Slot.Lock) as CodeLock;
        }

        private void CanChangeCode(BasePlayer basePlayer, CodeLock codeLock)
        {
            // TODO: Support changing code on any code lock, for all building code locks
            Message(basePlayer, "CodeSynced");
        }

        private object CanUseLockedEntity(BasePlayer basePlayer, CodeLock codeLock)
        {
            // Check if entity is already unlocked
            if (!codeLock.IsLocked())
            {
                return null;
            }

            // Check for valid building entity
            BuildingManager.Building building = GetBuilding(codeLock);
            if (building == null)
            {
                return null;
            }

            // Check if code matches tool cupboard lock code
            CodeLock tcLock = GetCupboardLock(building);
            if (tcLock == null || tcLock.code != codeLock.code && tcLock.guestCode != codeLock.code)
            {
                return null;
            }

            // Check for and allow player if whitelisted
            if (tcLock.whitelistPlayers.Contains(basePlayer.userID) || tcLock.guestPlayers.Contains(basePlayer.userID))
            {
                return true;
            }

            return null;
        }

        private void OnCodeEntered(CodeLock codeLock, BasePlayer basePlayer, string code)
        {
            // Notify of sync if codelock code matches code provided
            if (GetBuilding(codeLock) != null && codeLock.code == code)
            {
                Message(basePlayer, "CodeSynced");
            }
        }

        #endregion Lock Handling

        #region Helpers

        private string GetLang(string langKey, string playerId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(langKey, this, playerId), args);
        }

        private void Message(BasePlayer basePlayer, string langKey, params object[] args)
        {
            if (basePlayer.IsConnected)
            {
                basePlayer.IPlayer.Message(GetLang(langKey, basePlayer.UserIDString, args));
            }
        }

        #endregion Helpers
    }
}