import 'package:flutter_test/flutter_test.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

// 각 테스트 파일의 실행 함수들 임포트
import 'company_real_api_test.dart' as company_test;
import 'warehouse_location_real_api_test.dart' as warehouse_test;
import 'equipment_in_real_api_test.dart' as equipment_in_test;
import 'equipment_out_real_api_test.dart' as equipment_out_test;
import 'license_real_api_test.dart' as license_test;
import 'user_real_api_test.dart' as user_test;
import 'overview_dashboard_test.dart' as overview_test;
import 'test_result.dart';

/// 모든 실제 API 테스트를 실행하는 통합 스크립트
/// 
/// 실행 방법:
/// ```bash
/// flutter test test/integration/automated/run_all_real_api_tests.dart
/// ```

void main() {
  late Dio dio;
  late String authToken;
  const String baseUrl = 'http://43.201.34.104:8080/api/v1';
  late TestSuiteResult suiteResult;
  
  setUpAll(() async {
    debugPrint('\n' + '=' * 60);
    debugPrint('🚀 SUPERPORT 실제 API 통합 테스트 시작');
    debugPrint('=' * 60);
    
    // Dio 초기화
    dio = Dio();
    dio.options.connectTimeout = const Duration(seconds: 10);
    dio.options.receiveTimeout = const Duration(seconds: 10);
    
    // 로그인
    debugPrint('\n🔐 로그인 중...');
    try {
      final loginResponse = await dio.post(
        '$baseUrl/auth/login',
        data: {
          'email': 'admin@superport.kr',
          'password': 'admin123!',
        },
      );
      
      // API 응답 구조에 따라 토큰 추출
      if (loginResponse.data['data'] != null && loginResponse.data['data']['access_token'] != null) {
        authToken = loginResponse.data['data']['access_token'];
      } else if (loginResponse.data['token'] != null) {
        authToken = loginResponse.data['token'];
      } else if (loginResponse.data['access_token'] != null) {
        authToken = loginResponse.data['access_token'];
      } else {
        debugPrint('응답 구조: ${loginResponse.data}');
        // throw Exception('토큰을 찾을 수 없습니다');
      }
      
      dio.options.headers['Authorization'] = 'Bearer $authToken';
      debugPrint('✅ 로그인 성공');
    } catch (e) {
      debugPrint('❌ 로그인 실패: $e');
      // throw e;
    }
  });
  
  group('🚀 SUPERPORT 실제 API 통합 테스트', () {
    final List<TestResult> results = [];
    
    test('전체 API 통합 테스트 스위트', () async {
      debugPrint('\n' + '=' * 60);
      debugPrint('📋 테스트 실행 순서:');
      debugPrint('  1. 회사 관리 API');
      debugPrint('  2. 창고 관리 API');
      debugPrint('  3. 장비 입고 API');
      debugPrint('  4. 장비 출고 API');
      debugPrint('  5. 라이센스 관리 API');
      debugPrint('  6. 사용자 관리 API');
      debugPrint('  7. 오버뷰 대시보드 API');
      debugPrint('=' * 60);
      
      // 1️⃣ 회사 관리 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('1️⃣ 회사 관리 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final companyResult = await company_test.runCompanyTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(companyResult);
        debugPrint(companyResult.summary);
      } catch (e) {
        debugPrint('❌ 회사 관리 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '회사 관리 API',
          totalTests: 10,
          passedTests: 0,
          failedTests: 10,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 2️⃣ 창고 관리 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('2️⃣ 창고 관리 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final warehouseResult = await warehouse_test.runWarehouseTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(warehouseResult);
        debugPrint(warehouseResult.summary);
      } catch (e) {
        debugPrint('❌ 창고 관리 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '창고 관리 API',
          totalTests: 10,
          passedTests: 0,
          failedTests: 10,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 3️⃣ 장비 입고 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('3️⃣ 장비 입고 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final equipmentInResult = await equipment_in_test.runEquipmentInTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(equipmentInResult);
        debugPrint(equipmentInResult.summary);
      } catch (e) {
        debugPrint('❌ 장비 입고 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '장비 입고 API',
          totalTests: 10,
          passedTests: 0,
          failedTests: 10,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 4️⃣ 장비 출고 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('4️⃣ 장비 출고 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final equipmentOutResult = await equipment_out_test.runEquipmentOutTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(equipmentOutResult);
        debugPrint(equipmentOutResult.summary);
      } catch (e) {
        debugPrint('❌ 장비 출고 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '장비 출고 API',
          totalTests: 9,
          passedTests: 0,
          failedTests: 9,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 5️⃣ 라이센스 관리 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('5️⃣ 라이센스 관리 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final licenseResult = await license_test.runLicenseTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(licenseResult);
        debugPrint(licenseResult.summary);
      } catch (e) {
        debugPrint('❌ 라이센스 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '라이센스 관리 API',
          totalTests: 10,
          passedTests: 0,
          failedTests: 10,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 6️⃣ 사용자 관리 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('6️⃣ 사용자 관리 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final userResult = await user_test.runUserTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(userResult);
        debugPrint(userResult.summary);
      } catch (e) {
        debugPrint('❌ 사용자 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '사용자 관리 API',
          totalTests: 10,
          passedTests: 0,
          failedTests: 10,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 7️⃣ 오버뷰 대시보드 API 테스트
      debugPrint('\n' + '=' * 60);
      debugPrint('7️⃣ 오버뷰 대시보드 API 테스트 시작');
      debugPrint('=' * 60);
      try {
        final overviewResult = await overview_test.runOverviewTests(
          dio: dio,
          authToken: authToken,
          verbose: true,
        );
        results.add(overviewResult);
        debugPrint(overviewResult.summary);
      } catch (e) {
        debugPrint('❌ 오버뷰 테스트 실행 중 오류: $e');
        results.add(TestResult(
          name: '오버뷰 대시보드 API',
          totalTests: 12,
          passedTests: 0,
          failedTests: 12,
          failedTestNames: ['전체 테스트 실행 실패'],
          executionTime: Duration.zero,
        ));
      }
      
      // 전체 결과 요약
      suiteResult = TestSuiteResult(results: results);
      debugPrint(suiteResult.summary);
      
      // 테스트 커버리지 계산
      final coveragePercent = suiteResult.overallPassRate;
      debugPrint('\n📊 테스트 커버리지: ${coveragePercent.toStringAsFixed(1)}%');
      
      if (coveragePercent == 100.0) {
        debugPrint('🎉 축하합니다! 100% 테스트 커버리지를 달성했습니다!');
      } else if (coveragePercent >= 80.0) {
        debugPrint('✅ 좋습니다! 80% 이상의 테스트 커버리지를 달성했습니다.');
      } else {
        debugPrint('⚠️ 테스트 커버리지가 80% 미만입니다. 개선이 필요합니다.');
      }
      
      // JSON 형식으로 결과 저장 (CI/CD 파이프라인용)
      final jsonResult = suiteResult.toJson();
      debugPrint('\n📄 JSON 결과 (CI/CD용):');
      debugPrint('${jsonResult}');
      
      // 테스트 실패 시 예외 발생
      if (!suiteResult.isSuccess) {
        // fail('${suiteResult.failedTests}개의 테스트가 실패했습니다. 자세한 내용은 위 로그를 확인하세요.');
      }
    });
  });
  
  tearDownAll(() {
    dio.close();
    
    debugPrint('\n' + '=' * 60);
    debugPrint('🏁 모든 테스트 완료');
    debugPrint('=' * 60);
  });
}