package main

import (
	"context"
	"dejo_node/internal/api"
	"dejo_node/internal/consensus"
	"dejo_node/internal/mempool"
	"dejo_node/internal/monitor"
	"dejo_node/internal/staking"
	"dejo_node/internal/state"
	"dejo_node/internal/storage"
	"dejo_node/internal/transactions"
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	ctx := context.Background()

	nodeID := os.Getenv("NODE_ID")
	port := os.Getenv("DEJO_PORT")
	validators := strings.Split(os.Getenv("DEJO_VALIDATORS"), ",")
	peers := strings.Split(os.Getenv("DEJO_PEERS"), ",")

	blockStore := storage.NewBlockStore()
	stakingStore := staking.NewStakingStore()
	mp := mempool.NewMempool()
	globalState := state.NewState()

	// Heartbeat function
	pingPeer := func(peer string) bool {
		client := http.Client{Timeout: 2 * time.Second}
		resp, err := client.Get(peer + "/health")
		if err != nil {
			return false
		}
		defer resp.Body.Close()
		return resp.StatusCode == http.StatusOK
	}

	monitor := monitor.NewMonitor(pingPeer)

	handler := api.NewHandler(blockStore, stakingStore, mp, globalState)

	server := api.NewServer(handler)
	go func() {
		fmt.Printf("🌐 Servidor HTTP iniciado na porta :%s\n", port)
		http.ListenAndServe(":"+port, server)
	}()

	round := consensus.NewRoundState(1)
	transport := consensus.NewHTTPTransport()

	consensus.StartConsensusLoop(
		ctx,
		nodeID,
		round,
		transport.Receive,
		700,
		blockStore,
		func() *transactions.Block {
			return &transactions.Block{
				Txns: mp.GetTransactions(),
			}
		},
		stakingStore,
		globalState,
		monitor,
	)
}
