import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';
import '../models/sake_item.dart';
import 'image_compression_service.dart';

// ⚠️ Critical Fix (Day 5.5): cleanupTempFiles() を修正
// 問題: getApplicationDocumentsDirectory() をスキャンして _compressed, _gallery を削除
// 結果: 本物の画像を誤削除
// 修正: getTemporaryDirectory() のみをスキャン

/// 既存画像の一括圧縮サービス
/// 
/// 用途: アプリ更新後、既存の未圧縮画像を圧縮してストレージを削減
class ImageBatchCompressionService {
  /// 既存の画像を一括圧縮
  /// 
  /// 処理内容:
  /// 1. すべての SakeItem から画像パスを取得
  /// 2. 各画像を圧縮（1024px, JPEG 85%）
  /// 3. 元画像を削除
  /// 4. SakeItem の imagePaths を更新
  /// 
  /// 戻り値: (圧縮成功数, 圧縮失敗数, 削減したバイト数)
  static Future<(int, int, int)> compressAllImages({
    required Function(int current, int total, String fileName) onProgress,
  }) async {
    final box = Hive.box<SakeItem>('sake_items');
    final allItems = box.values.toList();
    
    int successCount = 0;
    int failedCount = 0;
    int savedBytes = 0;
    int totalImages = 0;
    
    // 全画像数をカウント
    for (final item in allItems) {
      totalImages += item.displayData.imagePaths.length;
    }
    
    int processedCount = 0;
    
    for (final item in allItems) {
      final originalPaths = List<String>.from(item.displayData.imagePaths);
      final newPaths = <String>[];
      
      for (final originalPath in originalPaths) {
        processedCount++;
        final file = File(originalPath);
        
        try {
          // ファイルが存在するか確認
          if (!await file.exists()) {
            debugPrint('⚠️ File not found: $originalPath');
            newPaths.add(originalPath); // パスをそのまま保持
            failedCount++;
            continue;
          }
          
          // 元のファイルサイズを取得
          final originalSize = await file.length();
          
          // ファイル名から拡張子を取得
          final fileName = originalPath.split('/').last;
          onProgress(processedCount, totalImages, fileName);
          
          // 既に圧縮済みか確認（ファイルサイズで判断）
          if (originalSize < 500 * 1024) { // 500KB以下なら既に圧縮済み
            debugPrint('✅ Already compressed: $fileName (${(originalSize / 1024).toStringAsFixed(1)}KB)');
            newPaths.add(originalPath);
            successCount++;
            continue;
          }
          
          // Day 5: 安全な圧縮（一時ファイル経由）
          debugPrint('🗜️ Compressing: $fileName (${(originalSize / 1024 / 1024).toStringAsFixed(1)}MB)');
          
          // 1. 一時ファイルに圧縮（targetPathを指定しない）
          final tempCompressedPath = await ImageCompressionService.compressForGemini(originalPath);
          
          // 2. 圧縮後のサイズを取得
          final compressedSize = await File(tempCompressedPath).length();
          final saved = originalSize - compressedSize;
          savedBytes += saved;
          
          debugPrint('✅ Compressed: $fileName - ${(originalSize / 1024).toStringAsFixed(1)}KB → ${(compressedSize / 1024).toStringAsFixed(1)}KB (${(saved / 1024).toStringAsFixed(1)}KB saved)');
          
          // 3. 圧縮成功後に元ファイルを削除
          try {
            await file.delete();
            debugPrint('🗑️ Deleted original: $originalPath');
          } catch (e) {
            debugPrint('⚠️ Failed to delete original: $e');
            // エラー時は一時ファイルを削除して元のパスを保持
            await File(tempCompressedPath).delete();
            newPaths.add(originalPath);
            failedCount++;
            continue;
          }
          
          // 4. 一時ファイルを元の場所に移動
          try {
            await File(tempCompressedPath).rename(originalPath);
            debugPrint('📦 Moved compressed file to: $originalPath');
          } catch (e) {
            debugPrint('⚠️ Failed to rename file: $e');
            // エラー時は一時ファイルをそのまま使用
            newPaths.add(tempCompressedPath);
            failedCount++;
            continue;
          }
          
          newPaths.add(originalPath);
          successCount++;
          
        } catch (e) {
          debugPrint('❌ Failed to compress: $originalPath - $e');
          newPaths.add(originalPath); // エラー時は元のパスを保持
          failedCount++;
        }
      }
      
      // SakeItem の imagePaths を更新
      if (newPaths.isNotEmpty) {
        final updatedItem = item.copyWith(
          imagePaths: newPaths,
        );
        await box.put(item.key, updatedItem);
      }
    }
    
    return (successCount, failedCount, savedBytes);
  }
  
  /// ストレージ使用量を取得
  /// 
  /// 戻り値: (総ファイル数, 総バイト数)
  static Future<(int, int)> getStorageUsage() async {
    final box = Hive.box<SakeItem>('sake_items');
    final allItems = box.values.toList();
    
    int totalFiles = 0;
    int totalBytes = 0;
    
    for (final item in allItems) {
      for (final path in item.displayData.imagePaths) {
        final file = File(path);
        if (await file.exists()) {
          totalFiles++;
          totalBytes += await file.length();
        }
      }
    }
    
    return (totalFiles, totalBytes);
  }
  
  /// 一時ファイルをクリーンアップ
  /// 
  /// 🔒 Safe: getTemporaryDirectory() のみをスキャン（永続ファイルは削除しない）
  /// 
  /// 戻り値: (削除したファイル数, 削減したバイト数)
  static Future<(int, int)> cleanupTempFiles() async {
    try {
      // ⚠️ 重要: getTemporaryDirectory() を使用（getApplicationDocumentsDirectory() ではない）
      final directory = await getTemporaryDirectory();
      final dir = Directory(directory.path);
      
      int deletedCount = 0;
      int deletedBytes = 0;
      
      // ディレクトリ内のすべてのファイルをスキャン
      await for (final entity in dir.list()) {
        if (entity is File) {
          final fileName = entity.path.split('/').last;
          
          // 一時ファイルを検出（画像ファイルのみ）
          if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png')) {
            try {
              final fileSize = await entity.length();
              await entity.delete();
              deletedCount++;
              deletedBytes += fileSize;
              debugPrint('🗑️ Deleted temp file: $fileName (${(fileSize / 1024).toStringAsFixed(1)}KB)');
            } catch (e) {
              debugPrint('⚠️ Failed to delete temp file: $fileName - $e');
            }
          }
        }
      }
      
      debugPrint('✅ Cleanup complete: $deletedCount files, ${(deletedBytes / 1024 / 1024).toStringAsFixed(1)}MB');
      
      return (deletedCount, deletedBytes);
    } catch (e) {
      debugPrint('❌ Cleanup error: $e');
      return (0, 0);
    }
  }
}
