package api

import (
	"dejo_node/internal/state"
	"dejo_node/internal/storage"
	"encoding/json"
	"net/http"
	"strings"
)

var GlobalState *state.State
var GlobalBlockStore *storage.BlockStore

func HandleGetBalance(w http.ResponseWriter, r *http.Request) {
	addr := strings.TrimPrefix(r.URL.Path, "/accounts/")
	if strings.Contains(addr, "/") {
		addr = strings.Split(addr, "/")[0]
	}
	if addr == "" {
		http.Error(w, "endereço inválido", http.StatusBadRequest)
		return
	}

	balance := GlobalState.GetBalance(addr)
	resp := map[string]interface{}{
		"address": addr,
		"balance": balance,
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(resp)
}

func HandleGetTransactionsByAddress(w http.ResponseWriter, r *http.Request) {
	addr := strings.TrimPrefix(r.URL.Path, "/accounts/")
	addr = strings.TrimSuffix(addr, "/txs")
	if addr == "" {
		http.Error(w, "endereço inválido", http.StatusBadRequest)
		return
	}

	txs := []map[string]interface{}{}
	blocks, err := GlobalBlockStore.LoadAll()
	if err != nil {
		http.Error(w, "erro ao carregar blocos", http.StatusInternalServerError)
		return
	}
	for _, blk := range blocks {
		for _, tx := range blk.Txns {
			if tx.From == addr || tx.To == addr {
				txs = append(txs, map[string]interface{}{
					"from":  tx.From,
					"to":    tx.To,
					"value": tx.Value,
					"hash":  tx.Hash(),
					"block": blk.Index,
				})
			}
		}
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(txs)
}

func (h *Handler) GetTransactionByHash(w http.ResponseWriter, r *http.Request) {
	hash := strings.TrimPrefix(r.URL.Path, "/transaction/")
	blocks, err := h.Store.LoadAll()
	if err != nil {
		http.Error(w, "erro ao carregar blocos", http.StatusInternalServerError)
		return
	}
	for _, blk := range blocks {
		for _, tx := range blk.Txns {
			if tx.Hash() == hash {
				w.Header().Set("Content-Type", "application/json")
				json.NewEncoder(w).Encode(tx)
				return
			}
		}
	}
	http.Error(w, "transação não encontrada", http.StatusNotFound)
}
