package service_test

import (
	"context"
	"testing"

	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/service"
)

// =============================================================================
// Auth Admin Bootstrap Tests - Phase 1
// =============================================================================

func TestAuthService_BootstrapAdmin(t *testing.T) {
	svc, db := setupCapabilitiesTestEnv(t)
	ctx := context.Background()

	t.Run("Bootstrap admin success", func(t *testing.T) {
		// 确保没有现有管理员
		// Clean up any existing users
		db.Exec("DELETE FROM user_roles")
		db.Exec("DELETE FROM users")

		req := &service.BootstrapAdminRequest{
			Username: "admin",
			Password: "Admin123!",
			Email:    "admin@test.com",
			Nickname: "Administrator",
		}

		resp, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err != nil {
			t.Fatalf("BootstrapAdmin failed: %v", err)
		}
		if resp.AccessToken == "" {
			t.Error("Expected access token")
		}
		if resp.RefreshToken == "" {
			t.Error("Expected refresh token")
		}
		if resp.User.Username != "admin" {
			t.Errorf("Expected username 'admin', got %s", resp.User.Username)
		}
	})

	t.Run("Bootstrap admin when already exists", func(t *testing.T) {
		req := &service.BootstrapAdminRequest{
			Username: "admin2",
			Password: "Admin123!",
		}

		// First bootstrap should succeed (if previous test cleaned up)
		// But if admin exists, this should fail
		_, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err != nil {
			t.Logf("BootstrapAdmin returned error (expected if admin exists): %v", err)
		}
	})

	t.Run("Bootstrap admin with nil request", func(t *testing.T) {
		_, err := svc.BootstrapAdmin(ctx, nil, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for nil request")
		}
	})

	t.Run("Bootstrap admin with empty username", func(t *testing.T) {
		req := &service.BootstrapAdminRequest{
			Username: "",
			Password: "Admin123!",
		}
		_, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for empty username")
		}
	})

	t.Run("Bootstrap admin with empty password", func(t *testing.T) {
		req := &service.BootstrapAdminRequest{
			Username: "newadmin",
			Password: "",
		}
		_, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for empty password")
		}
	})

	t.Run("Bootstrap admin with weak password", func(t *testing.T) {
		req := &service.BootstrapAdminRequest{
			Username: "newadmin",
			Password: "123",
		}
		_, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for weak password")
		}
	})

	t.Run("Bootstrap admin with duplicate username", func(t *testing.T) {
		// First ensure an admin exists
		db.Exec("DELETE FROM user_roles WHERE user_id IN (SELECT id FROM users WHERE username = ?)", "duptest")
		db.Exec("DELETE FROM users WHERE username = ?", "duptest")

		req := &service.BootstrapAdminRequest{
			Username: "duptest",
			Password: "Admin123!",
		}
		// Create first admin
		svc.BootstrapAdmin(ctx, req, "127.0.0.1")

		// Try to create again
		_, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for duplicate username")
		}
	})

	t.Run("Bootstrap admin with duplicate email", func(t *testing.T) {
		// Clean up
		db.Exec("DELETE FROM user_roles WHERE user_id IN (SELECT id FROM users WHERE username LIKE 'emaildup%')")
		db.Exec("DELETE FROM users WHERE username LIKE 'emaildup%'")

		// Create first admin with email
		req1 := &service.BootstrapAdminRequest{
			Username: "emaildup1",
			Password: "Admin123!",
			Email:    "duplicate@test.com",
		}
		svc.BootstrapAdmin(ctx, req1, "127.0.0.1")

		// Try to create with same email
		req2 := &service.BootstrapAdminRequest{
			Username: "emaildup2",
			Password: "Admin123!",
			Email:    "duplicate@test.com",
		}
		_, err := svc.BootstrapAdmin(ctx, req2, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for duplicate email")
		}
	})

	t.Run("Bootstrap admin with nil service", func(t *testing.T) {
		var nilSvc *service.AuthService
		req := &service.BootstrapAdminRequest{
			Username: "admin",
			Password: "Admin123!",
		}
		_, err := nilSvc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err == nil {
			t.Error("nil service should return error")
		}
	})
}

// Test admin role assignment
func TestAuthService_AdminRoleAssignment(t *testing.T) {
	svc, db := setupCapabilitiesTestEnv(t)
	ctx := context.Background()

	t.Run("Admin gets admin role", func(t *testing.T) {
		// Clean up
		db.Exec("DELETE FROM user_roles")
		db.Exec("DELETE FROM users")

		req := &service.BootstrapAdminRequest{
			Username: "roletest",
			Password: "Admin123!",
			Email:    "role@test.com",
		}

		resp, err := svc.BootstrapAdmin(ctx, req, "127.0.0.1")
		if err != nil {
			t.Fatalf("BootstrapAdmin failed: %v", err)
		}

		// Check user has admin role through database
		var count int64
		db.Model(&domain.UserRole{}).Where("user_id = ?", resp.User.ID).Count(&count)
		if count == 0 {
			t.Error("Admin user should have roles assigned")
		}
	})
}

// =============================================================================
// BootstrapAdmin Extended Tests
// =============================================================================

func TestAuthService_BootstrapAdmin_Extended(t *testing.T) {
	t.Run("nil service returns error", func(t *testing.T) {
		var nilSvc *service.AuthService
		req := &service.BootstrapAdminRequest{
			Username: "admin",
			Password: "Admin123!",
		}
		_, err := nilSvc.BootstrapAdmin(context.Background(), req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error for nil service")
		}
	})

	t.Run("service without user repo returns error", func(t *testing.T) {
		svc := &service.AuthService{}
		req := &service.BootstrapAdminRequest{
			Username: "admin",
			Password: "Admin123!",
		}
		_, err := svc.BootstrapAdmin(context.Background(), req, "127.0.0.1")
		if err == nil {
			t.Error("Expected error when user repo not configured")
		}
	})
}
