package main

import (
	"counter/internal/delivery/http"
	"counter/internal/delivery/http/handlers"
	"counter/internal/infrastructure/config"
	"counter/internal/infrastructure/database/postgres"
	"counter/internal/infrastructure/logging"
	"counter/internal/infrastructure/metrics"
	"counter/internal/infrastructure/security"
	"counter/internal/usecase/auth"
	"counter/internal/usecase/counter"

	"github.com/sirupsen/logrus"
)

func main() {
	// 1. Load configuration
	cfg := config.LoadConfig()

	// 2. Initialize logger
	logger, err := logging.InitLogger(cfg)
	if err != nil {
		logrus.Fatal("Failed to initialize logger:", err)
	}

	// 3. Initialize database
	dbConn, err := postgres.NewConnection(cfg, logger)
	if err != nil {
		logger.WithError(err).Fatal("Failed to initialize database")
	}
	defer dbConn.Close()

	// 4. Initialize repositories (infrastructure implementations)
	userRepo := postgres.NewUserRepository(dbConn.GetDB())
	counterRepo := postgres.NewCounterRepository(dbConn.GetDB())

	// 5. Initialize services (infrastructure)
	passwordService := security.NewPasswordService()
	jwtService := security.NewJWTService(cfg.JWTSecret)
	metricsService := metrics.NewPrometheusMetricsService()

	// 6. Initialize use cases (business logic)
	authService := auth.NewAuthService(userRepo, passwordService, jwtService)
	counterService := counter.NewCounterService(counterRepo)

	// 7. Initialize handlers (delivery)
	authHandler := handlers.NewAuthHandler(authService)
	counterHandler := handlers.NewCounterHandler(counterService)

	// 8. Initialize router
	router := http.NewRouter(authHandler, counterHandler, cfg, logger, metricsService, jwtService)
	router.SetupRoutes()

	// 9. Start metrics server
	metricsService.StartMetricsServer(cfg.MetricsPort)

	// 10. Start HTTP server
	port := cfg.Port

	logger.WithFields(logrus.Fields{
		"port":         port,
		"metrics_port": cfg.MetricsPort,
		"log_dir":      cfg.LogDir,
		"log_volume":   cfg.LogVolume,
	}).Info("🚀 Starting Counter Application Server")

	logger.WithFields(logrus.Fields{
		"health_url":   "http://localhost:" + port + "/health",
		"api_url":      "http://localhost:" + port + "/api/v1",
		"frontend_url": "http://localhost:" + port + "/",
		"metrics_url":  "http://localhost:" + cfg.MetricsPort + "/metrics",
	}).Info("✅ Server is ready and accepting connections")

	logger.Fatal(router.GetRouter().Run(":" + port))
}
