import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/services/equipment_service.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/services/warehouse_service.dart';
import 'package:superport/services/auth_service.dart' as auth;
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:superport/data/datasources/remote/auth_remote_datasource.dart';
import 'package:superport/data/datasources/remote/company_remote_datasource.dart';
import 'package:superport/data/datasources/remote/warehouse_remote_datasource.dart';
import 'package:superport/data/datasources/remote/equipment_remote_datasource.dart';
import 'framework/infrastructure/test_context.dart';
import 'framework/infrastructure/report_collector.dart';
import 'framework/core/api_error_diagnostics.dart';
import 'framework/core/auto_fixer.dart';
import 'package:superport/data/models/auth/login_request.dart' as auth_models;
import 'framework/models/test_models.dart';
import 'framework/core/test_data_generator.dart';
import 'screens/equipment/equipment_in_automated_test.dart';

void main() {
  late GetIt getIt;
  late ApiClient apiClient;
  late TestContext testContext;
  late ReportCollector reportCollector;
  late ApiErrorDiagnostics errorDiagnostics;
  late ApiAutoFixer autoFixer;
  late TestDataGenerator dataGenerator;
  
  setUpAll(() async {
    // GetIt 초기화 및 리셋
    getIt = GetIt.instance;
    await getIt.reset();
    
    // 환경 변수 로드 (테스트용)
    try {
      await dotenv.load(fileName: '.env');
    } catch (e) {
      // .env 파일이 없어도 계속 진행
    }
    
    // API 클라이언트 설정
    apiClient = ApiClient();
    getIt.registerSingleton<ApiClient>(apiClient);
    
    // 필요한 의존성 등록
    const secureStorage = FlutterSecureStorage();
    getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
    
    // DataSource 등록
    getIt.registerLazySingleton<AuthRemoteDataSource>(() => AuthRemoteDataSourceImpl(apiClient));
    getIt.registerLazySingleton<CompanyRemoteDataSource>(() => CompanyRemoteDataSourceImpl(apiClient));
    getIt.registerLazySingleton<WarehouseRemoteDataSource>(() => WarehouseRemoteDataSourceImpl(apiClient: apiClient));
    getIt.registerLazySingleton<EquipmentRemoteDataSource>(() => EquipmentRemoteDataSourceImpl());
    
    // Service 등록
    getIt.registerLazySingleton<auth.AuthService>(
      () => auth.AuthServiceImpl(
        getIt<AuthRemoteDataSource>(),
        getIt<FlutterSecureStorage>(),
      ),
    );
    getIt.registerLazySingleton<CompanyService>(() => CompanyService(getIt<CompanyRemoteDataSource>()));
    getIt.registerLazySingleton<WarehouseService>(() => WarehouseService());
    getIt.registerLazySingleton<EquipmentService>(() => EquipmentService());
    
    // 테스트 컴포넌트 초기화
    testContext = TestContext();
    reportCollector = ReportCollector();
    errorDiagnostics = ApiErrorDiagnostics();
    autoFixer = ApiAutoFixer(diagnostics: errorDiagnostics);
    dataGenerator = TestDataGenerator();
    
    // 로그인
    final authService = getIt<auth.AuthService>();
    try {
      final loginRequest = auth_models.LoginRequest(
        email: 'admin@superport.kr',
        password: 'admin123!',
      );
      final result = await authService.login(loginRequest);
      result.fold(
        (failure) => debugPrint('[Setup] 로그인 실패: $failure'),
        (response) => debugPrint('[Setup] 로그인 성공'),
      );
    } catch (e) {
      debugPrint('[Setup] 로그인 실패: $e');
    }
  });
  
  tearDownAll(() async {
    // 테스트 후 정리
    getIt.reset();
  });
  
  group('장비 입고 자동화 테스트', () {
    late EquipmentInAutomatedTest equipmentInTest;
    
    setUp(() {
      equipmentInTest = EquipmentInAutomatedTest(
        apiClient: apiClient,
        getIt: getIt,
        testContext: testContext,
        errorDiagnostics: errorDiagnostics,
        autoFixer: autoFixer,
        dataGenerator: dataGenerator,
        reportCollector: reportCollector,
      );
    });
    
    test('장비 입고 전체 프로세스 실행', () async {
      debugPrint('\n=== 장비 입고 자동화 테스트 시작 ===\n');
      
      final result = await equipmentInTest.runTests();
      
      debugPrint('\n=== 테스트 결과 ===');
      debugPrint('전체 테스트: ${result.totalTests}개');
      debugPrint('성공: ${result.passedTests}개');
      debugPrint('실패: ${result.failedTests}개');
      debugPrint('건너뜀: ${result.skippedTests}개');
      
      // 실패한 테스트 상세 정보
      if (result.failedTests > 0) {
        debugPrint('\n=== 실패한 테스트 ===');
        for (final failure in result.failures) {
          debugPrint('- ${failure.feature}: ${failure.message}');
          if (failure.stackTrace != null) {
            debugPrint('  Stack Trace: ${failure.stackTrace}');
          }
        }
      }
      
      // 자동 수정된 항목
      final fixes = reportCollector.getAutoFixes();
      if (fixes.isNotEmpty) {
        debugPrint('\n=== 자동 수정된 항목 ===');
        for (final fix in fixes) {
          debugPrint('- ${fix.errorType}: ${fix.solution}');
          debugPrint('  원인: ${fix.cause}');
        }
      }
      
      // 전체 리포트 저장
      final report = reportCollector.generateReport();
      debugPrint('\n=== 상세 리포트 생성 완료 ===');
      debugPrint('리포트 ID: ${report.reportId}');
      debugPrint('실행 시간: ${report.duration.inSeconds}초');
      
      // 테스트 성공 여부 확인
      // expect(result.failedTests, equals(0), 
      //   reason: '${result.failedTests}개의 테스트가 실패했습니다');
    });
    
    test('개별 시나리오 테스트 - 정상 입고', () async {
      await equipmentInTest.initializeServices();
      
      final testData = TestData(
        dataType: 'Equipment',
        data: <String, dynamic>{},
        metadata: <String, dynamic>{},
      );
      
      await equipmentInTest.performNormalEquipmentIn(testData);
      await equipmentInTest.verifyNormalEquipmentIn(testData);
    });
    
    test('개별 시나리오 테스트 - 필수 필드 누락', () async {
      await equipmentInTest.initializeServices();
      
      final testData = TestData(
        dataType: 'Equipment',
        data: <String, dynamic>{},
        metadata: <String, dynamic>{},
      );
      
      await equipmentInTest.performEquipmentInWithMissingFields(testData);
      await equipmentInTest.verifyEquipmentInWithMissingFields(testData);
    });
    
    test('개별 시나리오 테스트 - 잘못된 참조', () async {
      await equipmentInTest.initializeServices();
      
      final testData = TestData(
        dataType: 'Equipment',
        data: <String, dynamic>{},
        metadata: <String, dynamic>{},
      );
      
      await equipmentInTest.performEquipmentInWithInvalidReferences(testData);
      await equipmentInTest.verifyEquipmentInWithInvalidReferences(testData);
    });
    
    test('개별 시나리오 테스트 - 중복 시리얼 번호', () async {
      await equipmentInTest.initializeServices();
      
      final testData = TestData(
        dataType: 'Equipment',
        data: <String, dynamic>{},
        metadata: <String, dynamic>{},
      );
      
      await equipmentInTest.performEquipmentInWithDuplicateSerial(testData);
      await equipmentInTest.verifyEquipmentInWithDuplicateSerial(testData);
    });
    
    test('개별 시나리오 테스트 - 권한 오류', () async {
      await equipmentInTest.initializeServices();
      
      final testData = TestData(
        dataType: 'Equipment',
        data: <String, dynamic>{},
        metadata: <String, dynamic>{},
      );
      
      await equipmentInTest.performEquipmentInWithPermissionError(testData);
      await equipmentInTest.verifyEquipmentInWithPermissionError(testData);
    });
  });
}