package simple

import (
	"dejo_node/internal/consensus"
	"dejo_node/internal/transactions"
	"errors"
	"fmt"

	"go.uber.org/zap"
)

// SimpleEngine é uma implementação básica do mecanismo de consenso.
type SimpleEngine struct {
	logger *zap.SugaredLogger
}

// New cria uma nova instância do SimpleEngine
func New() consensus.Engine {
	logger, _ := zap.NewProduction()
	return &SimpleEngine{
		logger: logger.Sugar().Named("consensus.simple"),
	}
}

// CanPropose retorna true para permitir que qualquer nó proponha blocos.
func (s *SimpleEngine) CanPropose() bool {
	s.logger.Debug("verificando permissão para propor bloco: permitido")
	return true
}

// Finalize aplica validações de integridade ao bloco antes de ser aceito.
func (s *SimpleEngine) Finalize(block *transactions.Block) error {
	if block == nil {
		s.logger.Error("bloco recebido é nulo")
		return errors.New("bloco nulo")
	}

	s.logger.Infow("finalizando bloco",
		"index", block.Index,
		"txns", len(block.Txns),
		"hash", block.Hash,
	)

	if len(block.Txns) == 0 {
		s.logger.Warn("bloco sem transações")
		return fmt.Errorf("bloco sem transações não é permitido")
	}
	if block.Timestamp == 0 {
		s.logger.Warn("timestamp ausente")
		return fmt.Errorf("timestamp ausente no bloco")
	}

	hashRecalculado := block.CalculateHash()
	if block.Hash != hashRecalculado {
		s.logger.Errorw("hash inconsistente",
			"esperado", hashRecalculado,
			"recebido", block.Hash,
		)
		return fmt.Errorf("hash inconsistente: esperado %s, calculado %s", block.Hash, hashRecalculado)
	}

	s.logger.Infow("bloco finalizado com sucesso", "index", block.Index)
	return nil
}

// Name retorna o identificador deste mecanismo de consenso.
func (s *SimpleEngine) Name() string {
	return "SimpleEngine"
}