package transactions

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"time"
)

// Block representa um bloco da blockchain DEJO.
type Block struct {
	Index     uint64          // posição na cadeia
	PrevHash  string          // hash do bloco anterior
	Txns      []*Transaction  // lista de transações
	Timestamp int64           // timestamp unix
	Nonce     uint64          // reservado para PoW/futuro
	Hash      string          // hash do bloco
}

// CreateBlock monta um novo bloco com transações válidas.
func CreateBlock(prevHash string, txs []*Transaction, index uint64) *Block {
	block := &Block{
		Index:     index,
		PrevHash:  prevHash,
		Txns:      txs,
		Timestamp: time.Now().Unix(),
		Nonce:     0, // reservado para PoW ou consenso
	}

	block.Hash = block.CalculateHash()
	return block
}

// CalculateHash calcula o hash do bloco.
func (b *Block) CalculateHash() string {
	h := sha256.New()
	h.Write([]byte(fmt.Sprintf("%d:%s:%d:%d",
		b.Index, b.PrevHash, b.Timestamp, b.Nonce)))
	for _, tx := range b.Txns {
		h.Write([]byte(tx.Hash()))
	}
	return hex.EncodeToString(h.Sum(nil))
}

// ComputeHash atualiza o campo Hash com base nos dados atuais do bloco.
func (b *Block) ComputeHash() {
	b.Hash = b.CalculateHash()
}