package main

import (
	"context"
	"flag"
	"fmt"
	"os"

	"git.threesix.ai/jordan/slack5-1770529463/pkg/app"
	"git.threesix.ai/jordan/slack5-1770529463/pkg/database"
	"git.threesix.ai/jordan/slack5-1770529463/pkg/logging"
	"git.threesix.ai/jordan/slack5-1770529463/services/preferences-api/internal/adapter/postgres"
	"git.threesix.ai/jordan/slack5-1770529463/services/preferences-api/internal/api"
	"git.threesix.ai/jordan/slack5-1770529463/services/preferences-api/internal/config"
	"git.threesix.ai/jordan/slack5-1770529463/services/preferences-api/internal/migrations"
	"git.threesix.ai/jordan/slack5-1770529463/services/preferences-api/internal/service"
)

func main() {
	// Parse flags
	exportOpenAPI := flag.Bool("export-openapi", false, "Export OpenAPI spec to stdout and exit")
	flag.Parse()

	// If exporting OpenAPI, generate spec and exit (used by CI for docs generation)
	if *exportOpenAPI {
		spec := api.NewServiceSpec()
		jsonBytes, err := spec.JSON()
		if err != nil {
			fmt.Fprintf(os.Stderr, "failed to generate OpenAPI spec: %v\n", err)
			os.Exit(1)
		}
		fmt.Println(string(jsonBytes))
		os.Exit(0)
	}

	// Create logger
	logger := logging.Default()

	// Load configuration
	cfg := config.Load()

	// Connect to database
	ctx := context.Background()
	pool := database.MustConnect(ctx, cfg.Database.URL, database.Options{
		MaxOpenConns:    cfg.Database.MaxOpenConns,
		MaxIdleConns:    cfg.Database.MaxIdleConns,
		ConnMaxLifetime: cfg.Database.ConnMaxLifetime,
	})
	logger.Info("connected to database", "url", pool.URL)

	// Run migrations
	database.MustRunMigrations(ctx, pool, migrations.FS, migrations.Dir)
	logger.Info("database migrations complete")

	// Create adapters (repositories)
	prefRepo := postgres.NewPreferenceRepository(pool.DB)

	// Create services (business logic)
	preferenceService := service.NewPreferenceService(prefRepo, logger)

	// Create application
	application := app.New("preferences-api", app.WithDefaultPort(8001))

	// Register shutdown hook for database pool
	application.OnShutdown(func(ctx context.Context) error {
		logger.Info("closing database connection pool")
		return pool.Close()
	})

	// Register routes with dependency injection
	api.RegisterRoutes(application, preferenceService)

	// Start server
	application.Run()
}
