package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gogenex/bridge-monitor/internal/config"
	"github.com/gogenex/bridge-monitor/internal/eth"
	"github.com/gogenex/bridge-monitor/internal/genex"
	"github.com/gogenex/bridge-monitor/internal/handler"
	"github.com/gogenex/bridge-monitor/internal/monitor"
	log "github.com/sirupsen/logrus"
)

func main() {
	log.SetFormatter(&log.JSONFormatter{})
	log.Info("Starting Genex Bridge Monitor...")

	cfg := config.Load()

	ethClient := eth.NewClient(cfg.EthereumRPCURL, cfg.AxelarGatewayAddress)
	genexClient := genex.NewClient(cfg.GenexRPCURL, cfg.GenexBridgeTokenAddress)
	alerter := monitor.NewAlerter(cfg.AlertWebhookURL)
	metrics := monitor.NewMetrics()

	reconciler := monitor.NewBridgeMonitor(ethClient, genexClient, alerter, metrics, cfg.DiscrepancyThreshold)

	// 启动定期对账
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		ticker := time.NewTicker(cfg.ReconcileInterval)
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
				result, err := reconciler.Reconcile(ctx)
				if err != nil {
					log.WithError(err).Error("Reconciliation failed")
				} else {
					log.WithField("healthy", result.Healthy).
						WithField("ethLocked", result.EthLocked).
						WithField("genexMinted", result.GenexMinted).
						Info("Reconciliation completed")
				}
			case <-ctx.Done():
				return
			}
		}
	}()

	// HTTP 服务器
	router := handler.NewRouter(reconciler, metrics)
	srv := &http.Server{
		Addr:    fmt.Sprintf(":%d", cfg.Port),
		Handler: router,
	}

	go func() {
		log.Infof("Bridge Monitor HTTP server on :%d", cfg.Port)
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Server error: %v", err)
		}
	}()

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Info("Shutting down...")
	cancel()
	shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer shutdownCancel()
	srv.Shutdown(shutdownCtx)
}
