import 'package:flutter/foundation.dart'; // debugPrint
import 'package:hive_flutter/hive_flutter.dart';
import '../models/sake_item.dart';
import 'image_compression_service.dart';

class MigrationService {
  static const String _boxName = 'sake_items';
  static const String _backupBoxName = 'sake_items_backup';

  /// Runs the migration process with safety backup.
  /// Should be called after Hive.init and Adapter registration, but before app UI loads.
  static Future<void> runMigration() async {
    debugPrint('[Migration] Starting Phase 0 Migration...');
    
    // 1. Open Boxes
    final box = await Hive.openBox<SakeItem>(_boxName);
    
    // 2. Backup Strategy
    try {
      final backupBox = await Hive.openBox<SakeItem>(_backupBoxName);
      
      if (backupBox.isEmpty && box.isNotEmpty) {
        debugPrint('[Migration] detailed backup started...');
        // Copy all
        for (var key in box.keys) {
          final SakeItem? item = box.get(key);
          if (item != null) {
            await backupBox.put(key, item.copyWith());
          }
        }
        debugPrint('[Migration] Backup completed. ${backupBox.length} items secured.');
      } else {
        debugPrint('[Migration] Backup skipped (Existing backup found or Empty source).');
      }
      
      // Close backup to ensure flush
      await backupBox.close();

    } catch (e) {
      debugPrint('[Migration] CRITICAL ERROR during Backup: $e');
      // If backup fails, do we abort?
      // Yes, abort migration to be safe.
      return; 
    }

    // 3. Migration (In-Place)
    int migratedCount = 0;
    for (var key in box.keys) {
      final SakeItem? item = box.get(key);
      if (item != null) {
        try {
          // ensureMigrated checks if displayData is null.
          // If null, it populates it from legacy fields.
          bool performed = item.ensureMigrated();
          if (performed) {
            await item.save(); // Persist the new structure (DisplayData, etc)
            migratedCount++;
          }
        } catch (e) {
          debugPrint('[Migration] Error migrating item $key: $e');
        }
      }
    }

    if (migratedCount > 0) {
      debugPrint('[Migration] Successfully migrated $migratedCount items to Schema v2.0.');
    } else {
      debugPrint('[Migration] No items needed migration.');
    }
  }

  /// CR-005: 既存画像の圧縮マイグレーション
  /// 500MB超の既存画像を圧縮してストレージを解放する
  static Future<void> compressAllExistingImages() async {
    debugPrint('[Migration] Starting Image Compression...');
    final box = Hive.box<SakeItem>(_boxName);
    int compressedCount = 0;

    for (var key in box.keys) {
      final SakeItem? item = box.get(key);
      if (item == null) continue;

      bool changed = false;
      List<String> newPaths = [];

      for (String path in item.displayData.imagePaths) {
        // 既に圧縮済みっぽいファイル名ならスキップ (簡易チェック)
        if (path.contains('_compressed')) {
          newPaths.add(path);
          continue;
        }

        try {
          // 圧縮実行 (1024px, 85%)
          // 元ファイルを置き換えるのではなく、新しいパスを取得
          final String newPath = await ImageCompressionService.compressForGemini(path);
          
          if (newPath != path) {
            newPaths.add(newPath);
            changed = true;
            // 元画像は？ 安全のため一旦保持するか、削除するか。
            // 容量削減が目的なので、成功したら元画像は削除したいが、
            // ユーザーのファイルを勝手に消すのはリスクがあるため、今回は「新しいパスへの切り替え」のみ行う。
            // (OSの一時ファイル削除に任せる、または後でクリーンアップ)
            // が、Storage Rescueの文脈では「容量削減」なので削除すべきだが、
            // ImageCompressionServiceの実装では '_compressed' を別名で作る。
            // 元ファイルがユーザーのギャラリーにある場合、それを消すとオリジナルが消える。
            // アプリ内コピーであれば消して良い。
            // 安全策: パスだけ更新。圧縮ファイルを使うようにする。
          } else {
             newPaths.add(path);
          }
        } catch (e) {
          debugPrint('[Migration] Error compressing image for ${item.displayData.displayName}: $e');
          newPaths.add(path); // エラー時は元パス維持
        }
      }

      if (changed) {
        final newItem = item.copyWith(
          imagePaths: newPaths,
        );
        await box.put(key, newItem);
        compressedCount++;
      }
    }
    debugPrint('[Migration] Image compression completed. Updated $compressedCount items.');
  }
}
