package suggestions

import (
	"database/sql"
	"encoding/json"
	"errors"
	"net/http"
	"strings"

	"github.com/go-chi/chi/v5"

	"gitea.parodia.dev/drwily/petal/internal/db"
	"gitea.parodia.dev/drwily/petal/internal/llm"
)

// rewriteRequest is the body the selection bubble posts: the selected passage
// and the target style ("natural", "academic", …). The text is the client's
// live selection — unlike a checkpoint, there is nothing to anchor server-side,
// so the rewrite is stateless and never persisted (the editor applies it
// directly, and the version history captures the resulting document change).
type rewriteRequest struct {
	Text  string `json:"text"`
	Style string `json:"style"`
}

type rewriteResponse struct {
	Rewrite string `json:"rewrite"`
}

// rewrite runs a one-shot tone-rewrite over a selected passage and returns the
// rewritten text for the editor to preview. The document id scopes the request
// to the owner (and reserves room to feed document context to the model later),
// even though the passage itself rides in the body.
func (h *Handler) rewrite(w http.ResponseWriter, r *http.Request) {
	docID := chi.URLParam(r, "id")

	var body rewriteRequest
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		errorJSON(w, http.StatusBadRequest, "invalid request body")
		return
	}

	text := strings.TrimSpace(body.Text)
	if text == "" {
		errorJSON(w, http.StatusBadRequest, "no text to rewrite")
		return
	}
	if len([]rune(text)) > llm.RewriteMaxRunes {
		errorJSON(w, http.StatusBadRequest, "selection too long to rewrite")
		return
	}

	// Scope to the owner so a stray id can't drive rewrites against another
	// user's document (and 404 cleanly when it doesn't exist).
	var exists int
	err := h.DB.QueryRow(
		`SELECT 1 FROM documents WHERE id = ? AND user_id = ?`,
		docID, db.LocalUserID,
	).Scan(&exists)
	if errors.Is(err, sql.ErrNoRows) {
		errorJSON(w, http.StatusNotFound, "document not found")
		return
	}
	if err != nil {
		serverError(w, err)
		return
	}

	out, err := llm.RunRewrite(r.Context(), h.Client, text, body.Style)
	if err != nil {
		errorJSON(w, http.StatusBadGateway, "rewrite failed: "+err.Error())
		return
	}

	writeJSON(w, http.StatusOK, rewriteResponse{Rewrite: out})
}
