---@brief [[
---Utility module for MacroBank providing key processing, parsing, and helper functions.
---@brief ]]

---@tag macrobank-util

local U = {}

--- Convert key sequence to human-readable format
---@param keys string|nil Key sequence to convert
---@return string Readable key representation
function U.readable(keys)
  return vim.fn.keytrans(keys or '')
end

--- Convert string to terminal codes
---@param s string|nil String with key notation
---@return string String with actual terminal codes
function U.to_termcodes(s)
  return vim.api.nvim_replace_termcodes(s or '', true, true, true)
end

--- Parse Live Editor line format
---@param line string|nil Line to parse in format "a  keys"
---@return table|nil Parsed result {reg, text} or nil if invalid
function U.parse_reg_line(line)
  if not line then return nil end
  local reg, text = line:match('^([a-z])%s%s(.*)$')
  if not reg then return nil end
  return { reg = reg, text = text or '' }
end

--- Parse Bank Editor line format  
---@param line string|nil Line to parse in format "name  keys"
---@return table|nil Parsed result {name, text} or nil if invalid
function U.parse_bank_line(line)
  if not line then return nil end
  local name, text = line:match('^(.-)%s%s(.*)$')
  if not name then return nil end
  return { name = vim.trim(name), text = text or '' }
end

--- Generate unique timestamp-based ID
---@return string Unique identifier
function U.uuid()
  local n = tostring(vim.loop.hrtime()):reverse()
  return n:sub(1,8)..'-'..n:sub(9,12)..'-'..n:sub(13,16)
end

-- Messages
function U.info(msg)  vim.notify(msg, vim.log.levels.INFO) end
function U.warn(msg)  vim.notify(msg, vim.log.levels.WARN) end
function U.err(msg)   vim.notify(msg, vim.log.levels.ERROR) end

-- Fuzzy helper (built-in fallback)
function U.matchfuzzy(list, query)
  if query == '' then return list end
  if vim.fn.exists('*matchfuzzy') == 1 then return vim.fn.matchfuzzy(list, query) end
  local out, q = {}, query:lower()
  for _, s in ipairs(list) do if tostring(s):lower():find(q, 1, true) then table.insert(out, s) end end
  return out
end

-- Horizontal rule with left-aligned text ("-- text ------")
function U.hr(text, width, ch)
  ch = ch or '-'
  width = width or vim.o.columns
  if text and text ~= '' then
    local prefix = '--- ' .. text .. ' '
    local fill = width - #prefix
    if fill < 0 then fill = 0 end
    return prefix .. string.rep(ch, fill)
  end
  return string.rep(ch, width)
end

-- Format datetime to natural format
function U.format_datetime(iso_datetime)
  if not iso_datetime then return '?' end
  -- Parse ISO datetime: 2024-01-15T14:30:45Z
  local year, month, day, hour, min, sec = iso_datetime:match('(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)')
  if not year then return iso_datetime end -- fallback to original
  
  local months = {'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'}
  local month_name = months[tonumber(month)] or month
  
  return string.format('%s %d, %s at %s:%s', month_name, tonumber(day), year, hour, min)
end

return U
