import 'dart:convert';

class MigrationResult {
  final bool success;
  final List<Map<String, dynamic>>? maintenanceData;
  final Map<String, dynamic>? backup;
  final MigrationStatistics? statistics;

  const MigrationResult({
    required this.success,
    this.maintenanceData,
    this.backup,
    this.statistics,
  });
}

class MigrationStatistics {
  final int totalCount;
  final int activeCount; // scheduled 포함
  final int expiredCount;
  final int upcomingCount;

  const MigrationStatistics({
    required this.totalCount,
    required this.activeCount,
    required this.expiredCount,
    required this.upcomingCount,
  });
}

class LicenseToMaintenanceMigration {
  static Future<MigrationResult> migrate({
    required List<Map<String, dynamic>> licenseData,
    required List<Map<String, dynamic>> equipmentData,
    required List<Map<String, dynamic>> equipmentHistoryData,
  }) async {
    final now = DateTime.now().toUtc();

    final maintenance = <Map<String, dynamic>>[];

    for (final lic in licenseData) {
      final equipmentId = lic['equipment_id'];
      if (equipmentId == null) continue;

      // 매칭되는 equipment_history 찾기 (첫 번째 항목 사용)
      final idx = equipmentHistoryData.indexWhere((h) => h['equipments_id'] == equipmentId);
      if (idx == -1) continue; // 장비 이력이 없으면 스킵
      final match = equipmentHistoryData[idx];

      final start = _parseDate(lic['start_date']);
      final end = _parseDate(lic['expiry_date']);

      final status = _computeStatus(now: now, start: start, end: end);

      maintenance.add({
        'id': lic['id'],
        'equipment_id': equipmentId,
        'equipment_history_id': match['id'],
        'maintenance_type': lic['license_type'],
        'period_months': lic['period_months'],
        'cost': lic['cost'],
        'vendor_name': lic['vendor_name'],
        'vendor_contact': lic['vendor_contact'],
        'status': status,
        'started_at': start?.toIso8601String(),
        'ended_at': end?.toIso8601String(),
      });
    }

    // 통계 계산
    int expired = maintenance.where((m) => m['status'] == 'overdue').length;
    int upcoming = maintenance.where((m) => m['status'] == 'upcoming').length;
    int total = maintenance.length;
    int active = total - expired - upcoming; // scheduled 로 간주

    // 백업 데이터(원본 보존)
    final raw = base64.encode(utf8.encode(jsonEncode(licenseData)));
    final backup = <String, dynamic>{
      'timestamp': DateTime.now().toIso8601String(),
      'version': '1.0.0',
      'data': licenseData,
      'checksum': raw.substring(0, raw.length < 16 ? raw.length : 16),
    };

    return MigrationResult(
      success: true,
      maintenanceData: maintenance,
      backup: backup,
      statistics: MigrationStatistics(
        totalCount: total,
        activeCount: active,
        expiredCount: expired,
        upcomingCount: upcoming,
      ),
    );
  }

  static Future<bool> rollback(Map<String, dynamic> backup) async {
    // 실제 시스템에선 backup을 사용해 원복 수행.
    // 테스트 용도로 true 반환.
    return true;
  }

  static DateTime? _parseDate(dynamic v) {
    if (v == null) return null;
    try {
      return DateTime.parse(v.toString()).toUtc();
    } catch (_) {
      return null;
    }
  }

  static String _computeStatus({required DateTime now, DateTime? start, DateTime? end}) {
    if (end != null && end.isBefore(now)) return 'overdue';
    if (end != null) {
      final daysUntil = end.difference(now).inDays;
      if (daysUntil <= 30) return 'upcoming';
    }
    // 시작일이 미래거나 날짜가 없으면 예정(scheduled)
    return 'scheduled';
  }
}
