//go:build e2e

package testkit

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type mobileVerificationEntry struct {
	Code string `json:"code"`
}

// InviteMobileForEmail derives a stable E.164-style mobile number from an email address.
// It matches the web E2E helper in agentteam/web/e2e/inviteDialog.ts.
func InviteMobileForEmail(email string) string {
	normalized := strings.ToLower(strings.TrimSpace(email))
	if !strings.Contains(normalized, "@") {
		return email
	}

	var hash uint32
	for _, char := range normalized {
		hash = hash*31 + uint32(char)
	}
	suffix := fmt.Sprintf("%07d", hash%10_000_000)
	return fmt.Sprintf("+1 (555) %s-%s", suffix[:3], suffix[3:])
}

func waitForMobileVerificationCode(ctx context.Context, baseURL, mobile string) (string, error) {
	client := &http.Client{Timeout: MobileVerificationHTTPTimeout()}
	endpoint := strings.TrimRight(baseURL, "/") + "/internal/e2e/mobile-verification/latest?mobile=" + url.QueryEscape(mobile)
	ticker := time.NewTicker(MobileVerificationPollInterval())
	defer ticker.Stop()

	deadline, ok := ctx.Deadline()
	if !ok {
		deadline = time.Now().Add(MobileVerificationPollTimeout())
	}

	for {
		req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
		if err != nil {
			return "", err
		}
		resp, err := client.Do(req)
		if err == nil && resp.StatusCode == http.StatusOK {
			var entry mobileVerificationEntry
			decodeErr := json.NewDecoder(resp.Body).Decode(&entry)
			resp.Body.Close()
			if decodeErr == nil && strings.TrimSpace(entry.Code) != "" {
				return strings.TrimSpace(entry.Code), nil
			}
		} else if resp != nil {
			resp.Body.Close()
		}

		if time.Now().After(deadline) {
			return "", fmt.Errorf("timed out waiting for mobile verification code for %s", mobile)
		}
		select {
		case <-ctx.Done():
			return "", ctx.Err()
		case <-ticker.C:
		}
	}
}
