package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"time"

	"github.com/golang-jwt/jwt/v5"
	"github.com/google/uuid"
)

type Claims struct {
	SessionID string `json:"session_id"`
	PartyID   string `json:"party_id"`
	TokenType string `json:"token_type"`
	jwt.RegisteredClaims
}

func generateAccessToken(secretKey, userID, username string) (string, error) {
	now := time.Now()
	claims := Claims{
		PartyID:   username,
		TokenType: "access",
		RegisteredClaims: jwt.RegisteredClaims{
			ID:        uuid.New().String(),
			Issuer:    "mpc-system",
			Subject:   userID,
			IssuedAt:  jwt.NewNumericDate(now),
			NotBefore: jwt.NewNumericDate(now),
			ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)),
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString([]byte(secretKey))
}

func main() {
	// Get JWT secret from environment or use test value
	jwtSecret := os.Getenv("JWT_SECRET_KEY")
	if jwtSecret == "" {
		jwtSecret = "change_this_jwt_secret_key_to_random_value_min_32_chars"
	}

	// Generate access token
	token, err := generateAccessToken(jwtSecret, "admin", "admin")
	if err != nil {
		fmt.Printf("Failed to generate token: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Generated JWT token: %s\n\n", token)

	// Create keygen session via account-service (without delegate)
	// For true 2-of-3: threshold_t=1 means t+1=2 signers required out of 3 total
	sessionData := map[string]interface{}{
		"threshold_n":      3,
		"threshold_t":      1,
		"username":         "admin",
		"require_delegate": false,
	}

	jsonData, err := json.Marshal(sessionData)
	if err != nil {
		fmt.Printf("Failed to marshal JSON: %v\n", err)
		os.Exit(1)
	}

	// Get API key from environment or use test value
	apiKey := os.Getenv("MPC_API_KEY")
	if apiKey == "" {
		apiKey = "test-api-key"
	}

	// Call account-service API
	req, err := http.NewRequest("POST", "http://localhost:4000/api/v1/mpc/keygen", bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("Failed to create request: %v\n", err)
		os.Exit(1)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-API-Key", apiKey)
	req.Header.Set("Authorization", "Bearer "+token)

	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Failed to send request: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Failed to read response: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Response status: %s\n", resp.Status)
	fmt.Printf("Response body: %s\n", string(body))

	if resp.StatusCode == 200 || resp.StatusCode == 201 {
		var result map[string]interface{}
		if err := json.Unmarshal(body, &result); err == nil {
			if sessionID, ok := result["session_id"].(string); ok {
				fmt.Printf("\n✓ Session created successfully: %s\n", sessionID)
			}
		}
	}
}
