package rest

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

// SetupRoutes sets up all API routes
func (s *Server) SetupRoutes(mux *http.ServeMux) {
	// Block routes
	mux.HandleFunc("/api/v1/blocks", s.handleListBlocks)
	mux.HandleFunc("/api/v1/blocks/", s.handleBlockDetail)

	// Transaction routes
	mux.HandleFunc("/api/v1/transactions", s.handleListTransactions)
	mux.HandleFunc("/api/v1/transactions/", s.handleTransactionDetail)

	// Address routes
	mux.HandleFunc("/api/v1/addresses", s.handleListAddresses)
	mux.HandleFunc("/api/v1/addresses/", s.handleAddressDetail)

	// Search route
	mux.HandleFunc("/api/v1/search", s.handleSearch)

	// Stats route
	mux.HandleFunc("/api/v2/stats", s.handleStats)

	// Etherscan-compatible API route
	mux.HandleFunc("/api", s.handleEtherscanAPI)

	// Health check
	mux.HandleFunc("/health", s.handleHealth)

	// MetaMask / dual-chain config (Chain 138 + Ethereum Mainnet)
	mux.HandleFunc("/api/config/networks", s.handleConfigNetworks)
	mux.HandleFunc("/api/config/token-list", s.handleConfigTokenList)
	mux.HandleFunc("/api/config/capabilities", s.handleConfigCapabilities)

	// Feature flags endpoint
	mux.HandleFunc("/api/v1/features", s.handleFeatures)

	// Explorer AI endpoints
	mux.HandleFunc("/api/v1/ai/context", s.handleAIContext)
	mux.HandleFunc("/api/v1/ai/chat", s.handleAIChat)
	mux.HandleFunc("/api/v1/ai/metrics", s.handleAIMetrics)

	// Route decision tree proxy
	mux.HandleFunc("/api/v1/routes/tree", s.handleRouteDecisionTree)
	mux.HandleFunc("/api/v1/routes/depth", s.handleRouteDepth)

	// Auth endpoints
	mux.HandleFunc("/api/v1/auth/nonce", s.handleAuthNonce)
	mux.HandleFunc("/api/v1/auth/wallet", s.handleAuthWallet)
	mux.HandleFunc("/api/v1/auth/register", s.handleAuthRegister)
	mux.HandleFunc("/api/v1/auth/login", s.handleAuthLogin)
	mux.HandleFunc("/api/v1/access/me", s.handleAccessMe)
	mux.HandleFunc("/api/v1/access/products", s.handleAccessProducts)
	mux.HandleFunc("/api/v1/access/subscriptions", s.handleAccessSubscriptions)
	mux.HandleFunc("/api/v1/access/admin/subscriptions", s.handleAccessAdminSubscriptions)
	mux.HandleFunc("/api/v1/access/admin/audit", s.handleAccessAdminAudit)
	mux.HandleFunc("/api/v1/access/internal/validate-key", s.handleAccessInternalValidateAPIKey)
	mux.HandleFunc("/api/v1/access/api-keys", s.handleAccessAPIKeys)
	mux.HandleFunc("/api/v1/access/api-keys/", s.handleAccessAPIKeyAction)
	mux.HandleFunc("/api/v1/access/usage", s.handleAccessUsage)
	mux.HandleFunc("/api/v1/access/audit", s.handleAccessAudit)

	// Track 1 routes (public, optional auth)
	// Note: Track 1 endpoints should be registered with OptionalAuth middleware
	// mux.HandleFunc("/api/v1/track1/blocks/latest", s.track1Server.handleLatestBlocks)
	// mux.HandleFunc("/api/v1/track1/txs/latest", s.track1Server.handleLatestTransactions)
	// mux.HandleFunc("/api/v1/track1/block/", s.track1Server.handleBlockDetail)
	// mux.HandleFunc("/api/v1/track1/tx/", s.track1Server.handleTransactionDetail)
	// mux.HandleFunc("/api/v1/track1/address/", s.track1Server.handleAddressBalance)
	// mux.HandleFunc("/api/v1/track1/bridge/status", s.track1Server.handleBridgeStatus)

	// Track 2 routes (require Track 2+)
	// Note: Track 2 endpoints should be registered with RequireAuth + RequireTrack(2) middleware
	// mux.HandleFunc("/api/v1/track2/address/", s.track2Server.handleAddressTransactions)
	// mux.HandleFunc("/api/v1/track2/token/", s.track2Server.handleTokenInfo)
	// mux.HandleFunc("/api/v1/track2/search", s.track2Server.handleSearch)

	// Track 3 routes (require Track 3+)
	// Note: Track 3 endpoints should be registered with RequireAuth + RequireTrack(3) middleware
	// mux.HandleFunc("/api/v1/track3/analytics/flows", s.track3Server.handleFlows)
	// mux.HandleFunc("/api/v1/track3/analytics/bridge", s.track3Server.handleBridge)
	// mux.HandleFunc("/api/v1/track3/analytics/token-distribution/", s.track3Server.handleTokenDistribution)
	// mux.HandleFunc("/api/v1/track3/analytics/address-risk/", s.track3Server.handleAddressRisk)

	// Track 4 routes (require Track 4)
	// Note: Track 4 endpoints should be registered with RequireAuth + RequireTrack(4) + IP whitelist middleware
	// mux.HandleFunc("/api/v1/track4/operator/bridge/events", s.track4Server.handleBridgeEvents)
	// mux.HandleFunc("/api/v1/track4/operator/validators", s.track4Server.handleValidators)
	// mux.HandleFunc("/api/v1/track4/operator/contracts", s.track4Server.handleContracts)
	// mux.HandleFunc("/api/v1/track4/operator/protocol-state", s.track4Server.handleProtocolState)
}

// handleBlockDetail handles GET /api/v1/blocks/{chain_id}/{number} or /api/v1/blocks/{chain_id}/hash/{hash}
func (s *Server) handleBlockDetail(w http.ResponseWriter, r *http.Request) {
	if !s.requireDB(w) {
		return
	}
	path := strings.TrimPrefix(r.URL.Path, "/api/v1/blocks/")
	parts := strings.Split(path, "/")

	if len(parts) < 2 {
		writeValidationError(w, fmt.Errorf("invalid block path"))
		return
	}

	// Validate chain ID
	if err := validateChainID(parts[0], s.chainID); err != nil {
		writeValidationError(w, err)
		return
	}

	if parts[1] == "hash" && len(parts) == 3 {
		// Validate hash format
		hash := normalizeHash(parts[2])
		if !isValidHash(hash) {
			writeValidationError(w, ErrInvalidHash)
			return
		}
		// Get by hash
		s.handleGetBlockByHash(w, r, hash)
	} else {
		// Validate and parse block number
		blockNumber, err := validateBlockNumber(parts[1])
		if err != nil {
			writeValidationError(w, err)
			return
		}
		s.handleGetBlockByNumber(w, r, blockNumber)
	}
}

// handleGetBlockByNumber and handleGetBlockByHash are in blocks.go

// handleTransactionDetail handles GET /api/v1/transactions/{chain_id}/{hash}
func (s *Server) handleTransactionDetail(w http.ResponseWriter, r *http.Request) {
	if !s.requireDB(w) {
		return
	}
	path := strings.TrimPrefix(r.URL.Path, "/api/v1/transactions/")
	parts := strings.Split(path, "/")

	if len(parts) < 2 {
		writeValidationError(w, fmt.Errorf("invalid transaction path"))
		return
	}

	// Validate chain ID
	if err := validateChainID(parts[0], s.chainID); err != nil {
		writeValidationError(w, err)
		return
	}

	// Validate hash format
	hash := normalizeHash(parts[1])
	if !isValidHash(hash) {
		writeValidationError(w, ErrInvalidHash)
		return
	}

	s.handleGetTransactionByHash(w, r, hash)
}

// handleGetTransactionByHash is implemented in transactions.go

// handleAddressDetail handles GET /api/v1/addresses/{chain_id}/{address}
func (s *Server) handleAddressDetail(w http.ResponseWriter, r *http.Request) {
	if !s.requireDB(w) {
		return
	}
	path := strings.TrimPrefix(r.URL.Path, "/api/v1/addresses/")
	parts := strings.Split(path, "/")

	if len(parts) < 2 {
		writeValidationError(w, fmt.Errorf("invalid address path"))
		return
	}

	// Validate chain ID
	if err := validateChainID(parts[0], s.chainID); err != nil {
		writeValidationError(w, err)
		return
	}

	// Validate address format
	address := normalizeAddress(parts[1])
	if !isValidAddress(address) {
		writeValidationError(w, ErrInvalidAddress)
		return
	}

	// Set address in query and call handler
	query := r.URL.Query()
	query.Set("address", address)
	r.URL.RawQuery = query.Encode()
	s.handleGetAddress(w, r)
}
