// ignore_for_file: avoid_print

import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:superport/services/license_service.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/services/user_service.dart';
import 'package:superport/models/license_model.dart';
import '../base/base_screen_test.dart';
import '../../framework/models/test_models.dart';
import '../../framework/models/error_models.dart';
import '../../framework/models/report_models.dart' as report_models;

/// 라이선스(License) 화면 자동화 테스트
/// 
/// 이 테스트는 라이선스 관리 전체 프로세스를 자동으로 실행하고,
/// 에러 발생 시 자동으로 진단하고 수정합니다.
class LicenseScreenTest extends BaseScreenTest {
  late LicenseService licenseService;
  late CompanyService companyService;
  late UserService userService;
  
  LicenseScreenTest({
    required super.apiClient,
    required super.getIt,
    required super.testContext,
    required super.errorDiagnostics,
    required super.autoFixer,
    required super.dataGenerator,
    required super.reportCollector,
  });
  
  @override
  ScreenMetadata getScreenMetadata() {
    return ScreenMetadata(
      screenName: 'LicenseScreen',
      controllerType: LicenseService,
      relatedEndpoints: [
        ApiEndpoint(
          path: '/api/v1/licenses',
          method: 'POST',
          description: '라이선스 생성',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses',
          method: 'GET',
          description: '라이선스 목록 조회',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/{id}',
          method: 'GET',
          description: '라이선스 상세 조회',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/{id}',
          method: 'PUT',
          description: '라이선스 수정',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/{id}',
          method: 'DELETE',
          description: '라이선스 삭제',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/{id}/assign',
          method: 'POST',
          description: '라이선스 할당',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/{id}/unassign',
          method: 'POST',
          description: '라이선스 할당 해제',
        ),
        ApiEndpoint(
          path: '/api/v1/licenses/expiring',
          method: 'GET',
          description: '만료 예정 라이선스 조회',
        ),
      ],
      screenCapabilities: {
        'license_management': {
          'crud': true,
          'expiry_management': true,
          'license_key_validation': true,
          'duplicate_check': true,
          'user_assignment': true,
          'search': true,
          'pagination': true,
          'status_filter': true,
          'type_filter': true,
        },
      },
    );
  }
  
  @override
  Future<void> initializeServices() async {
    licenseService = getIt<LicenseService>();
    companyService = getIt<CompanyService>();
    userService = getIt<UserService>();
  }
  
  @override
  dynamic getService() => licenseService;
  
  @override
  String getResourceType() => 'license';
  
  @override
  Map<String, dynamic> getDefaultFilters() {
    return {
      'isActive': true, // 기본적으로 활성 라이선스만 필터링
    };
  }
  
  @override
  Future<List<TestableFeature>> detectCustomFeatures(ScreenMetadata metadata) async {
    final features = <TestableFeature>[];
    
    // 라이선스 관리 기능 테스트
    features.add(TestableFeature(
      featureName: 'License Management',
      type: FeatureType.custom,
      testCases: [
        // 정상 라이선스 생성 시나리오
        TestCase(
          name: 'Normal license creation',
          execute: (data) async {
            await performNormalLicenseCreation(data);
          },
          verify: (data) async {
            await verifyNormalLicenseCreation(data);
          },
        ),
        // 만료일 관리 시나리오 - 만료 임박
        TestCase(
          name: 'Expiring license management',
          execute: (data) async {
            await performExpiringLicenseManagement(data);
          },
          verify: (data) async {
            await verifyExpiringLicenseManagement(data);
          },
        ),
        // 만료일 관리 시나리오 - 만료된 라이선스
        TestCase(
          name: 'Expired license management',
          execute: (data) async {
            await performExpiredLicenseManagement(data);
          },
          verify: (data) async {
            await verifyExpiredLicenseManagement(data);
          },
        ),
        // 라이선스 키 유효성 검증 시나리오
        TestCase(
          name: 'License key validation',
          execute: (data) async {
            await performLicenseKeyValidation(data);
          },
          verify: (data) async {
            await verifyLicenseKeyValidation(data);
          },
        ),
        // 중복 라이선스 키 처리 시나리오
        TestCase(
          name: 'Duplicate license key handling',
          execute: (data) async {
            await performDuplicateLicenseKeyHandling(data);
          },
          verify: (data) async {
            await verifyDuplicateLicenseKeyHandling(data);
          },
        ),
        // 필수 필드 누락 시나리오
        TestCase(
          name: 'Missing required fields',
          execute: (data) async {
            await performMissingRequiredFields(data);
          },
          verify: (data) async {
            await verifyMissingRequiredFields(data);
          },
        ),
        // 라이선스 타입별 테스트 - 영구 라이선스
        TestCase(
          name: 'Perpetual license type test',
          execute: (data) async {
            await performPerpetualLicenseTest(data);
          },
          verify: (data) async {
            await verifyPerpetualLicenseTest(data);
          },
        ),
        // 라이선스 타입별 테스트 - 기간제 라이선스
        TestCase(
          name: 'Term license type test',
          execute: (data) async {
            await performTermLicenseTest(data);
          },
          verify: (data) async {
            await verifyTermLicenseTest(data);
          },
        ),
        // 사용자 할당/해제 시나리오
        TestCase(
          name: 'User assignment and unassignment',
          execute: (data) async {
            await performUserAssignment(data);
          },
          verify: (data) async {
            await verifyUserAssignment(data);
          },
        ),
      ],
      metadata: {
        'description': '라이선스 관리 프로세스 자동화 테스트',
      },
    ));
    
    return features;
  }
  
  /// 정상 라이선스 생성 프로세스
  Future<void> performNormalLicenseCreation(TestData data) async {
    _log('=== 정상 라이선스 생성 프로세스 시작 ===');
    
    try {
      // 1. 라이선스 데이터 자동 생성
      _log('라이선스 데이터 자동 생성 중...');
      final licenseData = await dataGenerator.generate(
        GenerationStrategy(
          dataType: License,
          fields: [
            FieldGeneration(
              fieldName: 'licenseKey',
              valueType: String,
              strategy: 'unique',
              prefix: 'LIC-',
            ),
            FieldGeneration(
              fieldName: 'productName',
              valueType: String,
              strategy: 'predefined',
              values: ['Microsoft Office', 'Adobe Creative Suite', 'JetBrains IDE', 'Visual Studio', 'Slack', 'Zoom'],
            ),
            FieldGeneration(
              fieldName: 'vendor',
              valueType: String,
              strategy: 'predefined',
              values: ['Microsoft', 'Adobe', 'JetBrains', 'Atlassian', 'Oracle', 'Salesforce'],
            ),
            FieldGeneration(
              fieldName: 'licenseType',
              valueType: String,
              strategy: 'predefined',
              values: ['구독형', '영구', '평가판', '교육용', '기업용'],
            ),
            FieldGeneration(
              fieldName: 'userCount',
              valueType: int,
              strategy: 'fixed',
              value: 10,
            ),
            FieldGeneration(
              fieldName: 'purchaseDate',
              valueType: DateTime,
              strategy: 'date',
              format: 'yyyy-MM-dd',
            ),
            FieldGeneration(
              fieldName: 'expiryDate',
              valueType: DateTime,
              strategy: 'date',
              format: 'yyyy-MM-dd',
            ),
            FieldGeneration(
              fieldName: 'purchasePrice',
              valueType: double,
              strategy: 'fixed',
              value: 100000.0,
            ),
          ],
          relationships: [],
          constraints: {
            'licenseKey': ['required', 'minLength:5'],
            'productName': ['required'],
            'userCount': ['min:1'],
          },
        ),
      );
      
      _log('생성된 라이선스 데이터: ${licenseData.toJson()}');
      
      // 2. 회사 ID 확보
      final companyId = testContext.getData('testCompanyId') as int?;
      if (companyId != null) {
        licenseData.data['companyId'] = companyId;
      }
      
      // 3. 라이선스 생성
      _log('라이선스 생성 API 호출 중...');
      License? createdLicense;
      
      try {
        final licenseReq = licenseData.data as Map<String, dynamic>;
        
        // License 객체 생성
        final newLicense = License(
          licenseKey: licenseReq['licenseKey'] ?? 'TEST-${DateTime.now().millisecondsSinceEpoch}',
          productName: licenseReq['productName'] ?? '테스트 제품',
          vendor: licenseReq['vendor'],
          licenseType: licenseReq['licenseType'],
          userCount: licenseReq['userCount'] ?? 1,
          purchaseDate: licenseReq['purchaseDate'] ?? DateTime.now(),
          expiryDate: licenseReq['expiryDate'],
          purchasePrice: licenseReq['purchasePrice']?.toDouble(),
          companyId: licenseReq['companyId'],
          branchId: licenseReq['branchId'],
          remark: '자동화 테스트로 생성된 라이선스',
        );
        
        createdLicense = await licenseService.createLicense(newLicense);
        
        _log('라이선스 생성 성공: ID=${createdLicense.id}');
        testContext.addCreatedResourceId('license', createdLicense.id.toString());
      } catch (e) {
        _log('라이선스 생성 실패: $e');
        
        // 에러 진단
        final diagnosis = await errorDiagnostics.diagnose(
          ApiError(
            endpoint: '/api/v1/licenses',
            method: 'POST',
            statusCode: 400,
            message: e.toString(),
            requestBody: licenseData.toJson(),
            timestamp: DateTime.now(),
            requestUrl: '/api/v1/licenses',
            requestMethod: 'POST',
          ),
        );
        
        _log('에러 진단 결과: ${diagnosis.errorType} - ${diagnosis.description}');
        
        // 자동 수정
        final fixResult = await autoFixer.attemptAutoFix(diagnosis);
        if (!fixResult.success) {
          throw Exception('자동 수정 실패: ${fixResult.error}');
        }
        
        // 수정된 데이터로 재시도
        _log('수정된 데이터로 재시도...');
        final fixedLicense = License(
          licenseKey: 'FIXED-${LicenseTestData.generateLicenseKey()}',
          productName: 'Fixed ${LicenseTestData.generateProductName()}',
          vendor: LicenseTestData.generateVendor(),
          licenseType: 'perpetual',
          userCount: 10,
          purchaseDate: DateTime.now(),
          remark: '자동 수정된 라이선스',
        );
        
        createdLicense = await licenseService.createLicense(fixedLicense);
        
        _log('라이선스 생성 성공 (재시도): ID=${createdLicense.id}');
        testContext.addCreatedResourceId('license', createdLicense.id.toString());
      }
      
      // 4. 생성된 라이선스 조회
      _log('생성된 라이선스 조회 중...');
      final licenseDetail = await licenseService.getLicenseById(createdLicense.id!);
      _log('라이선스 상세 조회 성공: ${licenseDetail.productName}');
      
      testContext.setData('createdLicense', createdLicense);
      testContext.setData('licenseDetail', licenseDetail);
      testContext.setData('processSuccess', true);
      
    } catch (e) {
      _log('예상치 못한 오류 발생: $e');
      testContext.setData('processSuccess', false);
      testContext.setData('lastError', e.toString());
    }
  }
  
  /// 정상 라이선스 생성 검증
  Future<void> verifyNormalLicenseCreation(TestData data) async {
    final processSuccess = testContext.getData('processSuccess') ?? false;
    expect(processSuccess, isTrue, reason: '라이선스 생성 프로세스가 실패했습니다');
    
    final createdLicense = testContext.getData('createdLicense') as License?;
    expect(createdLicense, isNotNull, reason: '라이선스가 생성되지 않았습니다');
    expect(createdLicense!.id, isNotNull, reason: '라이선스 ID가 없습니다');
    expect(createdLicense.licenseKey, isNotEmpty, reason: '라이선스 키가 비어있습니다');
    
    _log('✓ 정상 라이선스 생성 프로세스 검증 완료');
  }
  
  /// 만료 임박 라이선스 관리 시나리오
  Future<void> performExpiringLicenseManagement(TestData data) async {
    _log('=== 만료 임박 라이선스 관리 시나리오 시작 ===');
    
    try {
      // 1. 30일 후 만료되는 라이선스 생성
      final expiryDate = DateTime.now().add(Duration(days: 15)); // 15일 후 만료
      
      final expiringLicense = License(
        licenseKey: 'EXPIRING-${LicenseTestData.generateLicenseKey()}',
        productName: '곧 만료될 제품',
        vendor: LicenseTestData.generateVendor(),
        licenseType: 'subscription',
        userCount: 5,
        purchaseDate: DateTime.now().subtract(Duration(days: 350)),
        expiryDate: expiryDate,
        purchasePrice: 500000,
        companyId: testContext.getData('testCompanyId'),
        remark: '만료 임박 테스트용 라이선스',
      );
      
      final created = await licenseService.createLicense(expiringLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      
      _log('만료 임박 라이선스 생성 완료: ${created.id}, 만료일: ${expiryDate.toIso8601String()}');
      
      // 2. 만료 예정 라이선스 조회
      _log('만료 예정 라이선스 조회 중...');
      final expiringLicenses = await licenseService.getExpiringLicenses(days: 30);
      
      _log('30일 이내 만료 예정 라이선스: ${expiringLicenses.length}개');
      
      // 3. 방금 생성한 라이선스가 포함되어 있는지 확인
      final hasOurLicense = expiringLicenses.any((l) => l.id == created.id);
      
      testContext.setData('expiringLicenseCreated', created);
      testContext.setData('expiringLicensesList', expiringLicenses);
      testContext.setData('hasOurExpiringLicense', hasOurLicense);
      testContext.setData('expiringSuccess', true);
      
    } catch (e) {
      _log('만료 임박 라이선스 관리 중 오류: $e');
      testContext.setData('expiringSuccess', false);
      testContext.setData('expiringError', e.toString());
    }
  }
  
  /// 만료 임박 라이선스 관리 검증
  Future<void> verifyExpiringLicenseManagement(TestData data) async {
    final success = testContext.getData('expiringSuccess') ?? false;
    expect(success, isTrue, reason: '만료 임박 라이선스 관리가 실패했습니다');
    
    final expiringLicenses = testContext.getData('expiringLicensesList') as List<License>?;
    expect(expiringLicenses, isNotNull, reason: '만료 예정 라이선스 목록을 가져오지 못했습니다');
    
    // API가 우리가 생성한 라이선스를 정확히 반환하는지는 타이밍에 따라 다를 수 있음
    // 하지만 만료 예정 라이선스 조회 기능 자체는 작동해야 함
    expect(expiringLicenses, isA<List<License>>(), reason: '올바른 형식의 목록이 아닙니다');
    
    _log('✓ 만료 임박 라이선스 관리 시나리오 검증 완료');
  }
  
  /// 만료된 라이선스 관리 시나리오
  Future<void> performExpiredLicenseManagement(TestData data) async {
    _log('=== 만료된 라이선스 관리 시나리오 시작 ===');
    
    try {
      // 1. 이미 만료된 라이선스 생성
      final expiredDate = DateTime.now().subtract(Duration(days: 30)); // 30일 전 만료
      
      final expiredLicense = License(
        licenseKey: 'EXPIRED-${LicenseTestData.generateLicenseKey()}',
        productName: '만료된 제품',
        vendor: LicenseTestData.generateVendor(),
        licenseType: 'subscription',
        userCount: 3,
        purchaseDate: DateTime.now().subtract(Duration(days: 395)),
        expiryDate: expiredDate,
        purchasePrice: 300000,
        companyId: testContext.getData('testCompanyId'),
        remark: '만료된 라이선스 테스트',
        isActive: false, // 만료된 라이선스는 비활성화
      );
      
      final created = await licenseService.createLicense(expiredLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      
      _log('만료된 라이선스 생성 완료: ${created.id}, 만료일: ${expiredDate.toIso8601String()}');
      
      // 2. 비활성 라이선스 필터링 테스트
      _log('비활성 라이선스 조회 중...');
      final inactiveLicenses = await licenseService.getLicenses(
        page: 1,
        perPage: 100,
        isActive: false,
      );
      
      _log('비활성 라이선스: ${inactiveLicenses.length}개');
      
      // 3. 만료된 라이선스가 비활성 목록에 있는지 확인
      final hasExpiredLicense = inactiveLicenses.any((l) => l.id == created.id);
      
      testContext.setData('expiredLicenseCreated', created);
      testContext.setData('inactiveLicensesList', inactiveLicenses);
      testContext.setData('hasExpiredLicense', hasExpiredLicense);
      testContext.setData('expiredSuccess', true);
      
    } catch (e) {
      _log('만료된 라이선스 관리 중 오류: $e');
      testContext.setData('expiredSuccess', false);
      testContext.setData('expiredError', e.toString());
    }
  }
  
  /// 만료된 라이선스 관리 검증
  Future<void> verifyExpiredLicenseManagement(TestData data) async {
    final success = testContext.getData('expiredSuccess') ?? false;
    expect(success, isTrue, reason: '만료된 라이선스 관리가 실패했습니다');
    
    final inactiveLicenses = testContext.getData('inactiveLicensesList') as List<License>?;
    expect(inactiveLicenses, isNotNull, reason: '비활성 라이선스 목록을 가져오지 못했습니다');
    
    _log('✓ 만료된 라이선스 관리 시나리오 검증 완료');
  }
  
  /// 라이선스 키 유효성 검증 시나리오
  Future<void> performLicenseKeyValidation(TestData data) async {
    _log('=== 라이선스 키 유효성 검증 시나리오 시작 ===');
    
    final invalidKeys = [
      '', // 빈 키
      'A', // 너무 짧은 키
      'ABC-', // 불완전한 형식
      'TEST KEY WITH SPACES', // 공백 포함
      '테스트-라이선스-키', // 한글 포함
      'A' * 300, // 너무 긴 키
    ];
    
    int validationErrors = 0;
    
    for (final invalidKey in invalidKeys) {
      try {
        final invalidLicense = License(
          licenseKey: invalidKey,
          productName: '유효성 검증 테스트',
          vendor: 'Test Vendor',
          licenseType: 'test',
          userCount: 1,
          purchaseDate: DateTime.now(),
        );
        
        await licenseService.createLicense(invalidLicense);
        _log('⚠️ 잘못된 키가 허용됨: "$invalidKey"');
      } catch (e) {
        _log('✓ 예상된 검증 에러 발생: "$invalidKey" - ${e.toString().split('\n').first}');
        validationErrors++;
      }
    }
    
    // 유효한 키 테스트
    final validKeys = [
      'ABCD-EFGH-IJKL-MNOP',
      'TEST123456789',
      'LICENSE-2024-001',
      'PRO_VERSION_1.0',
    ];
    
    int validKeysAccepted = 0;
    
    for (final validKey in validKeys) {
      try {
        final validLicense = License(
          licenseKey: validKey,
          productName: '유효한 라이선스',
          vendor: 'Test Vendor',
          licenseType: 'test',
          userCount: 1,
          purchaseDate: DateTime.now(),
        );
        
        final created = await licenseService.createLicense(validLicense);
        testContext.addCreatedResourceId('license', created.id.toString());
        _log('✓ 유효한 키 허용됨: "$validKey"');
        validKeysAccepted++;
      } catch (e) {
        _log('⚠️ 유효한 키가 거부됨: "$validKey" - ${e.toString()}');
      }
    }
    
    testContext.setData('invalidKeysRejected', validationErrors);
    testContext.setData('validKeysAccepted', validKeysAccepted);
    testContext.setData('keyValidationSuccess', true);
  }
  
  /// 라이선스 키 유효성 검증 확인
  Future<void> verifyLicenseKeyValidation(TestData data) async {
    final success = testContext.getData('keyValidationSuccess') ?? false;
    expect(success, isTrue, reason: '키 유효성 검증이 실행되지 않았습니다');
    
    final invalidKeysRejected = testContext.getData('invalidKeysRejected') ?? 0;
    final validKeysAccepted = testContext.getData('validKeysAccepted') ?? 0;
    
    // 적어도 일부 잘못된 키는 거부되어야 함
    expect(invalidKeysRejected, greaterThan(0), reason: '잘못된 키가 전혀 거부되지 않았습니다');
    
    // 적어도 일부 유효한 키는 허용되어야 함
    expect(validKeysAccepted, greaterThan(0), reason: '유효한 키가 전혀 허용되지 않았습니다');
    
    _log('✓ 라이선스 키 유효성 검증 시나리오 검증 완료');
  }
  
  /// 중복 라이선스 키 처리 시나리오
  Future<void> performDuplicateLicenseKeyHandling(TestData data) async {
    _log('=== 중복 라이선스 키 처리 시나리오 시작 ===');
    
    try {
      // 1. 첫 번째 라이선스 생성
      final uniqueKey = 'UNIQUE-${DateTime.now().millisecondsSinceEpoch}';
      
      final firstLicense = License(
        licenseKey: uniqueKey,
        productName: '첫 번째 제품',
        vendor: 'Test Vendor',
        licenseType: 'perpetual',
        userCount: 10,
        purchaseDate: DateTime.now(),
      );
      
      final created = await licenseService.createLicense(firstLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      _log('첫 번째 라이선스 생성 성공: ${created.id}');
      
      // 2. 동일한 키로 두 번째 라이선스 생성 시도
      final duplicateLicense = License(
        licenseKey: uniqueKey, // 동일한 키 사용
        productName: '두 번째 제품',
        vendor: 'Another Vendor',
        licenseType: 'subscription',
        userCount: 5,
        purchaseDate: DateTime.now(),
      );
      
      bool duplicateRejected = false;
      
      try {
        await licenseService.createLicense(duplicateLicense);
        _log('⚠️ 중복 라이선스 키가 허용되었습니다');
      } catch (e) {
        _log('✓ 예상된 중복 에러 발생: ${e.toString().split('\n').first}');
        duplicateRejected = true;
      }
      
      testContext.setData('firstLicenseId', created.id);
      testContext.setData('duplicateKey', uniqueKey);
      testContext.setData('duplicateRejected', duplicateRejected);
      testContext.setData('duplicateSuccess', true);
      
    } catch (e) {
      _log('중복 라이선스 키 처리 중 오류: $e');
      testContext.setData('duplicateSuccess', false);
      testContext.setData('duplicateError', e.toString());
    }
  }
  
  /// 중복 라이선스 키 처리 검증
  Future<void> verifyDuplicateLicenseKeyHandling(TestData data) async {
    final success = testContext.getData('duplicateSuccess') ?? false;
    expect(success, isTrue, reason: '중복 라이선스 키 처리가 실행되지 않았습니다');
    
    // 중복 키가 거부되었는지 확인
    // 일부 시스템은 중복을 허용할 수 있으므로 경고만 표시
    final duplicateRejected = testContext.getData('duplicateRejected') ?? false;
    if (!duplicateRejected) {
      _log('⚠️ 경고: 시스템이 중복 라이선스 키를 허용합니다');
    }
    
    _log('✓ 중복 라이선스 키 처리 시나리오 검증 완료');
  }
  
  /// 필수 필드 누락 시나리오
  Future<void> performMissingRequiredFields(TestData data) async {
    _log('=== 필수 필드 누락 시나리오 시작 ===');
    
    // 필수 필드가 누락된 라이선스 데이터
    try {
      final incompleteLicense = License(
        licenseKey: '', // 빈 라이선스 키
        productName: null, // null 제품명
        vendor: null,
        licenseType: null,
        userCount: null,
        purchaseDate: null,
        expiryDate: null,
        purchasePrice: null,
      );
      
      await licenseService.createLicense(incompleteLicense);
      fail('필수 필드가 누락된 데이터로 라이선스가 생성되어서는 안 됩니다');
    } catch (e) {
      _log('예상된 에러 발생: $e');
      
      // 에러 진단
      final diagnosis = await errorDiagnostics.diagnose(
        ApiError(
          endpoint: '/api/v1/licenses',
          method: 'POST',
          statusCode: 400,
          message: e.toString(),
          requestBody: {
            'licenseKey': '',
            'productName': null,
          },
          timestamp: DateTime.now(),
          requestUrl: '/api/v1/licenses',
          requestMethod: 'POST',
        ),
      );
      
      expect(diagnosis.errorType, equals(ErrorType.missingRequiredField));
      _log('진단 결과: ${diagnosis.missingFields?.length ?? 0}개 필드 누락');
      
      // 자동 수정
      final fixResult = await autoFixer.attemptAutoFix(diagnosis);
      if (!fixResult.success) {
        throw Exception('자동 수정 실패: ${fixResult.error}');
      }
      
      // 수정된 데이터로 재시도
      _log('수정된 데이터로 재시도...');
      final fixedLicense = License(
        licenseKey: 'AUTO-FIXED-${LicenseTestData.generateLicenseKey()}',
        productName: 'Auto Fixed Product',
        vendor: 'Auto Fix Vendor',
        licenseType: 'perpetual',
        userCount: 1,
        purchaseDate: DateTime.now(),
      );
      
      final created = await licenseService.createLicense(fixedLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      testContext.setData('missingFieldsFixed', true);
      testContext.setData('fixedLicense', created);
    }
  }
  
  /// 필수 필드 누락 시나리오 검증
  Future<void> verifyMissingRequiredFields(TestData data) async {
    final missingFieldsFixed = testContext.getData('missingFieldsFixed') ?? false;
    expect(missingFieldsFixed, isTrue, reason: '필수 필드 누락 문제가 해결되지 않았습니다');
    
    final fixedLicense = testContext.getData('fixedLicense');
    expect(fixedLicense, isNotNull, reason: '수정된 라이선스가 생성되지 않았습니다');
    
    _log('✓ 필수 필드 누락 시나리오 검증 완료');
  }
  
  /// 영구 라이선스 타입 테스트
  Future<void> performPerpetualLicenseTest(TestData data) async {
    _log('=== 영구 라이선스 타입 테스트 시작 ===');
    
    try {
      // 영구 라이선스는 만료일이 없음
      final perpetualLicense = License(
        licenseKey: 'PERPETUAL-${LicenseTestData.generateLicenseKey()}',
        productName: '영구 라이선스 제품',
        vendor: 'Perpetual Vendor',
        licenseType: 'perpetual',
        userCount: 999, // 무제한을 나타내는 큰 수
        purchaseDate: DateTime.now(),
        expiryDate: null, // 만료일 없음
        purchasePrice: 5000000,
        remark: '영구 라이선스 - 만료 없음',
      );
      
      final created = await licenseService.createLicense(perpetualLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      
      _log('영구 라이선스 생성 성공: ${created.id}');
      
      // 생성된 라이선스 확인
      final retrieved = await licenseService.getLicenseById(created.id!);
      
      testContext.setData('perpetualLicense', created);
      testContext.setData('retrievedPerpetual', retrieved);
      testContext.setData('perpetualSuccess', true);
      
    } catch (e) {
      _log('영구 라이선스 생성 중 오류: $e');
      testContext.setData('perpetualSuccess', false);
      testContext.setData('perpetualError', e.toString());
    }
  }
  
  /// 영구 라이선스 타입 검증
  Future<void> verifyPerpetualLicenseTest(TestData data) async {
    final success = testContext.getData('perpetualSuccess') ?? false;
    expect(success, isTrue, reason: '영구 라이선스 생성이 실패했습니다');
    
    final perpetualLicense = testContext.getData('perpetualLicense') as License?;
    expect(perpetualLicense, isNotNull, reason: '영구 라이선스가 생성되지 않았습니다');
    expect(perpetualLicense!.licenseType, equals('perpetual'), reason: '라이선스 타입이 올바르지 않습니다');
    expect(perpetualLicense.expiryDate, isNull, reason: '영구 라이선스에 만료일이 설정되었습니다');
    
    _log('✓ 영구 라이선스 타입 테스트 검증 완료');
  }
  
  /// 기간제 라이선스 타입 테스트
  Future<void> performTermLicenseTest(TestData data) async {
    _log('=== 기간제 라이선스 타입 테스트 시작 ===');
    
    try {
      // 1년 기간제 라이선스
      final startDate = DateTime.now();
      final endDate = startDate.add(Duration(days: 365));
      
      final termLicense = License(
        licenseKey: 'TERM-${LicenseTestData.generateLicenseKey()}',
        productName: '기간제 라이선스 제품',
        vendor: 'Term Vendor',
        licenseType: 'subscription',
        userCount: 20,
        purchaseDate: startDate,
        expiryDate: endDate, // 1년 후 만료
        purchasePrice: 1200000, // 연간 구독료
        remark: '1년 기간제 라이선스',
      );
      
      final created = await licenseService.createLicense(termLicense);
      testContext.addCreatedResourceId('license', created.id.toString());
      
      _log('기간제 라이선스 생성 성공: ${created.id}');
      _log('시작일: ${startDate.toIso8601String()}');
      _log('만료일: ${endDate.toIso8601String()}');
      
      // 생성된 라이선스 확인
      final retrieved = await licenseService.getLicenseById(created.id!);
      
      testContext.setData('termLicense', created);
      testContext.setData('retrievedTerm', retrieved);
      testContext.setData('termSuccess', true);
      
    } catch (e) {
      _log('기간제 라이선스 생성 중 오류: $e');
      testContext.setData('termSuccess', false);
      testContext.setData('termError', e.toString());
    }
  }
  
  /// 기간제 라이선스 타입 검증
  Future<void> verifyTermLicenseTest(TestData data) async {
    final success = testContext.getData('termSuccess') ?? false;
    expect(success, isTrue, reason: '기간제 라이선스 생성이 실패했습니다');
    
    final termLicense = testContext.getData('termLicense') as License?;
    expect(termLicense, isNotNull, reason: '기간제 라이선스가 생성되지 않았습니다');
    expect(termLicense!.licenseType, equals('subscription'), reason: '라이선스 타입이 올바르지 않습니다');
    expect(termLicense.expiryDate, isNotNull, reason: '기간제 라이선스에 만료일이 없습니다');
    
    // 만료일이 구매일보다 나중인지 확인
    if (termLicense.purchaseDate != null && termLicense.expiryDate != null) {
      expect(
        termLicense.expiryDate!.isAfter(termLicense.purchaseDate!),
        isTrue,
        reason: '만료일이 구매일보다 이전입니다',
      );
    }
    
    _log('✓ 기간제 라이선스 타입 테스트 검증 완료');
  }
  
  /// 사용자 할당/해제 시나리오
  Future<void> performUserAssignment(TestData data) async {
    _log('=== 사용자 할당/해제 시나리오 시작 ===');
    
    try {
      // 1. 라이선스 생성
      final license = License(
        licenseKey: 'ASSIGN-${LicenseTestData.generateLicenseKey()}',
        productName: '사용자 할당 테스트 제품',
        vendor: 'Assignment Vendor',
        licenseType: 'user',
        userCount: 1, // 단일 사용자 라이선스
        purchaseDate: DateTime.now(),
        expiryDate: DateTime.now().add(Duration(days: 365)),
        purchasePrice: 500000,
      );
      
      final created = await licenseService.createLicense(license);
      testContext.addCreatedResourceId('license', created.id.toString());
      
      _log('할당용 라이선스 생성 완료: ${created.id}');
      
      // 2. 사용자 목록 조회 (할당할 사용자 찾기)
      final users = await userService.getUsers(page: 1, perPage: 10);
      
      if (users.isNotEmpty) {
        final targetUser = users.first;
        _log('할당 대상 사용자: ${targetUser.name} (ID: ${targetUser.id})');
        
        // 3. 라이선스 할당
        _log('라이선스 할당 중...');
        final assignedLicense = await licenseService.assignLicense(created.id!, targetUser.id!);
        
        _log('라이선스 할당 성공');
        expect(assignedLicense.assignedUserId, equals(targetUser.id), reason: '사용자 ID가 일치하지 않습니다');
        
        // 4. 할당 해제
        _log('라이선스 할당 해제 중...');
        final unassignedLicense = await licenseService.unassignLicense(created.id!);
        
        _log('라이선스 할당 해제 성공');
        expect(unassignedLicense.assignedUserId, isNull, reason: '사용자 ID가 제거되지 않았습니다');
        
        testContext.setData('assignmentSuccess', true);
        testContext.setData('assignedUserId', targetUser.id);
      } else {
        _log('할당할 사용자가 없습니다. 할당 테스트를 건너뜁니다.');
        testContext.setData('assignmentSuccess', true);
        testContext.setData('noUsersAvailable', true);
      }
      
    } catch (e) {
      _log('사용자 할당/해제 중 오류: $e');
      testContext.setData('assignmentSuccess', false);
      testContext.setData('assignmentError', e.toString());
    }
  }
  
  /// 사용자 할당/해제 검증
  Future<void> verifyUserAssignment(TestData data) async {
    final success = testContext.getData('assignmentSuccess') ?? false;
    expect(success, isTrue, reason: '사용자 할당/해제가 실패했습니다');
    
    final noUsersAvailable = testContext.getData('noUsersAvailable') ?? false;
    if (!noUsersAvailable) {
      final assignedUserId = testContext.getData('assignedUserId');
      expect(assignedUserId, isNotNull, reason: '사용자가 할당되지 않았습니다');
    }
    
    _log('✓ 사용자 할당/해제 시나리오 검증 완료');
  }
  
  // BaseScreenTest의 추상 메서드 구현
  
  @override
  Future<dynamic> performCreateOperation(TestData data) async {
    final licenseData = data.data;
    
    final license = License(
      licenseKey: licenseData['licenseKey'] ?? 'TEST-${DateTime.now().millisecondsSinceEpoch}',
      productName: licenseData['productName'] ?? 'Test Product',
      vendor: licenseData['vendor'],
      licenseType: licenseData['licenseType'] ?? 'perpetual',
      userCount: licenseData['userCount'] ?? 1,
      purchaseDate: licenseData['purchaseDate'] ?? DateTime.now(),
      expiryDate: licenseData['expiryDate'],
      purchasePrice: licenseData['purchasePrice']?.toDouble(),
      companyId: licenseData['companyId'],
      branchId: licenseData['branchId'],
      remark: licenseData['remark'],
    );
    
    return await licenseService.createLicense(license);
  }
  
  @override
  Future<dynamic> performReadOperation(TestData data) async {
    return await licenseService.getLicenses(
      page: data.data['page'] ?? 1,
      perPage: data.data['perPage'] ?? 20,
      isActive: data.data['isActive'],
      companyId: data.data['companyId'],
      licenseType: data.data['licenseType'],
    );
  }
  
  @override
  Future<dynamic> performUpdateOperation(dynamic resourceId, Map<String, dynamic> updateData) async {
    // 먼저 기존 라이선스 정보 조회
    final existing = await licenseService.getLicenseById(resourceId as int);
    
    // 업데이트할 라이선스 객체 생성
    final updated = License(
      id: existing.id,
      licenseKey: existing.licenseKey, // 키는 변경 불가
      productName: updateData['productName'] ?? existing.productName,
      vendor: updateData['vendor'] ?? existing.vendor,
      licenseType: updateData['licenseType'] ?? existing.licenseType,
      userCount: updateData['userCount'] ?? existing.userCount,
      purchaseDate: updateData['purchaseDate'] ?? existing.purchaseDate,
      expiryDate: updateData['expiryDate'] ?? existing.expiryDate,
      purchasePrice: updateData['purchasePrice']?.toDouble() ?? existing.purchasePrice,
      companyId: existing.companyId,
      branchId: existing.branchId,
      assignedUserId: existing.assignedUserId,
      remark: updateData['remark'] ?? existing.remark,
      isActive: updateData['isActive'] ?? existing.isActive,
    );
    
    return await licenseService.updateLicense(updated);
  }
  
  @override
  Future<void> performDeleteOperation(dynamic resourceId) async {
    await licenseService.deleteLicense(resourceId as int);
  }
  
  @override
  dynamic extractResourceId(dynamic resource) {
    return (resource as License).id;
  }
  
  // 헬퍼 메서드
  void _log(String message) {
    final timestamp = DateTime.now().toString();
    debugPrint('[$timestamp] [License] $message');
    
    // 리포트 수집기에도 로그 추가
    reportCollector.addStep(
      report_models.StepReport(
        stepName: 'License Management',
        timestamp: DateTime.now(),
        success: !message.contains('실패') && !message.contains('에러'),
        message: message,
        details: {},
      ),
    );
  }
}

/// 라이선스 테스트 데이터 생성 유틸리티
class LicenseTestData {
  static final random = Random();
  
  // 라이선스 키 생성기
  static String generateLicenseKey() {
    final prefixes = ['PRO', 'ENT', 'STD', 'TRIAL', 'DEV', 'PROD'];
    final prefix = prefixes[random.nextInt(prefixes.length)];
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString().substring(6);
    final randomPart = random.nextInt(9999).toString().padLeft(4, '0');
    
    return '$prefix-$timestamp-$randomPart';
  }
  
  // 제품명 생성기
  static String generateProductName() {
    final products = [
      'Microsoft Office 365',
      'Adobe Creative Cloud',
      'AutoCAD 2024',
      'Visual Studio Enterprise',
      'IntelliJ IDEA Ultimate',
      'Slack Business+',
      'Zoom Pro',
      'Jira Software',
      'GitHub Enterprise',
      'Docker Enterprise',
      'VMware vSphere',
      'Salesforce CRM',
      'SAP S/4HANA',
      'Oracle Database',
      'MongoDB Enterprise',
    ];
    
    return products[random.nextInt(products.length)];
  }
  
  // 벤더명 생성기
  static String generateVendor() {
    final vendors = [
      'Microsoft',
      'Adobe',
      'Autodesk',
      'JetBrains',
      'Atlassian',
      'Oracle',
      'SAP',
      'IBM',
      'VMware',
      'Salesforce',
      'Google',
      'Amazon',
      'Docker',
      'Red Hat',
      'Elastic',
    ];
    
    return vendors[random.nextInt(vendors.length)];
  }
  
  // 라이선스 타입 생성기
  static String generateLicenseType() {
    final types = ['perpetual', 'subscription', 'trial', 'oem', 'academic', 'nfr'];
    return types[random.nextInt(types.length)];
  }
  
  // 구매일 생성기 (과거 2년 이내)
  static DateTime generatePurchaseDate() {
    final daysAgo = random.nextInt(730); // 최대 2년 전
    return DateTime.now().subtract(Duration(days: daysAgo));
  }
  
  // 만료일 생성기 (구매일 기준 1-3년 후, 또는 null)
  static DateTime? generateExpiryDate() {
    // 30% 확률로 영구 라이선스 (만료일 없음)
    if (random.nextDouble() < 0.3) {
      return null;
    }
    
    // 나머지는 미래 날짜
    final daysFromNow = random.nextInt(1095) - 365; // -365 ~ +730일
    return DateTime.now().add(Duration(days: daysFromNow));
  }
}

// 테스트 실행을 위한 main 함수
void main() {
  group('License Screen Automated Test', () {
    test('This is a screen test class, not a standalone test', () {
      // 이 클래스는 BaseScreenTest를 상속받아 프레임워크를 통해 실행됩니다
      // 직접 실행하려면 run_license_test.dart를 사용하세요
      expect(true, isTrue);
    });
  });
}