﻿#region Header

// Copyright (c) 2025 AccelByte Inc. All Rights Reserved.
// This is licensed software from AccelByte Inc, for limitations
// and restrictions contact your company contract manager.

#endregion

using System;
using UnityEngine;

namespace BlackBox
{
    [Serializable]
    public struct HotKey
    {
        private const string KEY_FIELD = "Key";
        private const string ALT_FIELD = "bAlt";
        private const string CTRL_FIELD = "bCtrl";
        private const string SHIFT_FIELD = "bShift";
        private const string CMD_FIELD = "bCmd";
        
        public KeyCode Key;
        public bool bAlt;
        public bool bCtrl;
        public bool bShift;
        public bool bCmd;

        private bool bPressed;
        private bool bWasPressed;

        public void Setup(KeyCode inKey, bool inAlt, bool inCtrl, bool inShift, bool inCmd)
        {
            Key = inKey;
            bAlt = inAlt;
            bCtrl = inCtrl;
            bShift = inShift;
            bCmd = inCmd;
        }

        public bool IsPressed()
        {
            bool Result = Input.GetKey(Key);
            Result &= !bAlt || Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
            Result &= !bCtrl || Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
            Result &= !bShift || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
            Result &= !bCmd || Input.GetKey(KeyCode.LeftCommand) || Input.GetKey(KeyCode.RightCommand);

            // Debug.Log("Ispressed "+Result);
            return Result;
        }

        public bool WasPressed()
        {
            bWasPressed = bPressed;
            bPressed = IsPressed();
            return bWasPressed && !bPressed;
        }
        
        private bool IsModifierKey(KeyCode key)
        {
            return key == KeyCode.LeftShift || key == KeyCode.RightShift ||
                key == KeyCode.LeftControl || key == KeyCode.RightControl ||
                key == KeyCode.LeftAlt || key == KeyCode.RightAlt || 
                key == KeyCode.CapsLock;
        }

        public bool IsValid()
        {
            return Key != KeyCode.None && !IsModifierKey(Key);
        }

        public string Serialize()
        {
            string Result = String.Format($"{KEY_FIELD}={Key.ToString()},{ALT_FIELD}={(bAlt?1:0)},{CTRL_FIELD}={(bCtrl?1:0)},{SHIFT_FIELD}={(bShift?1:0)},{CMD_FIELD}={(bCmd?1:0)}");
            return Result;
        }
        
        public static HotKey Deserialize(string SerializedString)
        {
            Debug.Log("Will deserialize "+SerializedString);
            HotKey hotKey = new HotKey();

            if (String.IsNullOrEmpty(SerializedString))
            {
                Logger.LogWarning("The hotkey string is empty. Please check the config!");
            }
            else
            {
                string[] Tokens = SerializedString.Split(',');
                foreach (var Token in Tokens)
                {
                    string[] Comp = Token.Split(new string[] { "=" }, 2, StringSplitOptions.None);
                    // Index 0 is the key(ex: Key, bShift, bAlt, etc)
                    // Index 1 is the value
                    if (Comp[0].Equals(KEY_FIELD))
                    {
                        Enum.TryParse(Comp[1], out hotKey.Key);
                    }
                    else
                    {
                        int value = 0;
                        if (Int32.TryParse(Comp[1], out value))
                        {
                            if (Comp[0].Equals(ALT_FIELD))
                            {
                                hotKey.bAlt = value != 0;
                            }
                            else if (Comp[0].Equals(CTRL_FIELD))
                            {
                                hotKey.bCtrl = value != 0;
                            }
                            else if (Comp[0].Equals(SHIFT_FIELD))
                            {
                                hotKey.bShift = value != 0;
                            }
                            else if (Comp[0].Equals(CMD_FIELD))
                            {
                                hotKey.bCmd = value != 0;
                            }
                        }
                    }

                    Logger.Log(
                        $"Parsed hotkey result Key: {hotKey.Key.ToString()} Alt:{hotKey.bAlt} Ctrl:{hotKey.bCtrl} Shift:{hotKey.bShift} Cmd:{hotKey.bCmd}");
                }
            }

            if (!hotKey.IsValid())
            {
                Logger.Log("The loaded key is not valid!!!");
            }
            return hotKey;
        }
    }
}