local api = vim.api

local Base = require('fittencode.base')
local Config = require('fittencode.config')
local Log = require('fittencode.log')

local M = {}

function M:new(o)
  o = o or {}
  o.name = 'FittenCodePrompt/Default'
  o.priority = 1
  setmetatable(o, self)
  self.__index = self
  return o
end

function M:is_available(_)
  return true
end

function M:get_name()
  return self.name
end

function M:get_priority()
  return self.priority
end

---@class PromptContextDefault : PromptContext
---@field max_lines? number
---@field max_chars? number

---@param ctx PromptContextDefault
---@return Prompt?
function M:execute(ctx)
  if not ctx.buffer or not api.nvim_buf_is_valid(ctx.buffer) or ctx.row == nil or ctx.col == nil then
    return
  end

  local count = Base.buffer_characters(ctx.buffer)
  if not count then
    return
  end
  if count > Config.options.prompt.max_characters then
    return
  end

  local filename = api.nvim_buf_get_name(ctx.buffer)
  if filename == nil or filename == '' then
    filename = 'NONAME'
  end

  local row = ctx.row
  local col = ctx.col
  ---@diagnostic disable-next-line: param-type-mismatch
  local curllen = string.len(api.nvim_buf_get_lines(ctx.buffer, row, row + 1, false)[1])
  local within_the_line = col ~= curllen
  ---@diagnostic disable-next-line: param-type-mismatch
  local prefix = table.concat(api.nvim_buf_get_text(ctx.buffer, 0, 0, row, col, {}), '\n')
  ---@diagnostic disable-next-line: param-type-mismatch
  local suffix = table.concat(api.nvim_buf_get_text(ctx.buffer, row, col, -1, -1, {}), '\n')

  return {
    name = self.name,
    priority = self.priority,
    filename = filename,
    prefix = prefix,
    suffix = suffix,
    within_the_line = within_the_line,
  }
end

local function make_prefix(buffer, row)
  local prefix = {}
  local cur_line = api.nvim_buf_get_lines(buffer, row, row + 1, false)[1]
  if row > 1 then
    local prev_line = api.nvim_buf_get_lines(buffer, row - 1, row, false)[1]
    prefix[#prefix + 1] = prev_line
  end
  prefix[#prefix + 1] = cur_line
  return prefix
end

---@return SuggestionsPreprocessingFormat?
function M:get_suggestions_preprocessing_format(ctx)
  ---@type SuggestionsPreprocessingFormat
  return {
    prefix = make_prefix(ctx.buffer, ctx.row)
  }
end

return M
