/**
 * Integration Test: Onboarding Wizard Use Case Orchestration
 * 
 * Tests the orchestration logic of onboarding wizard-related Use Cases:
 * - CompleteDriverOnboardingUseCase: Orchestrates the driver creation flow
 * 
 * Validates that Use Cases correctly interact with their Ports (Repositories)
 * Uses In-Memory adapters for fast, deterministic testing
 * 
 * Focus: Business logic orchestration, NOT UI rendering
 */

import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
import { InMemoryDriverRepository } from '../../../adapters/racing/persistence/inmemory/InMemoryDriverRepository';
import { CompleteDriverOnboardingUseCase } from '../../../core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
import { Logger } from '../../../core/shared/domain/Logger';

describe('Onboarding Wizard Use Case Orchestration', () => {
  let driverRepository: InMemoryDriverRepository;
  let completeDriverOnboardingUseCase: CompleteDriverOnboardingUseCase;
  let mockLogger: Logger;

  beforeAll(() => {
    mockLogger = {
      info: () => {},
      debug: () => {},
      warn: () => {},
      error: () => {},
    } as unknown as Logger;

    driverRepository = new InMemoryDriverRepository(mockLogger);
    completeDriverOnboardingUseCase = new CompleteDriverOnboardingUseCase(
      driverRepository,
      mockLogger
    );
  });

  beforeEach(async () => {
    await driverRepository.clear();
  });

  describe('CompleteDriverOnboardingUseCase - Success Path', () => {
    it('should complete onboarding with valid personal info', async () => {
      // Scenario: Complete onboarding successfully
      // Given: A new user ID
      const userId = 'user-123';
      const input = {
        userId,
        firstName: 'John',
        lastName: 'Doe',
        displayName: 'RacerJohn',
        country: 'US',
        bio: 'New racer on the grid',
      };

      // When: CompleteDriverOnboardingUseCase.execute() is called
      const result = await completeDriverOnboardingUseCase.execute(input);

      // Then: Driver should be created
      expect(result.isOk()).toBe(true);
      const { driver } = result.unwrap();
      expect(driver.id).toBe(userId);
      expect(driver.name.toString()).toBe('RacerJohn');
      expect(driver.country.toString()).toBe('US');
      expect(driver.bio?.toString()).toBe('New racer on the grid');

      // And: Repository should contain the driver
      const savedDriver = await driverRepository.findById(userId);
      expect(savedDriver).not.toBeNull();
      expect(savedDriver?.id).toBe(userId);
    });

    it('should complete onboarding with minimal required data', async () => {
      // Scenario: Complete onboarding with minimal data
      // Given: A new user ID
      const userId = 'user-456';
      const input = {
        userId,
        firstName: 'Jane',
        lastName: 'Smith',
        displayName: 'JaneS',
        country: 'UK',
      };

      // When: CompleteDriverOnboardingUseCase.execute() is called
      const result = await completeDriverOnboardingUseCase.execute(input);

      // Then: Driver should be created successfully
      expect(result.isOk()).toBe(true);
      const { driver } = result.unwrap();
      expect(driver.id).toBe(userId);
      expect(driver.bio).toBeUndefined();
    });
  });

  describe('CompleteDriverOnboardingUseCase - Validation & Errors', () => {
    it('should reject onboarding if driver already exists', async () => {
      // Scenario: Already onboarded user
      // Given: A driver already exists for the user
      const userId = 'existing-user';
      const existingInput = {
        userId,
        firstName: 'Old',
        lastName: 'Name',
        displayName: 'OldRacer',
        country: 'DE',
      };
      await completeDriverOnboardingUseCase.execute(existingInput);

      // When: CompleteDriverOnboardingUseCase.execute() is called again for same user
      const result = await completeDriverOnboardingUseCase.execute({
        userId,
        firstName: 'New',
        lastName: 'Name',
        displayName: 'NewRacer',
        country: 'FR',
      });

      // Then: Should return DRIVER_ALREADY_EXISTS error
      expect(result.isErr()).toBe(true);
      const error = result.unwrapErr();
      expect(error.code).toBe('DRIVER_ALREADY_EXISTS');
    });

    it('should handle repository errors gracefully', async () => {
      // Scenario: Repository error
      // Given: Repository throws an error
      const userId = 'error-user';
      const originalCreate = driverRepository.create.bind(driverRepository);
      driverRepository.create = async () => {
        throw new Error('Database failure');
      };

      // When: CompleteDriverOnboardingUseCase.execute() is called
      const result = await completeDriverOnboardingUseCase.execute({
        userId,
        firstName: 'John',
        lastName: 'Doe',
        displayName: 'RacerJohn',
        country: 'US',
      });

      // Then: Should return REPOSITORY_ERROR
      expect(result.isErr()).toBe(true);
      const error = result.unwrapErr();
      expect(error.code).toBe('REPOSITORY_ERROR');
      expect(error.details.message).toBe('Database failure');

      // Restore
      driverRepository.create = originalCreate;
    });
  });
});
