package sync

import (
	"context"
	"fmt"
	"net/http"
	"strings"
	"time"
)

// demoConnector fabricates tickets locally (§11.11) so the entire
// import→atomize→publish→claim flow is demonstrable offline. Deterministic:
// the same project key always yields the same tickets. A project key ending
// in "-ORPHAN" omits the last ticket from ListAssignedKeys to exercise the
// orphan flow.
type demoConnector struct {
	projectKey string
}

var demoTickets = []struct {
	suffix      int
	typ         string
	title       string
	description string
}{
	{1, "epic", "Customer self-service portal",
		"Build a portal where customers can view invoices, update billing details, and download usage reports. Must integrate with the existing SSO and billing systems."},
	{2, "story", "User import from CSV",
		"As an admin I can bulk-import users from a CSV file with column mapping, validation preview, and an idempotent re-run option. Errors are reported per row."},
	{3, "story", "Email notification preferences",
		"As a user I can choose which events trigger email notifications (digest, immediate, off) and unsubscribe via a one-click link that does not require login."},
	{4, "task", "Rate-limit public API endpoints",
		"Add per-token rate limiting to all public API endpoints with sensible defaults, 429 responses with Retry-After, and metrics for limit hits."},
	{5, "task", "Fix timezone handling in reports",
		"Scheduled reports render dates in server time instead of the workspace timezone. Audit all report templates and normalize via the workspace setting."},
}

func (d *demoConnector) Authorize(*http.Request) {}

func (d *demoConnector) TestConnection(context.Context) error { return nil }

func (d *demoConnector) key(i int) string {
	base := strings.TrimSuffix(strings.ToUpper(d.projectKey), "-ORPHAN")
	if base == "" {
		base = "DEMO"
	}
	return fmt.Sprintf("%s-%d", base, i)
}

func (d *demoConnector) FetchUpdated(_ context.Context, _ string, _ time.Time) ([]Ticket, error) {
	out := make([]Ticket, 0, len(demoTickets))
	for _, dt := range demoTickets {
		out = append(out, Ticket{
			Key:         d.key(dt.suffix),
			URL:         "https://demo.invalid/browse/" + d.key(dt.suffix),
			Type:        dt.typ,
			Title:       dt.title,
			Description: dt.description,
			Raw:         map[string]any{"demo": true, "suffix": dt.suffix},
		})
	}
	return out, nil
}

func (d *demoConnector) ListAssignedKeys(context.Context, string) ([]string, error) {
	n := len(demoTickets)
	if strings.HasSuffix(strings.ToUpper(d.projectKey), "-ORPHAN") {
		n-- // last ticket "disappears" upstream → orphan flow
	}
	keys := make([]string, 0, n)
	for _, dt := range demoTickets[:n] {
		keys = append(keys, d.key(dt.suffix))
	}
	return keys, nil
}
