package webui

import (
	"net/http"
	"net/http/httptest"
	"strconv"
	"strings"
	"testing"
	"time"

	"mailgoserver/internal/db"
)

// 1x1 transparent PNG, base64-encoded — a minimal real image for the attachment part.
const testPNGBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="

func buildTestMIMEMessageWithImage() string {
	boundary := "testboundary123"
	return strings.Join([]string{
		"From: attacker@evil.example",
		"To: victim@example.com",
		"Subject: Free money",
		"MIME-Version: 1.0",
		"Content-Type: multipart/mixed; boundary=\"" + boundary + "\"",
		"",
		"--" + boundary,
		`Content-Type: text/html; charset="UTF-8"`,
		"",
		"<p>Click <b>here</b> to claim your prize.</p>",
		"",
		"--" + boundary,
		"Content-Type: image/png",
		"Content-Transfer-Encoding: base64",
		`Content-Disposition: attachment; filename="lure.png"`,
		"",
		testPNGBase64,
		"",
		"--" + boundary + "--",
	}, "\r\n")
}

// TestViewMessageContentRendersHTMLAndAttachmentInlineForStoredContent confirms that
// when a log's message_body holds a full raw message (the new default for a
// quarantined/opted-in message — see session.go's storeContent), the "View Full
// Message" page actually renders the real HTML body and offers the attachment inline
// (as a data: URI, no separate file/route needed) — not just a plain-text dump, and
// not silently dropping the image the way the old text-only capture always did.
func TestViewMessageContentRendersHTMLAndAttachmentInlineForStoredContent(t *testing.T) {
	app := newTestApp(t)
	mux := app.Mux()
	cookie := loginSession(t, app)

	logID, err := app.DB.InsertEmailLog(db.EmailLog{
		MessageID: "test-msg-id", Timestamp: time.Now(), PeerIP: "203.0.113.5",
		MailFrom: "attacker@evil.example", ToAddress: "victim@example.com", Subject: "Free money",
		EmailHeaders: "From: attacker@evil.example\nSubject: Free money",
		MessageBody:  buildTestMIMEMessageWithImage(),
		Status:       "failed",
	})
	if err != nil {
		t.Fatal(err)
	}

	req := httptest.NewRequest(http.MethodGet, Prefix+"/msg/content/"+strconv.FormatInt(logID, 10), nil)
	req.AddCookie(cookie)
	rec := httptest.NewRecorder()
	mux.ServeHTTP(rec, req)
	if rec.Code != http.StatusOK {
		t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String())
	}
	body := rec.Body.String()

	if !strings.Contains(body, "Click") || !strings.Contains(body, "<b>here</b>") {
		t.Errorf("expected the sanitized HTML body rendered, got:\n%s", body)
	}
	if !strings.Contains(body, "data:image/png;base64,") {
		t.Error("expected the attachment rendered inline as a data: URI")
	}
	if !strings.Contains(body, "lure.png") {
		t.Error("expected the attachment's filename shown")
	}
	// This is fetched into a modal on the logs page, not navigated to directly — it
	// must be a bare fragment, not a full page with the dashboard's own nav/sidebar.
	if strings.Contains(body, "<!DOCTYPE") || strings.Contains(body, "Email Server Management") || strings.Contains(body, "sidebar_email") {
		t.Errorf("expected a bare fragment with no dashboard chrome, got:\n%s", body)
	}
}
