package suggestions

import (
	"context"
	"encoding/json"
	"net/http"
	"strings"
	"testing"

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

// recordingClient captures the last Complete request so the rewrite test can
// assert the styled system prompt and the selected passage reached the model.
type recordingClient struct {
	response string
	last     llm.CompletionRequest
}

func (c *recordingClient) Complete(_ context.Context, req llm.CompletionRequest) (string, error) {
	c.last = req
	return c.response, nil
}

func (c *recordingClient) Stream(_ context.Context, _ llm.CompletionRequest) (<-chan string, error) {
	ch := make(chan string)
	close(ch)
	return ch, nil
}

func TestRewrite(t *testing.T) {
	// The model wraps its answer in quotes; cleanRewrite should strip them.
	client := &recordingClient{response: `"I have two apples."`}
	srv, docID, _ := newTestServer(t, client)

	rec := do(t, srv, http.MethodPost, "/docs/"+docID+"/rewrite",
		`{"text":"I has two apple.","style":"academic"}`)
	if rec.Code != http.StatusOK {
		t.Fatalf("rewrite: code=%d body=%s", rec.Code, rec.Body)
	}
	var resp rewriteResponse
	if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
		t.Fatalf("decode: %v", err)
	}
	if resp.Rewrite != "I have two apples." {
		t.Fatalf("rewrite = %q, want the de-quoted text", resp.Rewrite)
	}

	// The passage rode in as the user turn, and the style steered the system turn.
	msgs := client.last.Messages
	if len(msgs) != 2 || msgs[0].Role != "system" || msgs[1].Role != "user" {
		t.Fatalf("unexpected message shape: %+v", msgs)
	}
	if msgs[1].Content != "I has two apple." {
		t.Fatalf("passage not forwarded: %q", msgs[1].Content)
	}
	if !strings.Contains(msgs[0].Content, "academic") {
		t.Fatalf("system prompt missing academic style guidance:\n%s", msgs[0].Content)
	}
}

func TestRewriteEmptyText(t *testing.T) {
	client := &recordingClient{response: "anything"}
	srv, docID, _ := newTestServer(t, client)
	rec := do(t, srv, http.MethodPost, "/docs/"+docID+"/rewrite", `{"text":"   ","style":"natural"}`)
	if rec.Code != http.StatusBadRequest {
		t.Fatalf("empty text: want 400, got %d", rec.Code)
	}
}

func TestRewriteUnknownDoc(t *testing.T) {
	client := &recordingClient{response: "anything"}
	srv, _, _ := newTestServer(t, client)
	rec := do(t, srv, http.MethodPost, "/docs/does-not-exist/rewrite",
		`{"text":"hello there","style":"natural"}`)
	if rec.Code != http.StatusNotFound {
		t.Fatalf("unknown doc: want 404, got %d", rec.Code)
	}
}
