-- Garry's Mod Binder - Keybinds Tab (Virtual Keyboard)
local PANEL = {}

local KEY_LAYOUT = {
    {"ESC", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"},
    {"~", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "BKSP"},
    {"TAB", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\"},
    {"CAPS", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "ENTER"},
    {"SHIFT", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "SHIFT"},
    {"CTRL", "WIN", "ALT", "SPACE", "ALT", "WIN", "MENU"}
}

local KEY_SPECIAL = {
    {"PRSC", "SCRLK", "PAUSE"},
    {"INS", "HOME", "PGUP"},
    {"DEL", "END", "PGDN"},
    {"↑"},
    {"←", "↓", "→"}
}

local NUM_PAD = {
    {"NUM", "/", "*", "-"},
    {"7", "8", "9", "+"},
    {"4", "5", "6"},
    {"1", "2", "3", "ENT"},
    {"0", "."}
}

local STRING_TO_KEY = {
    ["ESC"] = KEY_ESCAPE, ["~"] = KEY_TILDE, ["-"] = KEY_MINUS, ["="] = KEY_EQUAL, ["BKSP"] = KEY_BACKSPACE, ["TAB"] = KEY_TAB,
    ["["] = KEY_LBRACKET, ["]"] = KEY_RBRACKET, ["\\"] = KEY_BACKSLASH, ["CAPS"] = KEY_CAPSLOCK, [";"] = KEY_SEMICOLON,
    ["'"] = KEY_APOSTROPHE, ["ENTER"] = KEY_ENTER, ["SHIFT"] = KEY_LSHIFT, [","] = KEY_COMMA, ["."] = KEY_PERIOD,
    ["/"] = KEY_SLASH, ["CTRL"] = KEY_LCONTROL, ["WIN"] = KEY_LWIN, ["ALT"] = KEY_LALT, ["SPACE"] = KEY_SPACE,
    ["MENU"] = KEY_APP,
    ["PRSC"] = KEY_SYSRQ, ["SCRLK"] = KEY_SCROLLLOCK, ["PAUSE"] = KEY_BREAK, ["INS"] = KEY_INSERT, ["HOME"] = KEY_HOME,
    ["PGUP"] = KEY_PAGEUP, ["DEL"] = KEY_DELETE, ["END"] = KEY_END, ["PGDN"] = KEY_PAGEDOWN,
    ["↑"] = KEY_UP, ["←"] = KEY_LEFT, ["↓"] = KEY_DOWN, ["→"] = KEY_RIGHT,
    ["NUM"] = KEY_NUMLOCK, ["/"] = KEY_PAD_DIVIDE, ["*"] = KEY_PAD_MULTIPLY, ["-"] = KEY_PAD_MINUS, ["+"] = KEY_PAD_PLUS,
    ["ENT"] = KEY_PAD_ENTER, ["."] = KEY_PAD_DECIMAL,
    ["1"] = KEY_1, ["2"] = KEY_2, ["3"] = KEY_3, ["4"] = KEY_4, ["5"] = KEY_5, ["6"] = KEY_6, ["7"] = KEY_7, ["8"] = KEY_8, ["9"] = KEY_9, ["0"] = KEY_0,
}

-- Add letters and F-keys
for i = 1, 26 do STRING_TO_KEY[string.char(64 + i)] = _G["KEY_" .. string.char(64 + i)] end
for i = 1, 12 do STRING_TO_KEY["F" .. i] = _G["KEY_F" .. i] end

function PANEL:Init()
    self:Dock(FILL)
    self:DockMargin(20, 20, 20, 20)
    self.Paint = function() end

    self.InfoBar = vgui.Create("DPanel", self)
    self.InfoBar:Dock(TOP)
    self.InfoBar:SetHeight(40)
    self.InfoBar.Paint = function(s, w, h)
        draw.RoundedBox(0, 0, 0, w, h, Color(255, 255, 255, 5))
        
        local activeProf = self:GetActiveProfile()
        local name = activeProf and activeProf.Name or "No Active Profile"
        local bindCount = activeProf and table.Count(activeProf.Binds or {}) or 0
        
        draw.SimpleText(name, "Binder_Main", 50, h / 2, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
        draw.SimpleText(Binder.GetPhrase("binds_count", bindCount), "Binder_Small", w - 20, h / 2, Color(255, 255, 255, 100), TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
    end

    self.KeyboardContainer = vgui.Create("DPanel", self)
    self.KeyboardContainer:Dock(FILL)
    self.KeyboardContainer:DockMargin(0, 40, 0, 0)
    self.KeyboardContainer.Paint = function() end

    self.KeyButtons = {}
    self:BuildKeyboard()
    self:Refresh()
end

function PANEL:GetActiveProfile()
    for _, p in ipairs(Binder.Profiles or {}) do
        if p.Active then return p end
    end
    return nil
end

function PANEL:Refresh()
    local profile = self:GetActiveProfile()
    local binds = profile and profile.Binds or {}

    for _, btnData in ipairs(self.KeyButtons) do
        local isBound = binds[btnData.enum] != nil
        btnData.btn.IsActiveNode = isBound
    end
end

function PANEL:PromptBind(keyStr, keyEnum)
    local profile = self:GetActiveProfile()
    if not profile then return end

    local currentCmd = profile.Binds[keyEnum] or ""

    Derma_StringRequest(
        "Bind " .. keyStr,
        "Enter console command to execute on press (e.g., 'say /raid'):\nLeave blank to unbind.",
        currentCmd,
        function(text)
            if text == "" then
                profile.Binds[keyEnum] = nil
            else
                profile.Binds[keyEnum] = text
            end
            Binder.SaveToServer()
            self:Refresh()
        end
    )
end

function PANEL:CreateKey(parent, text, x, y, w, h)
    local btn = vgui.Create("DButton", parent)
    btn:SetSize(w or 35, h or 35)
    btn:SetPos(x, y)
    btn:SetText("")
    btn.IsActiveNode = false
    
    local keyEnum = STRING_TO_KEY[text]
    
    btn.Paint = function(s, bw, bh)
        local bgColor = s.IsActiveNode and Binder.Config.AccentColor or Color(40, 40, 40)
        if s:IsHovered() then
            bgColor = Color(bgColor.r + 20, bgColor.g + 20, bgColor.b + 20)
        end
        draw.RoundedBox(4, 0, 0, bw, bh, bgColor)
        draw.SimpleText(text, "Binder_Key", bw / 2, bh / 2, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end
    
    btn.DoClick = function()
        if keyEnum then
            self:PromptBind(text, keyEnum)
        else
            print("Binder: Unmapped key - " .. text)
        end
    end

    table.insert(self.KeyButtons, {btn = btn, sysName = text, enum = keyEnum})
end

function PANEL:BuildKeyboard()
    local startX, startY = 10, 10
    local keySize = 38
    local spacing = 4

    -- Main Block
    for r, row in ipairs(KEY_LAYOUT) do
        local rx = startX
        local ry = startY + (r - 1) * (keySize + spacing)
        
        -- Adjustments
        if r == 1 then ry = ry - 5 end 
        
        for k, key in ipairs(row) do
            local kw = keySize
            if key == "BKSP" then kw = keySize * 2 + spacing
            elseif key == "TAB" then kw = keySize * 1.5
            elseif key == "CAPS" then kw = keySize * 1.8
            elseif key == "ENTER" then kw = keySize * 1.8
            elseif key == "SHIFT" then kw = keySize * 2.3
            elseif key == "SPACE" then kw = keySize * 5 + spacing * 4
            elseif key == "CTRL" or key == "ALT" or key == "WIN" then kw = keySize * 1.2
            end

            self:CreateKey(self.KeyboardContainer, key, rx, ry, kw, keySize)
            rx = rx + kw + spacing
        end
    end

    -- Special Keys Block
    local specX = startX + 15 * (keySize + spacing)
    for r, row in ipairs(KEY_SPECIAL) do
        local rx = specX
        local ry = startY + (r - 1) * (keySize + spacing)
        if r == 4 then rx = rx + keySize + spacing end 
        
        for k, key in ipairs(row) do
            self:CreateKey(self.KeyboardContainer, key, rx, ry, keySize, keySize)
            rx = rx + keySize + spacing
        end
    end

    -- Num Pad
    local numX = specX + 4 * (keySize + spacing)
    for r, row in ipairs(NUM_PAD) do
        local rx = numX
        local ry = startY + (r - 1) * (keySize + spacing)
        for k, key in ipairs(row) do
            local kh = keySize
            if key == "+" or key == "ENT" then kh = keySize * 2 + spacing end
            
            local kw = keySize
            if key == "0" then kw = keySize * 2 + spacing end

            self:CreateKey(self.KeyboardContainer, key, rx, ry, kw, kh)
            rx = rx + kw + spacing
        end
    end
end

vgui.Register("Binder_KeybindsTab", PANEL, "EditablePanel")
