package consensus

import (
	"log"
	"os"
	"strings"
	"sync"
	"time"
)

type LivenessMonitor struct {
	Peers   []string
	Status  map[string]bool
	Mu      sync.RWMutex
	SelfID  string
	Transport *HTTPTransport
}

func NewLivenessMonitor(transport *HTTPTransport) *LivenessMonitor {
	peersEnv := os.Getenv("DEJO_PEERS")
	peers := []string{}
	if peersEnv != "" {
		peers = strings.Split(peersEnv, ",")
	}
	status := make(map[string]bool)
	for _, peer := range peers {
		status[peer] = true
	}
	return &LivenessMonitor{
		Peers: peers,
		Status: status,
		Transport: transport,
		SelfID: os.Getenv("NODE_ID"),
	}
}

func (l *LivenessMonitor) Start() {
	interval := 5 * time.Second
	if val := os.Getenv("DEJO_LIVENESS_INTERVAL"); val != "" {
		if d, err := time.ParseDuration(val); err == nil {
			interval = d
		}
	}
	ticker := time.NewTicker(interval)
	go func() {
		for range ticker.C {
			l.checkPeers()
		}
	}()
}

func (l *LivenessMonitor) checkPeers() {
	for _, peer := range l.Peers {
		err := l.Transport.PingPeer(peer)
		l.Mu.Lock()
		if err != nil {
			if l.Status[peer] {
				log.Println("⚠️ Peer", peer, "está OFFLINE")
			}
			l.Status[peer] = false
		} else {
			if !l.Status[peer] {
				log.Println("✅ Peer", peer, "voltou ONLINE")
			}
			l.Status[peer] = true
		}
		l.Mu.Unlock()
	}
}

func (l *LivenessMonitor) IsAlive(peer string) bool {
	if peer == l.SelfID {
		return true
	}
	l.Mu.RLock()
	defer l.Mu.RUnlock()
	return l.Status[peer]
}