package main

import (
	"context"
	"flag"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/rs/zerolog"

	"github.com/vincentc-afk/gitea-notification-hub/internal/config"
	"github.com/vincentc-afk/gitea-notification-hub/internal/event"
	"github.com/vincentc-afk/gitea-notification-hub/internal/identity"
	"github.com/vincentc-afk/gitea-notification-hub/internal/identity/cache"
	"github.com/vincentc-afk/gitea-notification-hub/internal/identity/gitea"
	slacknotifier "github.com/vincentc-afk/gitea-notification-hub/internal/notifier/slack"
	"github.com/vincentc-afk/gitea-notification-hub/internal/server"
	"github.com/vincentc-afk/gitea-notification-hub/internal/storage/sqlite"
	"github.com/vincentc-afk/gitea-notification-hub/internal/webhook"
)

func main() {
	// Parse flags
	configPath := flag.String("config", "config/config.yaml", "path to config file")
	debug := flag.Bool("debug", false, "enable debug logging")
	flag.Parse()

	// Setup logger
	logger := setupLogger(*debug)

	// Load configuration
	cfg, err := config.Load(*configPath)
	if err != nil {
		logger.Fatal().Err(err).Msg("failed to load configuration")
	}
	logger.Info().Str("path", *configPath).Msg("configuration loaded")

	ctx := context.Background()

	// Initialize storage
	repo, err := sqlite.New(cfg.Database.DSN)
	if err != nil {
		logger.Fatal().Err(err).Msg("failed to initialize database")
	}
	defer repo.Close()

	// Run migrations
	if err := repo.Migrate(ctx); err != nil {
		logger.Fatal().Err(err).Msg("failed to run migrations")
	}
	logger.Info().Msg("database initialized")

	// Initialize Gitea API provider for email lookup
	var emailLookup identity.EmailLookup
	if cfg.Identity.Gitea.URL != "" {
		giteaProvider := gitea.New(&cfg.Identity.Gitea, logger)
		emailLookup = giteaProvider
		logger.Info().Str("url", cfg.Identity.Gitea.URL).Msg("Gitea identity provider initialized")
	} else {
		logger.Warn().Msg("Gitea URL not configured, email lookup disabled")
	}

	// Initialize Slack notifier
	slackClient := slacknotifier.New(&cfg.Notification.Slack, logger)
	logger.Info().Msg("Slack notifier initialized")

	// Initialize cached identity resolver with optional manual mappings
	manualMappings := cache.ParseManualMappings(os.Getenv("MANUAL_USER_MAPPINGS"))
	if len(manualMappings) > 0 {
		logger.Info().Int("count", len(manualMappings)).Msg("manual user mappings configured")
		for username := range manualMappings {
			logger.Debug().Str("username", username).Msg("manual mapping registered")
		}
	}
	resolver := cache.NewCachedResolver(repo, emailLookup, slackClient, manualMappings, logger)
	logger.Info().Msg("identity resolver initialized")

	// Create processor adapter that implements webhook.EventHandler
	processor := event.NewProcessor(cfg, &resolverAdapter{resolver}, slackClient, logger)
	logger.Info().Msg("event processor initialized")

	// Create HTTP server
	srv := server.New(cfg, logger)

	// Register webhook handler
	webhookHandler := webhook.NewHandler(cfg.Server.WebhookSecret, processor, logger)
	srv.Router().Post("/webhook", webhookHandler.ServeHTTP)
	logger.Info().Msg("webhook handler registered at POST /webhook")

	// Graceful shutdown
	go func() {
		sigCh := make(chan os.Signal, 1)
		signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
		<-sigCh

		logger.Info().Msg("received shutdown signal")

		shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
		defer cancel()

		if err := srv.Shutdown(shutdownCtx); err != nil {
			logger.Error().Err(err).Msg("shutdown error")
		}
	}()

	// Start server
	logger.Info().Int("port", cfg.Server.Port).Msg("starting server")
	if err := srv.Start(); err != nil && err != http.ErrServerClosed {
		logger.Fatal().Err(err).Msg("server error")
	}
}

func setupLogger(debug bool) zerolog.Logger {
	zerolog.TimeFieldFormat = time.RFC3339

	level := zerolog.InfoLevel
	if debug {
		level = zerolog.DebugLevel
	}

	// Allow LOG_LEVEL env var to override
	if logLevel := os.Getenv("LOG_LEVEL"); logLevel != "" {
		switch strings.ToLower(logLevel) {
		case "debug":
			level = zerolog.DebugLevel
		case "info":
			level = zerolog.InfoLevel
		case "warn":
			level = zerolog.WarnLevel
		case "error":
			level = zerolog.ErrorLevel
		}
	}

	return zerolog.New(zerolog.ConsoleWriter{
		Out:        os.Stdout,
		TimeFormat: "15:04:05",
	}).Level(level).With().Timestamp().Caller().Logger()
}

// resolverAdapter adapts cache.CachedResolver to event.IdentityResolver
type resolverAdapter struct {
	resolver *cache.CachedResolver
}

func (a *resolverAdapter) Resolve(ctx context.Context, user event.User) (*event.ResolvedIdentity, error) {
	identity, err := a.resolver.Resolve(ctx, user)
	if err != nil {
		return nil, err
	}
	return &event.ResolvedIdentity{
		Email:     identity.Email,
		SlackID:   identity.SlackID,
		SlackName: identity.SlackName,
	}, nil
}
