package service

import (
	"context"
	"testing"

	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/repository"
	gormsqlite "gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// =============================================================================
// Export Internal Functions Tests
// =============================================================================

func setupExportInternalTestEnv(t *testing.T) (*ExportService, *gorm.DB) {
	t.Helper()

	db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
		DriverName: "sqlite",
		DSN:        "file:export_internal_test?mode=memory&cache=shared",
	}), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		t.Fatalf("failed to connect database: %v", err)
	}

	if err := db.AutoMigrate(&domain.User{}); err != nil {
		t.Fatalf("failed to migrate: %v", err)
	}

	userRepo := repository.NewUserRepository(db)
	svc := NewExportService(userRepo, nil)

	return svc, db
}

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

	// Create test users with various fields
	email := "list@test.com"
	phone := "13900139000"
	users := []*domain.User{
		{Username: "listuser1", Password: "$2a$10$hash", Status: domain.UserStatusActive, Email: &email, Phone: &phone, Nickname: "List User 1"},
		{Username: "listuser2", Password: "$2a$10$hash", Status: domain.UserStatusInactive},
		{Username: "listuser3", Password: "$2a$10$hash", Status: domain.UserStatusLocked},
	}
	for _, u := range users {
		db.Create(u)
	}

	t.Run("List users for export with empty request", func(t *testing.T) {
		req := &ExportUsersRequest{}
		result, err := svc.listUsersForExport(ctx, req)
		if err != nil {
			t.Fatalf("listUsersForExport failed: %v", err)
		}
		if len(result) < 3 {
			t.Errorf("Expected at least 3 users, got %d", len(result))
		}
	})

	t.Run("List users with filter request", func(t *testing.T) {
		status := int(domain.UserStatusActive)
		req := &ExportUsersRequest{
			Status: &status,
		}
		result, err := svc.listUsersForExport(ctx, req)
		if err != nil {
			t.Fatalf("listUsersForExport failed: %v", err)
		}
		if len(result) < 1 {
			t.Error("Expected at least 1 active user")
		}
	})

	t.Run("List users with keyword", func(t *testing.T) {
		req := &ExportUsersRequest{
			Keyword: "listuser",
		}
		result, err := svc.listUsersForExport(ctx, req)
		if err != nil {
			t.Fatalf("listUsersForExport failed: %v", err)
		}
		if len(result) < 1 {
			t.Error("Expected at least 1 user matching keyword")
		}
	})
}

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

	t.Run("Import records with empty data", func(t *testing.T) {
		successCount, failCount, _ := svc.importUsersRecords(ctx, [][]string{})
		if successCount != 0 || failCount != 0 {
			t.Errorf("Expected (0, 0), got (%d, %d)", successCount, failCount)
		}
	})

	t.Run("Import records with only header", func(t *testing.T) {
		records := [][]string{{"用户名", "密码"}}
		successCount, failCount, _ := svc.importUsersRecords(ctx, records)
		if successCount != 0 {
			t.Errorf("Expected 0 success, got %d", successCount)
		}
		_ = failCount
	})

	t.Run("Import records with valid data", func(t *testing.T) {
		records := [][]string{
			{"用户名", "密码", "邮箱", "手机号"},
			{"importuser1", "Password123!", "import1@test.com", "13800138001"},
			{"importuser2", "Password123!", "import2@test.com", "13800138002"},
		}
		successCount, failCount, errs := svc.importUsersRecords(ctx, records)
		if successCount != 2 {
			t.Errorf("Expected 2 success, got %d, errors: %v", successCount, errs)
		}
		_ = failCount
	})

	t.Run("Import records with missing username", func(t *testing.T) {
		records := [][]string{
			{"用户名", "密码"},
			{"", "Password123!"},
		}
		successCount, failCount, errs := svc.importUsersRecords(ctx, records)
		if successCount != 0 {
			t.Errorf("Expected 0 success, got %d", successCount)
		}
		if failCount == 0 {
			t.Error("Expected at least one failure")
		}
		if len(errs) == 0 {
			t.Error("Expected error message")
		}
	})

	t.Run("Import records with missing password", func(t *testing.T) {
		records := [][]string{
			{"用户名", "密码"},
			{"nopwduser", ""},
		}
		successCount, failCount, errs := svc.importUsersRecords(ctx, records)
		if successCount != 0 {
			t.Errorf("Expected 0 success, got %d", successCount)
		}
		if failCount == 0 {
			t.Error("Expected at least one failure")
		}
		_ = errs
	})

	t.Run("Import records with duplicate username", func(t *testing.T) {
		// Create existing user
		db.Create(&domain.User{Username: "duplicateuser", Password: "$2a$10$hash", Status: domain.UserStatusActive})

		records := [][]string{
			{"用户名", "密码"},
			{"duplicateuser", "Password123!"},
		}
		successCount, failCount, _ := svc.importUsersRecords(ctx, records)
		if successCount != 0 {
			t.Errorf("Expected 0 success for duplicate, got %d", successCount)
		}
		if failCount == 0 {
			t.Error("Expected failure for duplicate username")
		}
	})
}

func TestParseXLSXRecords(t *testing.T) {
	t.Run("Parse invalid XLSX data", func(t *testing.T) {
		_, err := parseXLSXRecords([]byte("not a valid xlsx"))
		if err == nil {
			t.Error("Expected error for invalid XLSX data")
		}
	})
}
