" retoor <retoor@molodetz.nl>
" Self-contained config for the ppy container. No external plugins or managers:
" it works out of the box with the stock vim, and the AI edit feature uses only
" curl and the DEVPLACE_* gateway env that every instance is launched with.

set nocompatible
filetype plugin indent on
syntax on

set encoding=utf-8
set fileencoding=utf-8
set termencoding=utf-8
set mouse=a
set backspace=indent,eol,start
set autoindent
set smartindent
set tabstop=4
set shiftwidth=4
set expandtab
set number
set showmatch
set showtabline=2
set laststatus=2
set hidden
set incsearch
set hlsearch
set wildmenu
set ttimeoutlen=50

if has('clipboard')
    set clipboard=unnamedplus
endif

if !isdirectory(expand('~/.vim/undo'))
    call mkdir(expand('~/.vim/undo'), 'p')
endif
set undofile
set undodir=~/.vim/undo

set statusline=%f\ %h%m%r\ %=\ [%{&filetype}]\ [%l,%c]\ %p%%
highlight StatusLine   cterm=bold ctermfg=15 ctermbg=24
highlight StatusLineNC cterm=none ctermfg=250 ctermbg=236
highlight ErrorMsg     cterm=bold ctermfg=red ctermbg=none

let mapleader = ","

inoremap <C-n> <ESC>:tabnext<CR>
inoremap <C-p> <ESC>:tabprevious<CR>
nnoremap <C-n> :tabnext<CR>
nnoremap <C-p> :tabprevious<CR>
nnoremap <Tab> :tabnext<CR>
nnoremap <C-Tab> :tabprevious<CR>
nnoremap <C-e> :tabnew<Space>
inoremap <C-e> <ESC>:tabnew<Space>

if has('autocmd')
    autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif

function! s:GetVisualSelection() abort
    let [l:line_start, l:col_start] = [line("'<"), col("'<")]
    let [l:line_end, l:col_end] = [line("'>"), col("'>")]
    let l:lines = getline(l:line_start, l:line_end)
    if empty(l:lines)
        return ''
    endif
    let l:lines[-1] = l:lines[-1][: l:col_end - (l:line_start == l:line_end ? 1 : 2)]
    let l:lines[0] = l:lines[0][l:col_start - 1 :]
    return join(l:lines, "\n")
endfunction

function! s:GatewayUrl() abort
    let l:base = substitute($DEVPLACE_OPENAI_URL, '/\+$', '', '')
    if empty(l:base)
        return 'https://openai.app.molodetz.nl/v1/chat/completions'
    elseif l:base =~# '/chat/completions$'
        return l:base
    endif
    return l:base . '/chat/completions'
endfunction

function! AiEditSelection() abort
    let l:instruction = input('AI instruction: ')
    if empty(l:instruction)
        echo 'Cancelled.'
        return
    endif
    let l:orig = s:GetVisualSelection()
    if empty(l:orig)
        echo 'No selection.'
        return
    endif
    let l:prompt = l:instruction . "\n\nHere is the text:\n" . l:orig
        \ . "\n\nOutput only the transformed text. No explanations, markdown, or code blocks."
    let l:api_key = !empty($DEVPLACE_API_KEY) ? $DEVPLACE_API_KEY : $DEEPSEEK_API_KEY
    let l:json = '{"model":"deepseek-chat","messages":[{"role":"user","content":' . json_encode(l:prompt) . '}]}'
    let l:cmd = 'curl -sS -X POST ' . shellescape(s:GatewayUrl())
        \ . ' -H ' . shellescape('Authorization: Bearer ' . l:api_key)
        \ . ' -H ' . shellescape('Content-Type: application/json')
        \ . ' -d ' . shellescape(l:json)
    let l:reply = system(l:cmd)
    if v:shell_error
        echohl ErrorMsg | echom 'AI request failed' | echohl None
        return
    endif
    let l:text = matchstr(l:reply, '"content":\s*"\zs\(.\{-}\)\ze"\s*[,}]')
    if empty(l:text)
        echohl ErrorMsg | echom 'No content in AI response' | echohl None
        return
    endif
    let l:text = substitute(l:text, '\\n', "\n", 'g')
    let l:text = substitute(l:text, '\\"', '"', 'g')
    let l:text = substitute(l:text, '\\t', "\t", 'g')
    normal! gv
    normal! c
    call feedkeys(l:text, 'n')
endfunction

xnoremap <silent> <Leader>a :<C-u>call AiEditSelection()<CR>
