-- smarana.nvim — Preview integration
-- Auto-start typst-preview.nvim on smarana.typ and pin it as main

local M = {}
local util = require("smarana.util")

local preview_active = false

--- Pin smarana.typ as the main file via tinymist LSP executeCommand.
---@param smarana_typ string absolute path to smarana.typ
---@return boolean success
local function pin_main(smarana_typ)
  local clients = vim.lsp.get_clients({ name = "tinymist" })
  if #clients > 0 then
    local client = clients[1]
    if client.server_capabilities then
      client:request("workspace/executeCommand", {
        command = "tinymist.pinMain",
        arguments = { smarana_typ },
      })
      return true
    end
  end
  return false
end

--- Auto-start preview for a smarana notebook.
--- Uses a hidden floating window to avoid flickering the main UI.
---@param root string notebook root path
function M.auto_start(root)
  if preview_active then return end

  -- Check if typst-preview is available
  local ok = pcall(require, "typst-preview")
  if not ok then
    vim.notify("smarana: typst-preview.nvim not found, skipping preview", vim.log.levels.WARN)
    return
  end

  local smarana_typ = root .. "/smarana.typ"
  if vim.fn.filereadable(smarana_typ) ~= 1 then return end

  preview_active = true

  -- Load smarana.typ into a buffer without displaying it
  vim.fn.bufadd(smarana_typ)
  local smarana_bufnr = vim.fn.bufnr(smarana_typ)
  vim.fn.bufload(smarana_bufnr)

  -- Create a tiny hidden floating window (off-screen, 1x1)
  local float_win = vim.api.nvim_open_win(smarana_bufnr, false, {
    relative = "editor",
    width = 1,
    height = 1,
    row = 0,
    col = 0,
    style = "minimal",
    noautocmd = true,
  })

  -- Briefly enter the float to run TypstPreview, then close it
  local original_win = vim.api.nvim_get_current_win()
  vim.api.nvim_set_current_win(float_win)
  vim.cmd("TypstPreview")

  -- Restore focus immediately and close the float after preview attaches
  vim.api.nvim_set_current_win(original_win)
  vim.defer_fn(function()
    if vim.api.nvim_win_is_valid(float_win) then
      vim.api.nvim_win_close(float_win, true)
    end
  end, 500)

  -- Pin smarana.typ via tinymist LSP, retrying if LSP isn't ready
  local function try_pin()
    return pin_main(smarana_typ)
  end

  if not try_pin() then
    vim.defer_fn(function()
      if not try_pin() then
        vim.defer_fn(try_pin, 1000)
      end
    end, 500)
  end
end

--- Toggle preview state.
function M.toggle()
  if preview_active then
    pcall(vim.cmd, "TypstPreviewStop")
    preview_active = false
  else
    local root = util.resolve_root()
    if root then
      preview_active = false -- reset so auto_start runs
      M.auto_start(root)
    else
      -- Not in a smarana notebook, just toggle typst-preview normally
      pcall(vim.cmd, "TypstPreviewToggle")
    end
  end
end

return M
