package sales

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

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

// An unknown voucher code is a validation ANSWER, not a missing resource. The
// POS till asked "is this code usable?" and must render "voucher tidak
// ditemukan" instead of a 404 that reads like the endpoint is broken. The
// exhaustive UI sweep typed a random code and logged exactly that 404.
func TestValidateSalesVoucher_UnknownCodeIsAValidationAnswer(t *testing.T) {
	st := newFakeStore() // no vouchers registered
	svc := NewService(st, nil, nil)
	h := NewHandler(svc)

	r := chi.NewRouter()
	r.Post("/sales-vouchers/validate", h.ValidateSalesVoucher)

	body := strings.NewReader(`{"code":"TIDAK-ADA","subtotal":10000}`)
	req := httptest.NewRequest(http.MethodPost, "/sales-vouchers/validate", body)
	req.Header.Set("Content-Type", "application/json")
	rec := httptest.NewRecorder()
	r.ServeHTTP(rec, req)

	if rec.Code != http.StatusOK {
		t.Fatalf("unknown voucher = %d, want 200 (a validation answer): %s", rec.Code, rec.Body.String())
	}

	var env struct {
		Data struct {
			Valid  bool   `json:"valid"`
			Reason string `json:"reason"`
		} `json:"data"`
	}
	if err := json.Unmarshal(rec.Body.Bytes(), &env); err != nil {
		t.Fatalf("decode: %v (%s)", err, rec.Body.String())
	}
	if env.Data.Valid {
		t.Error("valid = true for an unknown code")
	}
	if env.Data.Reason == "" {
		t.Error("reason is empty — the till has nothing to show the cashier")
	}
}

// A real failure (not "not found") must keep its own status, so this fix
// cannot swallow genuine server errors.
func TestValidateSalesVoucher_KeepsRealErrors(t *testing.T) {
	st := newFakeStore()
	st.voucherErr = context.DeadlineExceeded
	svc := NewService(st, nil, nil)
	h := NewHandler(svc)

	r := chi.NewRouter()
	r.Post("/sales-vouchers/validate", h.ValidateSalesVoucher)
	req := httptest.NewRequest(http.MethodPost, "/sales-vouchers/validate",
		strings.NewReader(`{"code":"X","subtotal":1}`))
	req.Header.Set("Content-Type", "application/json")
	rec := httptest.NewRecorder()
	r.ServeHTTP(rec, req)

	if rec.Code == http.StatusOK {
		t.Fatalf("a deadline error was reported as 200: %s", rec.Body.String())
	}
}
