package main

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

	"github.com/jackc/pgx/v5/pgxpool"

	"archivmail/config"
	"archivmail/internal/userstore"
)

// runMigrateTenants performs a one-time migration to set up the default tenant,
// assign all existing users/emails/audit entries to it, and create a superadmin user.
//
// Usage: archivmail migrate-tenants [-config /etc/archivmail/config.yml]
func runMigrateTenants(args []string) {
	fs := flag.NewFlagSet("migrate-tenants", flag.ExitOnError)
	configPath := fs.String("config", "/etc/archivmail/config.yml", "path to config file")
	fs.Parse(args) //nolint

	cfg, err := config.Load(*configPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: load config: %v\n", err)
		os.Exit(1)
	}

	ctx := context.Background()
	pool, err := pgxpool.New(ctx, cfg.Database.DSN())
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: db connect: %v\n", err)
		os.Exit(1)
	}
	defer pool.Close()

	// Check if migration has already run
	var tenantCount int
	_ = pool.QueryRow(ctx, `SELECT COUNT(*) FROM tenants`).Scan(&tenantCount)
	if tenantCount > 0 {
		fmt.Println("migrate-tenants: tenants table already populated — skipping migration")
		os.Exit(0)
	}

	// 1. Create default tenant
	var defaultTenantID int64
	err = pool.QueryRow(ctx,
		`INSERT INTO tenants (name, slug, active) VALUES ('default', 'default', true) RETURNING id`,
	).Scan(&defaultTenantID)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: create default tenant: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("migrate-tenants: created default tenant with id=%d\n", defaultTenantID)

	// 2. Assign all users without tenant to the default tenant
	tag, err := pool.Exec(ctx,
		`UPDATE users SET tenant_id = $1 WHERE tenant_id IS NULL`, defaultTenantID)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: update users: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("migrate-tenants: assigned %d users to default tenant\n", tag.RowsAffected())

	// 3. Assign all emails without tenant to the default tenant
	tag, err = pool.Exec(ctx,
		`UPDATE emails SET tenant_id = $1 WHERE tenant_id IS NULL`, defaultTenantID)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: update emails: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("migrate-tenants: assigned %d emails to default tenant\n", tag.RowsAffected())

	// 4. Seed email_refs for existing emails (all assigned to default tenant)
	_, err = pool.Exec(ctx, `
		INSERT INTO email_refs (email_id, tenant_id)
		SELECT id, $1 FROM emails WHERE tenant_id = $1
		ON CONFLICT (email_id, tenant_id) DO NOTHING
	`, defaultTenantID)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: seed email_refs: %v\n", err)
		os.Exit(1)
	}

	// 5. Assign audit_log entries to default tenant (best-effort — column may not exist yet)
	_, _ = pool.Exec(ctx,
		`UPDATE audit_log SET tenant_id = $1 WHERE tenant_id IS NULL`, defaultTenantID)

	// 6. Promote existing 'admin' users to 'domain_admin'
	tag, err = pool.Exec(ctx,
		`UPDATE users SET role = $1 WHERE role = 'admin'`, userstore.RoleDomainAdmin)
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: promote admins: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("migrate-tenants: promoted %d admin(s) to domain_admin\n", tag.RowsAffected())

	// 7. Create superadmin user (tenant_id = NULL = global access)
	superPw, err := randomPassword()
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: generate password: %v\n", err)
		os.Exit(1)
	}

	// Use userstore so the password is properly bcrypt-hashed
	users, err := userstore.New(cfg.Database.DSN())
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: userstore init: %v\n", err)
		os.Exit(1)
	}
	defer users.Close()

	_, err = users.Create(userstore.CreateUserRequest{
		Username: "superadmin",
		Email:    "superadmin@archivmail.local",
		Password: superPw,
		Role:     userstore.RoleSuperAdmin,
		TenantID: nil, // global — no tenant restriction
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "migrate-tenants: create superadmin: %v\n", err)
		os.Exit(1)
	}

	fmt.Println()
	fmt.Println("╔══════════════════════════════════════════════════════════════════╗")
	fmt.Println("║         ARCHIVMAIL — TENANT MIGRATION ABGESCHLOSSEN             ║")
	fmt.Println("║  Superadmin-Zugangsdaten (NUR EINMAL ANGEZEIGT):                ║")
	fmt.Printf( "║  superadmin : %-52s ║\n", superPw)
	fmt.Println("║  Passwort sofort nach dem ersten Login ändern!                  ║")
	fmt.Println("╚══════════════════════════════════════════════════════════════════╝")
	fmt.Println()
	fmt.Printf("migrate-tenants: done — default tenant id=%d\n", defaultTenantID)
}
