package rest

import (
	"context"
	"database/sql"
	"encoding/json"
	"net/http"
	"time"
)

// handleGetBlockByNumber handles GET /api/v1/blocks/{chain_id}/{number}
func (s *Server) handleGetBlockByNumber(w http.ResponseWriter, r *http.Request, blockNumber int64) {
	// Validate input (already validated in routes.go, but double-check)
	if blockNumber < 0 {
		writeValidationError(w, ErrInvalidBlockNumber)
		return
	}

	// Add query timeout
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	query := `
		SELECT chain_id, number, hash, parent_hash, timestamp, timestamp_iso, miner,
		       transaction_count, gas_used, gas_limit, size, logs_bloom
		FROM blocks
		WHERE chain_id = $1 AND number = $2
	`

	var chainID, number, transactionCount int
	var hash, parentHash, miner string
	var timestamp time.Time
	var timestampISO sql.NullString
	var gasUsed, gasLimit, size int64
	var logsBloom sql.NullString

	err := s.db.QueryRow(ctx, query, s.chainID, blockNumber).Scan(
		&chainID, &number, &hash, &parentHash, &timestamp, &timestampISO, &miner,
		&transactionCount, &gasUsed, &gasLimit, &size, &logsBloom,
	)

	if err != nil {
		writeNotFound(w, "Block")
		return
	}

	block := map[string]interface{}{
		"chain_id":          chainID,
		"number":            number,
		"hash":              hash,
		"parent_hash":       parentHash,
		"timestamp":         timestamp,
		"miner":             miner,
		"transaction_count": transactionCount,
		"gas_used":          gasUsed,
		"gas_limit":         gasLimit,
		"size":              size,
	}

	if timestampISO.Valid {
		block["timestamp_iso"] = timestampISO.String
	}
	if logsBloom.Valid {
		block["logs_bloom"] = logsBloom.String
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"data": block,
	})
}

// handleGetBlockByHash handles GET /api/v1/blocks/{chain_id}/hash/{hash}
func (s *Server) handleGetBlockByHash(w http.ResponseWriter, r *http.Request, hash string) {
	// Validate hash format (already validated in routes.go, but double-check)
	if !isValidHash(hash) {
		writeValidationError(w, ErrInvalidHash)
		return
	}

	// Add query timeout
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	query := `
		SELECT chain_id, number, hash, parent_hash, timestamp, timestamp_iso, miner,
		       transaction_count, gas_used, gas_limit, size, logs_bloom
		FROM blocks
		WHERE chain_id = $1 AND hash = $2
	`

	var chainID, number, transactionCount int
	var blockHash, parentHash, miner string
	var timestamp time.Time
	var timestampISO sql.NullString
	var gasUsed, gasLimit, size int64
	var logsBloom sql.NullString

	err := s.db.QueryRow(ctx, query, s.chainID, hash).Scan(
		&chainID, &number, &blockHash, &parentHash, &timestamp, &timestampISO, &miner,
		&transactionCount, &gasUsed, &gasLimit, &size, &logsBloom,
	)

	if err != nil {
		writeNotFound(w, "Block")
		return
	}

	block := map[string]interface{}{
		"chain_id":          chainID,
		"number":            number,
		"hash":              blockHash,
		"parent_hash":       parentHash,
		"timestamp":         timestamp,
		"miner":             miner,
		"transaction_count": transactionCount,
		"gas_used":          gasUsed,
		"gas_limit":         gasLimit,
		"size":              size,
	}

	if timestampISO.Valid {
		block["timestamp_iso"] = timestampISO.String
	}
	if logsBloom.Valid {
		block["logs_bloom"] = logsBloom.String
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"data": block,
	})
}
