package main

import (
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"strings"
	"time"
)

// waktuDemo adalah waktu beku supaya output demo selalu identik.
var waktuDemo = time.Date(2026, 1, 15, 8, 0, 0, 0, time.UTC)

// genDemo mengeluarkan kode dari daftar tetap secara bergilir —
// deterministik untuk demo (produksi memakai Base62Generator acak).
type genDemo struct {
	daftar []string
	i      int
}

// NewCode memenuhi interface CodeGenerator.
func (g *genDemo) NewCode() (string, error) {
	code := g.daftar[g.i%len(g.daftar)]
	g.i++
	return code, nil
}

// demo menjalankan alur lengkap layanan di atas MemoryURLRepository
// tanpa PostgreSQL dan tanpa membuka port: shorten → redirect (dua
// kali) → stats → galat 404. Gunakan `go run . demo` untuk mencoba.
func demo() {
	gen := &genDemo{daftar: []string{"b1Gk0D3", "zP9xQ2w"}}
	svc := NewShortenService(NewMemoryURLRepository(), gen, FixedClock{Waktu: waktuDemo})
	router := NewRouter(svc, "http://short.test")

	fmt.Println("=== Demo URL shortener (mode memori, tanpa PostgreSQL) ===")
	kirimDemo(router, "POST", "/shorten", `{"url":"https://example.com/tutorial-go-yang-sangat-panjang"}`)
	kirimDemo(router, "POST", "/shorten", `{"url":"bukan-url-lengkap"}`)
	kirimDemo(router, "GET", "/b1Gk0D3", "")
	kirimDemo(router, "GET", "/b1Gk0D3", "")
	kirimDemo(router, "GET", "/stats/b1Gk0D3", "")
	kirimDemo(router, "GET", "/stats/takDikn", "")
}

// kirimDemo mengirim satu permintaan ke router lewat recorder, lalu
// mencetak status, header Location, dan body respons.
func kirimDemo(router http.Handler, metode, target, body string) {
	var rdr io.Reader
	if body != "" {
		rdr = strings.NewReader(body)
	}
	req := httptest.NewRequest(metode, target, rdr)
	if body != "" {
		req.Header.Set("Content-Type", "application/json")
	}
	rec := httptest.NewRecorder()
	router.ServeHTTP(rec, req)

	fmt.Printf("%s %s → %d %s\n", metode, target, rec.Code, http.StatusText(rec.Code))
	if loc := rec.Header().Get("Location"); loc != "" {
		fmt.Printf("  Location: %s\n", loc)
	}
	if b := strings.TrimSpace(rec.Body.String()); b != "" {
		fmt.Printf("  body: %s\n", b)
	}
}
