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

/// 画像パス修復サービス
/// 
/// バックアップ復元後に画像パスが不整合になった場合の修復
class ImagePathRepairService {
  /// 画像パスの整合性をチェック
  /// 
  /// 戻り値: (総アイテム数, 問題のあるアイテム数, 欠損ファイル数)
  static Future<(int, int, int)> diagnose() async {
    try {
      final box = Hive.box<SakeItem>('sake_items');
      final items = box.values.toList();
      
      int totalItems = items.length;
      int problematicItems = 0;
      int missingFiles = 0;
      
      debugPrint('🔍 画像パス診断開始: $totalItems アイテム');
      
      for (final item in items) {
        bool hasIssue = false;
        
        for (final imagePath in item.displayData.imagePaths) {
          final file = File(imagePath);
          if (!await file.exists()) {
            debugPrint('❌ Missing: $imagePath (${item.displayData.displayName})');
            missingFiles++;
            hasIssue = true;
          }
        }
        
        if (hasIssue) {
          problematicItems++;
        }
      }
      
      debugPrint('📊 診断結果: $totalItems アイテム中 $problematicItems に問題あり ($missingFiles ファイル欠損)');
      
      return (totalItems, problematicItems, missingFiles);
    } catch (e) {
      debugPrint('❌ 診断エラー: $e');
      return (0, 0, 0);
    }
  }
  
  /// 画像パスを修復
  /// 
  /// 戦略:
  /// 1. 存在しないパスを検出
  /// 2. getApplicationDocumentsDirectory() 内の実際のファイルを探す
  /// 3. ファイル名（UUID）で照合
  /// 4. パスを更新
  /// 
  /// 戻り値: (修復したアイテム数, 修復した画像パス数)
  static Future<(int, int)> repair() async {
    try {
      final box = Hive.box<SakeItem>('sake_items');
      final items = box.values.toList();
      final appDir = await getApplicationDocumentsDirectory();
      
      // アプリディレクトリ内のすべての画像ファイルを取得
      final availableFiles = <String>[];
      final dir = Directory(appDir.path);
      await for (final entity in dir.list()) {
        if (entity is File) {
          final fileName = path.basename(entity.path);
          if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png')) {
            availableFiles.add(entity.path);
          }
        }
      }
      
      debugPrint('📁 利用可能な画像ファイル: ${availableFiles.length}個');
      
      int repairedItems = 0;
      int repairedPaths = 0;
      
      for (final item in items) {
        bool needsRepair = false;
        List<String> newPaths = [];
        
        for (final oldPath in item.displayData.imagePaths) {
          final file = File(oldPath);
          
          if (await file.exists()) {
            // パスが有効な場合はそのまま
            newPaths.add(oldPath);
          } else {
            // パスが無効な場合、ファイル名で照合
            final oldFileName = path.basename(oldPath);
            
            // 完全一致を探す
            String? matchedPath;
            for (final availablePath in availableFiles) {
              if (path.basename(availablePath) == oldFileName) {
                matchedPath = availablePath;
                break;
              }
            }
            
            if (matchedPath != null) {
              newPaths.add(matchedPath);
              repairedPaths++;
              needsRepair = true;
              debugPrint('🔧 Repaired: $oldFileName -> $matchedPath');
            } else {
              // マッチしない場合、警告してスキップ
              debugPrint('⚠️ No match for: $oldFileName (${item.displayData.displayName})');
            }
          }
        }
        
        if (needsRepair && newPaths.isNotEmpty) {
          // パスを更新
          final updatedItem = item.copyWith(
            imagePaths: newPaths,
          );
          await box.put(item.key, updatedItem); // 🔧 Fixed: updatedItem を保存
          repairedItems++;
          debugPrint('✅ Updated: ${item.displayData.displayName} (${newPaths.length} paths)');
        }
      }
      
      debugPrint('✅ 修復完了: $repairedItems アイテム、$repairedPaths パス');
      
      return (repairedItems, repairedPaths);
    } catch (e) {
      debugPrint('❌ 修復エラー: $e');
      return (0, 0);
    }
  }
  
  /// 孤立したファイルを検出（Hiveに参照されていない画像ファイル）
  /// 
  /// 戻り値: (孤立ファイル数, 合計サイズ(bytes))
  static Future<(int, int)> findOrphanedFiles() async {
    try {
      final box = Hive.box<SakeItem>('sake_items');
      final items = box.values.toList();
      final appDir = await getApplicationDocumentsDirectory();
      
      // Hiveに登録されているすべての画像パスを収集
      final registeredPaths = <String>{};
      for (final item in items) {
        registeredPaths.addAll(item.displayData.imagePaths);
      }
      
      // アプリディレクトリ内のすべての画像ファイルを取得
      int orphanedCount = 0;
      int totalSize = 0;
      
      final dir = Directory(appDir.path);
      await for (final entity in dir.list()) {
        if (entity is File) {
          final fileName = path.basename(entity.path);
          if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png')) {
            if (!registeredPaths.contains(entity.path)) {
              final size = await entity.length();
              orphanedCount++;
              totalSize += size;
              debugPrint('🗑️ Orphaned: $fileName (${(size / 1024).toStringAsFixed(1)}KB)');
            }
          }
        }
      }
      
      debugPrint('📊 孤立ファイル: $orphanedCount 個 (${(totalSize / 1024 / 1024).toStringAsFixed(1)}MB)');
      
      return (orphanedCount, totalSize);
    } catch (e) {
      debugPrint('❌ 孤立ファイル検出エラー: $e');
      return (0, 0);
    }
  }
  
  /// 孤立ファイルを削除
  /// 
  /// 戻り値: (削除したファイル数, 削減したサイズ(bytes))
  static Future<(int, int)> cleanOrphanedFiles() async {
    try {
      final box = Hive.box<SakeItem>('sake_items');
      final items = box.values.toList();
      final appDir = await getApplicationDocumentsDirectory();
      
      // Hiveに登録されているすべての画像パスを収集
      final registeredPaths = <String>{};
      for (final item in items) {
        registeredPaths.addAll(item.displayData.imagePaths);
      }
      
      // アプリディレクトリ内のすべての画像ファイルを取得
      int deletedCount = 0;
      int deletedSize = 0;
      
      final dir = Directory(appDir.path);
      await for (final entity in dir.list()) {
        if (entity is File) {
          final fileName = path.basename(entity.path);
          if (fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png')) {
            if (!registeredPaths.contains(entity.path)) {
              final size = await entity.length();
              await entity.delete();
              deletedCount++;
              deletedSize += size;
              debugPrint('🗑️ Deleted: $fileName (${(size / 1024).toStringAsFixed(1)}KB)');
            }
          }
        }
      }
      
      debugPrint('✅ 孤立ファイル削除完了: $deletedCount 個 (${(deletedSize / 1024 / 1024).toStringAsFixed(1)}MB)');
      
      return (deletedCount, deletedSize);
    } catch (e) {
      debugPrint('❌ 孤立ファイル削除エラー: $e');
      return (0, 0);
    }
  }
}
