-- Improved Neovim ftplugin for mail with robust abook integration
-- Debugging enabled: check :messages for logs

local function log(msg)
  -- print("[abook] " .. msg)
end

log("ftplugin/mail.lua loaded for filetype: " .. vim.bo.filetype)

-- Omnifunc completion for email addresses
function _G.mail_complete(findstart, base)
  if findstart == 1 then
    local line = vim.api.nvim_get_current_line()
    local col = vim.fn.col(".")
    local line_to_cursor = line:sub(1, col - 1)

    -- Detect if we are on a header line that takes email addresses
    if not line_to_cursor:match("^%s*[Tt][Oo]:") and
       not line_to_cursor:match("^%s*[Cc][Cc]:") and
       not line_to_cursor:match("^%s*[Bb][Cc][Cc]:") and
       not line_to_cursor:match("^%s*[Ff][Rr][Oo][Mm]:") and
       not line_to_cursor:match("^%s*[Rr][Ee][Pp][Ll][Yy]%-[Tt][Oo]:") then
      return -1
    end

    -- Find start of current address (after comma or space)
    local start = line_to_cursor:reverse():find("[%s,]")
    if start then
      return col - start
    else
      return line_to_cursor:find(":") or 0
    end
  else
    -- Query abook
    log("Querying abook for: " .. base)
    local cmd = string.format('abook --mutt-query "%s" 2>/dev/null', base)
    local handle = io.popen(cmd)
    if not handle then return {} end

    local matches = {}
    for line in handle:lines() do
      if line ~= "" and not line:match("^%s*$") then
        local email, name = line:match("^([^\t]+)\t([^\t]+)")
        if email then
          local formatted = (name and name ~= "") and string.format("%s <%s>", name, email) or email
          table.insert(matches, { word = formatted, abbr = line:gsub("\t", " | "):gsub("%s+$", "") })
        end
      end
    end
    handle:close()
    log("Found " .. #matches .. " matches")
    return matches
  end
end

-- Set omnifunc locally
vim.opt_local.omnifunc = "v:lua.mail_complete"

-- Trigger completion on Tab in header lines
vim.keymap.set("i", "<Tab>", function()
  local line = vim.api.nvim_get_current_line()
  local col = vim.fn.col(".")
  local line_to_cursor = line:sub(1, col - 1)

  local is_header = line_to_cursor:match("^%s*[Tt][Oo]:") or
                   line_to_cursor:match("^%s*[Cc][Cc]:") or
                   line_to_cursor:match("^%s*[Bb][Cc][Cc]:") or
                   line_to_cursor:match("^%s*[Ff][Rr][Oo][Mm]:") or
                   line_to_cursor:match("^%s*[Rr][Ee][Pp][Ll][Yy]%-[Tt][Oo]:")

  if is_header then
    return "<C-x><C-o>"
  end

  return "<Tab>"
end, { expr = true, buffer = true })

-- Interactive picker
local function pick_email()
  log("Manual picker triggered")
  local handle = io.popen('abook --mutt-query "" 2>/dev/null')
  if not handle then
    vim.notify("Could not query abook", vim.log.levels.ERROR)
    return
  end

  local items = {}
  for line in handle:lines() do
    if line ~= "" and not line:match("^%s*$") then
      local email, name = line:match("^([^\t]+)\t([^\t]+)")
      if email then
        local formatted = (name and name ~= "") and string.format("%s <%s>", name, email) or email
        table.insert(items, { display = line:gsub("\t", " | "):gsub("%s+$", ""), value = formatted })
      end
    end
  end
  handle:close()

  if #items == 0 then
    vim.notify("No addresses in abook", vim.log.levels.WARN)
    return
  end

  table.sort(items, function(a, b) return a.display < b.display end)

  -- Use Snacks.picker if available, otherwise fallback to vim.ui.select
  if _G.Snacks and Snacks.picker then
      Snacks.picker.select(items, {
          prompt = "Select Recipient",
          format_item = function(item) return item.display end,
      }, function(choice)
          if choice then
            local row, col = unpack(vim.api.nvim_win_get_cursor(0))
            local line = vim.api.nvim_get_current_line()
            local before = line:sub(1, col)
            local after = line:sub(col + 1)
            if before:match("[:%,]$") then choice.value = " " .. choice.value end
            vim.api.nvim_set_current_line(before .. choice.value .. after)
            vim.api.nvim_win_set_cursor(0, { row, col + #choice.value })
          end
      end)
  else
      vim.ui.select(items, {
        prompt = "Select Recipient:",
        format_item = function(item) return item.display end,
      }, function(choice)
        if choice then
          local row, col = unpack(vim.api.nvim_win_get_cursor(0))
          local line = vim.api.nvim_get_current_line()
          local before = line:sub(1, col)
          local after = line:sub(col + 1)
          if before:match("[:%,]$") then choice.value = " " .. choice.value end
          vim.api.nvim_set_current_line(before .. choice.value .. after)
          vim.api.nvim_win_set_cursor(0, { row, col + #choice.value })
        end
      end)
  end
end

-- Keybinds
vim.keymap.set("i", "<C-f>", pick_email, { buffer = true, desc = "Pick email from abook" })
vim.keymap.set("n", "<C-f>", pick_email, { buffer = true, desc = "Pick email from abook" })
