package migrate

import (
	"fmt"

	"github.com/spf13/cobra"
	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/storage/database"
)

// MigrateCmd returns the migrate command with subcommands
func MigrateCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "migrate",
		Short: "Database migration commands",
	}

	cmd.AddCommand(upCmd())
	cmd.AddCommand(downCmd())
	cmd.AddCommand(versionCmd())
	cmd.AddCommand(forceCmd())

	return cmd
}

// upCmd runs pending migrations
func upCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "up",
		Short: "Run all pending migrations",
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.Load()
			if err != nil {
				return fmt.Errorf("failed to load config: %w", err)
			}

			// Create simple logger for CLI
			logger := zap.NewNop() // Silent logger for migrate commands
			migrator := database.NewMigrator(cfg, logger)
			if err := migrator.Up(); err != nil {
				return fmt.Errorf("failed to run migrations: %w", err)
			}

			return nil
		},
	}
}

// downCmd rolls back the last migration
func downCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "down",
		Short: "Rollback the last migration",
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.Load()
			if err != nil {
				return fmt.Errorf("failed to load config: %w", err)
			}

			// Create console logger for CLI output
			logger, _ := zap.NewDevelopment()
			defer logger.Sync()

			migrator := database.NewMigrator(cfg, logger)
			if err := migrator.Down(); err != nil {
				return fmt.Errorf("failed to rollback migration: %w", err)
			}

			logger.Info("Successfully rolled back last migration")
			return nil
		},
	}
}

// versionCmd shows the current migration version
func versionCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "version",
		Short: "Show current migration version",
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.Load()
			if err != nil {
				return fmt.Errorf("failed to load config: %w", err)
			}

			// Create console logger for CLI output
			logger, _ := zap.NewDevelopment()
			defer logger.Sync()

			migrator := database.NewMigrator(cfg, logger)
			version, dirty, err := migrator.Version()
			if err != nil {
				return fmt.Errorf("failed to get version: %w", err)
			}

			if dirty {
				logger.Warn("Current migration version is DIRTY - requires manual intervention",
					zap.Uint("version", uint(version)))
			} else {
				logger.Info("Current migration version",
					zap.Uint("version", uint(version)))
			}

			return nil
		},
	}
}

// forceCmd forces a specific migration version
func forceCmd() *cobra.Command {
	var version int

	cmd := &cobra.Command{
		Use:   "force",
		Short: "Force database to a specific migration version (use with caution)",
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.Load()
			if err != nil {
				return fmt.Errorf("failed to load config: %w", err)
			}

			logger := zap.NewNop()
			migrator := database.NewMigrator(cfg, logger)
			if err := migrator.ForceVersion(version); err != nil {
				return fmt.Errorf("failed to force version: %w", err)
			}

			return nil
		},
	}

	cmd.Flags().IntVarP(&version, "version", "v", 0, "Migration version to force")
	cmd.MarkFlagRequired("version")

	return cmd
}
