package main

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

	"customer-support-system/internal/database"
	"customer-support-system/internal/routes"
	"customer-support-system/pkg/config"
	"customer-support-system/pkg/logger"
)

func main() {
	// Load configuration
	if err := config.LoadConfig(); err != nil {
		log.Fatalf("Failed to load configuration: %v", err)
	}

	// Initialize logger
	logger.InitLogger()

	// Connect to database
	if err := database.Connect(); err != nil {
		logger.WithError(err).Fatal("Failed to connect to database")
	}

	// Run migrations
	if err := database.AutoMigrate(); err != nil {
		logger.WithError(err).Fatal("Failed to run database migrations")
	}

	// Seed database with initial data
	if err := database.SeedDatabase(); err != nil {
		logger.WithError(err).Fatal("Failed to seed database")
	}

	// Set up routes
	router := routes.SetupRoutes()

	// Create HTTP server
	server := &http.Server{
		Addr:         config.AppConfig.Server.GetServerAddress(),
		Handler:      router,
		ReadTimeout:  config.AppConfig.Server.ReadTimeout,
		WriteTimeout: config.AppConfig.Server.WriteTimeout,
	}

	// Start server in a goroutine
	go func() {
		logger.WithField("address", server.Addr).Info("Starting server")
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.WithError(err).Fatal("Failed to start server")
		}
	}()

	// Set up graceful shutdown
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	logger.Info("Shutting down server...")

	// Create context with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// Shutdown server
	if err := server.Shutdown(ctx); err != nil {
		logger.WithError(err).Fatal("Server forced to shutdown")
	}

	// Close database connection
	if err := database.Close(); err != nil {
		logger.WithError(err).Error("Failed to close database connection")
	}

	logger.Info("Server exited")
}
