package wallet

import (
	"context"
	"fmt"
	"os"
	"strings"
	"time"
)

const (
	WalletConnectStatusStub     = "stub"
	WalletConnectStatusDisabled = "disabled"
)

// Config describes the public WalletConnect v2 posture exposed to clients.
type Config struct {
	Status          string   `json:"status"`
	Enabled         bool     `json:"enabled"`
	ProjectID       string   `json:"projectId"`
	RelayURL        string   `json:"relayUrl"`
	MetadataURL     string   `json:"metadataUrl"`
	RequiredNamespaces []string `json:"requiredNamespaces"`
	SupportedChains []int    `json:"supportedChains"`
	FallbackAuth    string   `json:"fallbackAuth"`
	Message         string   `json:"message"`
	UpdatedAt       string   `json:"updatedAt"`
}

// ConnectResponse is returned while WalletConnect session bridging remains a stub.
type ConnectResponse struct {
	Status      string `json:"status"`
	Enabled     bool   `json:"enabled"`
	URI         string `json:"uri,omitempty"`
	SessionID   string `json:"sessionId,omitempty"`
	ExpiresAt   string `json:"expiresAt,omitempty"`
	FallbackAuth string `json:"fallbackAuth"`
	Message     string `json:"message"`
}

// Session represents a wallet session snapshot for future WalletConnect integration.
type Session struct {
	SessionID string `json:"sessionId"`
	Address   string `json:"address,omitempty"`
	ChainID   int    `json:"chainId,omitempty"`
	Connected bool   `json:"connected"`
	Status    string `json:"status"`
	Message   string `json:"message"`
}

// WalletConnect handles WalletConnect v2 integration posture for the explorer API.
type WalletConnect struct {
	projectID string
	relayURL  string
	chainID   int
}

// NewWalletConnect creates a WalletConnect handler using deployment env vars.
func NewWalletConnect(chainID int) *WalletConnect {
	projectID := strings.TrimSpace(os.Getenv("WALLETCONNECT_PROJECT_ID"))
	relayURL := strings.TrimSpace(os.Getenv("WALLETCONNECT_RELAY_URL"))
	if relayURL == "" {
		relayURL = "wss://relay.walletconnect.org"
	}
	return &WalletConnect{
		projectID: projectID,
		relayURL:  relayURL,
		chainID:   chainID,
	}
}

func (wc *WalletConnect) enabled() bool {
	return wc.projectID != ""
}

// PublicConfig returns the read-only WalletConnect config surface for clients.
func (wc *WalletConnect) PublicConfig() Config {
	status := WalletConnectStatusStub
	if !wc.enabled() {
		status = WalletConnectStatusDisabled
	}
	return Config{
		Status:             status,
		Enabled:            wc.enabled(),
		ProjectID:          wc.projectID,
		RelayURL:           wc.relayURL,
		MetadataURL:        "/api/v1/walletconnect/metadata",
		RequiredNamespaces: []string{"eip155"},
		SupportedChains:    []int{wc.chainID, 1},
		FallbackAuth:       "/api/v1/auth/wallet",
		Message:            wc.publicMessage(),
		UpdatedAt:          time.Now().UTC().Format(time.RFC3339),
	}
}

func (wc *WalletConnect) publicMessage() string {
	if wc.enabled() {
		return "WalletConnect v2 config is published, but session bridging is still stubbed. Use browser wallet auth at /api/v1/auth/wallet until mobile QR sessions ship."
	}
	return "WalletConnect v2 is not configured. Set WALLETCONNECT_PROJECT_ID to publish relay config; browser wallet auth remains available at /api/v1/auth/wallet."
}

// Connect initiates a wallet connection. Live QR sessions are not implemented yet.
func (wc *WalletConnect) Connect(_ context.Context) (*ConnectResponse, error) {
	return &ConnectResponse{
		Status:       WalletConnectStatusStub,
		Enabled:      wc.enabled(),
		FallbackAuth: "/api/v1/auth/wallet",
		Message:      "WalletConnect session creation is stubbed. Use browser extension wallet auth until the relay bridge is enabled.",
	}, fmt.Errorf("walletconnect session bridge not implemented")
}

// GetSession gets a wallet session snapshot. Storage is not implemented yet.
func (wc *WalletConnect) GetSession(_ context.Context, sessionID string) (*Session, error) {
	if strings.TrimSpace(sessionID) == "" {
		return nil, fmt.Errorf("session id is required")
	}
	return &Session{
		SessionID: sessionID,
		Connected: false,
		Status:    WalletConnectStatusStub,
		Message:   "WalletConnect session lookup is stubbed.",
	}, fmt.Errorf("walletconnect session storage not implemented")
}
