#!/usr/bin/env bash
# run_llama.sh — uruchamia llama-cli albo llama-server z wybranym modelem z ~/models

MODELS_DIR="$HOME/models"
DEFAULT_ARGS="-e -ngl 99 -t 4"
DEFAULT_PORT="8080"
LAST_MODEL_FILE="$HOME/.llama_last_model"

# ── 1. Lista modeli ──────────────────────────────────────────────────────────
MODELS=()
while IFS= read -r -d '' file; do
  MODELS+=("$(basename "$file")")
done < <(
  find "$MODELS_DIR" -maxdepth 1 -type f \( \
    -iname "*.gguf" -o -iname "*.bin" -o -iname "*.ggml" \
  \) -print0 | sort -z
)

if [[ ${#MODELS[@]} -eq 0 ]]; then
  echo "Brak modeli w $MODELS_DIR" >&2
  exit 1
fi

# ── 2. Funkcje pomocnicze ────────────────────────────────────────────────────
repeat_char() {
  local char="$1"
  local count="$2"
  local out=""
  for ((j=0; j<count; j++)); do
    out+="$char"
  done
  printf '%s' "$out"
}

print_centered_in_box() {
  local width="$1"
  local text="$2"
  local text_len=${#text}
  local left_pad right_pad

  if (( text_len >= width )); then
    printf '║%s║\n' "$text"
    return
  fi

  left_pad=$(( (width - text_len) / 2 ))
  right_pad=$(( width - text_len - left_pad ))

  printf '║%*s%s%*s║\n' \
    "$left_pad" "" \
    "$text" \
    "$right_pad" ""
}

ask_yes_no_default_no() {
  local prompt="$1"
  local answer

  while true; do
    read -rp "$prompt [y/N]: " answer
    answer="${answer,,}"

    if [[ -z "$answer" ]]; then
      return 1
    fi

    case "$answer" in
      y|yes) return 0 ;;
      n|no)  return 1 ;;
      *) echo "  ✗ Wpisz y/yes albo n/no." ;;
    esac
  done
}

# ── 3. Wyświetlenie menu modeli ──────────────────────────────────────────────
MAX_NAME_LEN=0
for model in "${MODELS[@]}"; do
  (( ${#model} > MAX_NAME_LEN )) && MAX_NAME_LEN=${#model}
done

TITLE="Dostępne modele w ~/models"

ROW_WIDTH=$((1 + 4 + 2 + MAX_NAME_LEN + 1))
INNER_WIDTH=$(( ROW_WIDTH > ${#TITLE} ? ROW_WIDTH : ${#TITLE} ))

echo ""
printf '╔%s╗\n' "$(repeat_char '═' "$INNER_WIDTH")"
print_centered_in_box "$INNER_WIDTH" "$TITLE"
printf '╠%s╣\n' "$(repeat_char '═' "$INNER_WIDTH")"

for i in "${!MODELS[@]}"; do
  printf '║ [%2d]  %-*s ║\n' "$((i+1))" "$MAX_NAME_LEN" "${MODELS[$i]}"
done

printf '╚%s╝\n' "$(repeat_char '═' "$INNER_WIDTH")"
echo ""

# ── 4. Wybór modelu ──────────────────────────────────────────────────────────
LAST_MODEL=""
if [[ -f "$LAST_MODEL_FILE" ]]; then
  LAST_MODEL=$(cat "$LAST_MODEL_FILE")
  LAST_INDEX=-1
  for i in "${!MODELS[@]}"; do
    if [[ "${MODELS[$i]}" == "$LAST_MODEL" ]]; then
      LAST_INDEX=$i
      break
    fi
  done
fi

while true; do
  if [[ -n "$LAST_MODEL" ]] && [[ $LAST_INDEX -ge 0 ]]; then
    read -rp "Wybierz numer modelu (1-${#MODELS[@]}, Enter = $LAST_MODEL): " CHOICE
  else
    read -rp "Wybierz numer modelu (1-${#MODELS[@]}): " CHOICE
  fi

  if [[ -z "$CHOICE" ]] && [[ -n "$LAST_MODEL" ]] && [[ $LAST_INDEX -ge 0 ]]; then
    SELECTED_MODEL="$LAST_MODEL"
    break
  fi

  if [[ "$CHOICE" =~ ^[0-9]+$ ]] && \
     [[ "$CHOICE" -ge 1 ]] && \
     [[ "$CHOICE" -le ${#MODELS[@]} ]]; then
    SELECTED_MODEL="${MODELS[$((CHOICE-1))]}"
    break
  fi
  echo "  Nieprawidłowy wybór, spróbuj ponownie."
done

echo "$SELECTED_MODEL" > "$LAST_MODEL_FILE"

echo ""
echo "  Wybrany model: $SELECTED_MODEL"

# ── 5. Tryb uruchomienia ─────────────────────────────────────────────────────
echo ""
if ask_yes_no_default_no "Uruchomić jako serwer?"; then
  RUN_AS_SERVER=1
  read -rp "Port serwera (Enter = $DEFAULT_PORT): " INPUT_PORT

  if [[ -z "$INPUT_PORT" ]]; then
    SERVER_PORT="$DEFAULT_PORT"
  else
    SERVER_PORT="$INPUT_PORT"
  fi

  echo "  → Uruchomienie w trybie serwera na porcie: $SERVER_PORT"

  read -rp "  Klucz API (Enter = brak): " INPUT_API_KEY
  if [[ -n "$INPUT_API_KEY" ]]; then
    API_KEY_ARG="--api-key $INPUT_API_KEY"
    echo "  → Klucz API: ustawiony"
  else
    API_KEY_ARG=""
    echo "  → Klucz API: brak"
  fi

else
  RUN_AS_SERVER=0
  SERVER_PORT="$DEFAULT_PORT"
  API_KEY_ARG=""
  echo "  → Uruchomienie w trybie CLI."
fi

# ── 6. Własne argumenty ──────────────────────────────────────────────────────
echo ""
echo "  Domyślne argumenty: $DEFAULT_ARGS"
read -rp "  Własne argumenty (Enter = użyj domyślnych): " CUSTOM_ARGS
echo ""

if [[ -z "$CUSTOM_ARGS" ]]; then
  FINAL_ARGS="$DEFAULT_ARGS"
  echo "  → Używam domyślnych argumentów."
else
  FINAL_ARGS="$CUSTOM_ARGS"
  echo "  → Używam własnych argumentów: $FINAL_ARGS"
fi

# ── 7. Budowanie i uruchamianie polecenia ────────────────────────────────────
if [[ "$RUN_AS_SERVER" -eq 1 ]]; then
  CMD="llama-server --model \"$MODELS_DIR/$SELECTED_MODEL\" --port \"$SERVER_PORT\" --host 0.0.0.0 ${API_KEY_ARG:+$API_KEY_ARG }$FINAL_ARGS"
else
  CMD="llama-cli -m \"$MODELS_DIR/$SELECTED_MODEL\" $FINAL_ARGS"
fi

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "  Uruchamiam:"
echo "  $CMD"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

# shellcheck disable=SC2086
if [[ "$RUN_AS_SERVER" -eq 1 ]]; then
  llama-server --model "$MODELS_DIR/$SELECTED_MODEL" \
    --port "$SERVER_PORT" \
    --host 0.0.0.0 \
    ${API_KEY_ARG:+$API_KEY_ARG} \
    $FINAL_ARGS
else
  llama-cli -m "$MODELS_DIR/$SELECTED_MODEL" $FINAL_ARGS
fi
