import 'package:flutter_test/flutter_test.dart';
import 'package:superport/core/migrations/license_to_maintenance_migration.dart';
import 'package:superport/core/migrations/maintenance_data_validator.dart';

void main() {
  group('License to Maintenance Migration Tests', () {
    // 테스트용 License 데이터
    final testLicenseData = [
      {
        'id': 1,
        'equipment_id': 101,
        'license_type': 'O', // Onsite
        'period_months': 12,
        'cost': 1000000,
        'vendor_name': '삼성전자서비스',
        'vendor_contact': '1588-3366',
        'start_date': '2024-01-01T00:00:00Z',
        'expiry_date': '2024-12-31T23:59:59Z',
        'created_at': '2024-01-01T00:00:00Z',
      },
      {
        'id': 2,
        'equipment_id': 102,
        'license_type': 'R', // Remote
        'period_months': 6,
        'cost': 500000,
        'vendor_name': 'LG전자서비스',
        'vendor_contact': '1544-7777',
        'start_date': '2024-06-01T00:00:00Z',
        'expiry_date': '2024-11-30T23:59:59Z',
        'created_at': '2024-06-01T00:00:00Z',
      },
      {
        'id': 3,
        'equipment_id': 103,
        'license_type': 'O',
        'period_months': 24,
        'cost': 2000000,
        'vendor_name': '델코리아',
        'vendor_contact': '1588-1588',
        'start_date': '2023-01-01T00:00:00Z',
        'expiry_date': '2024-12-31T23:59:59Z', // 곧 만료
        'created_at': '2023-01-01T00:00:00Z',
      },
    ];
    
    // 테스트용 Equipment 데이터
    final testEquipmentData = [
      {'id': 101, 'equipment_number': 'EQ-001', 'name': '서버 #1'},
      {'id': 102, 'equipment_number': 'EQ-002', 'name': '서버 #2'},
      {'id': 103, 'equipment_number': 'EQ-003', 'name': '서버 #3'},
    ];
    
    // 테스트용 Equipment History 데이터
    final testEquipmentHistoryData = [
      {
        'id': 201,
        'equipments_id': 101,
        'transaction_type': 'IN',
        'created_at': '2024-01-01T00:00:00Z',
      },
      {
        'id': 202,
        'equipments_id': 102,
        'transaction_type': 'IN',
        'created_at': '2024-06-01T00:00:00Z',
      },
      {
        'id': 203,
        'equipments_id': 103,
        'transaction_type': 'IN',
        'created_at': '2023-01-01T00:00:00Z',
      },
    ];
    
    test('Should successfully migrate license data to maintenance', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 검증
      expect(result.success, true);
      expect(result.maintenanceData, isNotNull);
      expect(result.maintenanceData!.length, 3);
      expect(result.backup, isNotNull);
      expect(result.statistics, isNotNull);
    });
    
    test('Should correctly map equipment history IDs', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 각 Maintenance가 올바른 equipment_history_id를 가지는지 검증
      final maintenance1 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 1);
      expect(maintenance1['equipment_history_id'], 201);
      
      final maintenance2 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 2);
      expect(maintenance2['equipment_history_id'], 202);
      
      final maintenance3 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 3);
      expect(maintenance3['equipment_history_id'], 203);
    });
    
    test('Should correctly convert license types to maintenance types', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 유형 변환 검증
      final maintenance1 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 1);
      expect(maintenance1['maintenance_type'], 'O'); // Onsite
      
      final maintenance2 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 2);
      expect(maintenance2['maintenance_type'], 'R'); // Remote
    });
    
    test('Should calculate correct maintenance status', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 상태 계산 검증
      for (final maintenance in result.maintenanceData!) {
        final status = maintenance['status'];
        expect(
          ['scheduled', 'upcoming', 'overdue'].contains(status),
          true,
          reason: 'Status should be one of: scheduled, upcoming, overdue',
        );
      }
    });
    
    test('Should preserve cost and vendor information', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 비용 및 업체 정보 보존 검증
      final maintenance1 = result.maintenanceData!
          .firstWhere((m) => m['id'] == 1);
      expect(maintenance1['cost'], 1000000);
      expect(maintenance1['vendor_name'], '삼성전자서비스');
      expect(maintenance1['vendor_contact'], '1588-3366');
    });
    
    test('Should generate correct analysis statistics', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 통계 검증
      expect(result.statistics, isNotNull);
      expect(result.statistics!.totalCount, 3);
      expect(result.statistics!.activeCount, greaterThanOrEqualTo(0));
      expect(result.statistics!.expiredCount, greaterThanOrEqualTo(0));
      expect(result.statistics!.upcomingCount, greaterThanOrEqualTo(0));
      
      // 총합 검증
      final total = result.statistics!.activeCount + 
                   result.statistics!.expiredCount + 
                   result.statistics!.upcomingCount;
      expect(total, result.statistics!.totalCount);
    });
    
    test('Should create valid backup data', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 백업 데이터 검증
      expect(result.backup, isNotNull);
      expect(result.backup!['timestamp'], isNotNull);
      expect(result.backup!['version'], '1.0.0');
      expect(result.backup!['data'], testLicenseData);
      expect(result.backup!['checksum'], isNotNull);
    });
    
    test('Should handle missing equipment history gracefully', () async {
      // Equipment History가 없는 License 데이터
      final incompleteData = [
        {
          'id': 999,
          'equipment_id': 999, // 존재하지 않는 Equipment
          'license_type': 'O',
          'period_months': 12,
          'cost': 1000000,
          'start_date': '2024-01-01T00:00:00Z',
          'expiry_date': '2024-12-31T23:59:59Z',
        },
      ];
      
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: incompleteData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 검증 - 마이그레이션은 성공하지만 데이터는 변환되지 않음
      expect(result.success, true);
      expect(result.maintenanceData!.length, 0); // 변환된 데이터 없음
    });
    
    test('Should validate migrated data correctly', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 데이터 검증
      final validationReport = await MaintenanceDataValidator.validate(
        maintenanceData: result.maintenanceData!,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      // 검증 결과 확인
      expect(validationReport.isValid, true);
      expect(validationReport.dataIntegrity, true);
      expect(validationReport.businessRulesValid, true);
    });
    
    test('Should support rollback functionality', () async {
      // 마이그레이션 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: testLicenseData,
        equipmentData: testEquipmentData,
        equipmentHistoryData: testEquipmentHistoryData,
      );
      
      expect(result.success, true);
      expect(result.backup, isNotNull);
      
      // 롤백 테스트
      final rollbackSuccess = await LicenseToMaintenanceMigration.rollback(
        result.backup!,
      );
      
      expect(rollbackSuccess, true);
    });
  });
  
  group('Edge Cases and Error Handling', () {
    test('Should handle empty license data', () async {
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: [],
        equipmentData: [],
        equipmentHistoryData: [],
      );
      
      // 검증
      expect(result.success, true);
      expect(result.maintenanceData!.length, 0);
      expect(result.statistics!.totalCount, 0);
    });
    
    test('Should handle null dates gracefully', () async {
      // null 날짜를 가진 License 데이터
      final dataWithNullDates = [
        {
          'id': 1,
          'equipment_id': 101,
          'license_type': 'O',
          'period_months': 12,
          'cost': 1000000,
          'start_date': null,
          'expiry_date': null,
        },
      ];
      
      final equipmentHistory = [
        {
          'id': 201,
          'equipments_id': 101,
          'transaction_type': 'IN',
        },
      ];
      
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: dataWithNullDates,
        equipmentData: [],
        equipmentHistoryData: equipmentHistory,
      );
      
      // 검증
      expect(result.success, true);
      expect(result.maintenanceData!.length, 1);
      expect(result.maintenanceData![0]['status'], 'scheduled');
    });
    
    test('Should handle duplicate license IDs', () async {
      // 중복 ID를 가진 License 데이터
      final duplicateData = [
        {
          'id': 1,
          'equipment_id': 101,
          'license_type': 'O',
          'period_months': 12,
        },
        {
          'id': 1, // 중복 ID
          'equipment_id': 102,
          'license_type': 'R',
          'period_months': 6,
        },
      ];
      
      final equipmentHistory = [
        {'id': 201, 'equipments_id': 101},
        {'id': 202, 'equipments_id': 102},
      ];
      
      // 실행
      final result = await LicenseToMaintenanceMigration.migrate(
        licenseData: duplicateData,
        equipmentData: [],
        equipmentHistoryData: equipmentHistory,
      );
      
      // 검증 - 중복 ID도 처리되어야 함
      expect(result.success, true);
      expect(result.maintenanceData!.length, 2);
    });
  });
}