import Foundation
import ImageIO
import SwiftUI
import UIKit

class ImageManager {
    static let shared = ImageManager()
    private let logTag = "ImageManager"

    private let thumbnailCache = NSCache<NSString, UIImage>()
    private let fileManager = FileManager.default
    private let appSupportDirectoryName = "Ascently"
    private let imagesDirectoryName = "Images"
    private let backupDirectoryName = "ImageBackups"
    private let migrationStateFile = "migration_state.json"
    private let migrationLockFile = "migration.lock"

    // Legacy directory name for migration
    private let legacyAppSupportDirectoryName = "OpenClimb"

    private init() {
        migrateFromOpenClimbDirectoryIfNeeded()
        createDirectoriesIfNeeded()

        // Debug-safe initialization with extra checks
        let recoveryPerformed = debugSafeInitialization()

        if !recoveryPerformed {
            performRobustMigration()
        }

        // Final integrity check
        if !validateStorageIntegrity() {
            logError("CRITICAL: Storage integrity compromised - attempting emergency recovery")
            emergencyImageRestore()
        }

        logDirectoryInfo()
    }

    var appSupportDirectory: URL {
        let urls = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)
        return urls.first!.appendingPathComponent(appSupportDirectoryName)
    }

    var imagesDirectory: URL {
        appSupportDirectory.appendingPathComponent(imagesDirectoryName)
    }

    var backupDirectory: URL {
        appSupportDirectory.appendingPathComponent(backupDirectoryName)
    }

    func getImagesDirectoryPath() -> String {
        return imagesDirectory.path
    }

    private var legacyDocumentsDirectory: URL {
        fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
    }

    var legacyImagesDirectory: URL {
        legacyDocumentsDirectory.appendingPathComponent("OpenClimbImages")
    }

    /// Legacy OpenClimb app support directory for migration
    private var legacyOpenClimbAppSupportDirectory: URL? {
        guard
            let appSupportBase = fileManager.urls(
                for: .applicationSupportDirectory, in: .userDomainMask
            ).first
        else {
            return nil
        }
        return appSupportBase.appendingPathComponent(legacyAppSupportDirectoryName)
    }

    /// Migrate images from OpenClimb directory to Ascently directory
    private func migrateFromOpenClimbDirectoryIfNeeded() {
        guard let legacyDir = legacyOpenClimbAppSupportDirectory,
            fileManager.fileExists(atPath: legacyDir.path),
            !fileManager.fileExists(atPath: appSupportDirectory.path)
        else {
            return
        }

        logInfo("🔄 Migrating images from OpenClimb to Ascently directory...")

        do {
            // Create parent directory if needed
            try fileManager.createDirectory(
                at: appSupportDirectory.deletingLastPathComponent(),
                withIntermediateDirectories: true,
                attributes: nil)

            // Move the entire directory
            try fileManager.moveItem(at: legacyDir, to: appSupportDirectory)
            logInfo("Successfully migrated image directory from OpenClimb to Ascently")
        } catch {
            logError("Failed to migrate image directory: \(error)")
            // If move fails, try to copy instead
            do {
                try fileManager.copyItem(at: legacyDir, to: appSupportDirectory)
                logInfo("Successfully copied image directory from OpenClimb to Ascently")
                // Don't remove the old directory in case of issues
            } catch {
                logError("Failed to copy image directory: \(error)")
            }
        }
    }

    var legacyImportImagesDirectory: URL {
        legacyDocumentsDirectory.appendingPathComponent("images")
    }

    private func createDirectoriesIfNeeded() {
        // Create Application Support structure
        [appSupportDirectory, imagesDirectory, backupDirectory].forEach { directory in
            if !fileManager.fileExists(atPath: directory.path) {
                do {
                    try fileManager.createDirectory(
                        at: directory, withIntermediateDirectories: true,
                        attributes: [
                            .protectionKey: FileProtectionType.completeUntilFirstUserAuthentication
                        ])
                    logInfo("Created directory: \(directory.path)")
                } catch {
                    logError("ERROR: Failed to create directory \(directory.path): \(error)")
                }
            }
        }

        // Exclude from iCloud backup to prevent storage issues
        excludeFromiCloudBackup()
    }

    private func excludeFromiCloudBackup() {
        do {
            var resourceValues = URLResourceValues()
            resourceValues.isExcludedFromBackup = true
            var imagesURL = imagesDirectory
            var backupURL = backupDirectory
            try imagesURL.setResourceValues(resourceValues)
            try backupURL.setResourceValues(resourceValues)
            logInfo("Excluded image directories from iCloud backup")
        } catch {
            logWarning("WARNING: Failed to exclude from iCloud backup: \(error)")
        }
    }

    private struct MigrationState: Codable {
        let version: Int
        let startTime: Date
        let completedFiles: [String]
        let totalFiles: Int
        let isComplete: Bool
        let lastCheckpoint: Date

        static let currentVersion = 2
    }

    private var migrationStateURL: URL {
        appSupportDirectory.appendingPathComponent(migrationStateFile)
    }

    private var migrationLockURL: URL {
        appSupportDirectory.appendingPathComponent(migrationLockFile)
    }

    private func performRobustMigration() {
        logInfo("Starting robust image migration system...")

        // Check for interrupted migration
        if let incompleteState = loadMigrationState() {
            logInfo("Detected interrupted migration, resuming...")
            resumeMigration(from: incompleteState)
        } else {
            // Start fresh migration
            startNewMigration()
        }

        // Always verify migration integrity
        verifyMigrationIntegrity()

        // Clean up migration state files
        cleanupMigrationState()
    }

    private func startNewMigration() {
        // First check for images in previous Application Support directories
        if let previousAppSupportImages = findPreviousAppSupportImages() {
            logInfo("Found images in previous Application Support directory")
            migratePreviousAppSupportImages(from: previousAppSupportImages)
            return
        }

        // Check if legacy directories exist
        let hasLegacyImages = fileManager.fileExists(atPath: legacyImagesDirectory.path)
        let hasLegacyImportImages = fileManager.fileExists(atPath: legacyImportImagesDirectory.path)

        guard hasLegacyImages || hasLegacyImportImages else {
            logInfo("No legacy images to migrate")
            return
        }

        // Create migration lock
        createMigrationLock()

        do {
            var allLegacyFiles: [String] = []

            // Collect files from OpenClimbImages directory
            if fileManager.fileExists(atPath: legacyImagesDirectory.path) {
                let legacyFiles = try fileManager.contentsOfDirectory(
                    atPath: legacyImagesDirectory.path)
                allLegacyFiles.append(contentsOf: legacyFiles)
                logInfo("Found \(legacyFiles.count) images in OpenClimbImages")
            }

            // Collect files from Documents/images directory
            if fileManager.fileExists(atPath: legacyImportImagesDirectory.path) {
                let importFiles = try fileManager.contentsOfDirectory(
                    atPath: legacyImportImagesDirectory.path)
                allLegacyFiles.append(contentsOf: importFiles)
                logInfo("Found \(importFiles.count) images in Documents/images")
            }

            logInfo("Total legacy images to migrate: \(allLegacyFiles.count)")

            let initialState = MigrationState(
                version: MigrationState.currentVersion,
                startTime: Date(),
                completedFiles: [],
                totalFiles: allLegacyFiles.count,
                isComplete: false,
                lastCheckpoint: Date()
            )

            saveMigrationState(initialState)
            performMigrationWithCheckpoints(files: allLegacyFiles, currentState: initialState)
        } catch {
            logError("ERROR: Failed to start migration: \(error)")
        }
    }

    private func resumeMigration(from state: MigrationState) {
        logInfo("Resuming migration from checkpoint...")
        logInfo("Progress: \(state.completedFiles.count)/\(state.totalFiles)")

        do {
            let legacyFiles = try fileManager.contentsOfDirectory(
                atPath: legacyImagesDirectory.path)
            let remainingFiles = legacyFiles.filter { !state.completedFiles.contains($0) }

            logInfo("Resuming with \(remainingFiles.count) remaining files")
            performMigrationWithCheckpoints(files: remainingFiles, currentState: state)
        } catch {
            logError("ERROR: Failed to resume migration: \(error)")
            // Fallback: start fresh
            removeMigrationState()
            startNewMigration()
        }
    }

    private func performMigrationWithCheckpoints(files: [String], currentState: MigrationState) {
        var migratedCount = currentState.completedFiles.count
        var failedCount = 0
        var completedFiles = currentState.completedFiles

        for (index, fileName) in files.enumerated() {
            autoreleasepool {
                // Check both legacy directories for the file
                var legacyFilePath: URL?
                if fileManager.fileExists(
                    atPath: legacyImagesDirectory.appendingPathComponent(fileName).path)
                {
                    legacyFilePath = legacyImagesDirectory.appendingPathComponent(fileName)
                } else if fileManager.fileExists(
                    atPath: legacyImportImagesDirectory.appendingPathComponent(fileName).path)
                {
                    legacyFilePath = legacyImportImagesDirectory.appendingPathComponent(fileName)
                }

                guard let sourcePath = legacyFilePath else {
                    completedFiles.append(fileName)
                    return
                }

                let newFilePath = imagesDirectory.appendingPathComponent(fileName)
                let backupPath = backupDirectory.appendingPathComponent(fileName)

                // Skip if already exists in new location
                if fileManager.fileExists(atPath: newFilePath.path) {
                    completedFiles.append(fileName)
                    return
                }

                do {
                    // Atomic migration: copy to temp, then move
                    let tempFilePath = newFilePath.appendingPathExtension("tmp")

                    // Copy to temp location first
                    try fileManager.copyItem(at: sourcePath, to: tempFilePath)

                    // Verify file integrity
                    let originalData = try Data(contentsOf: sourcePath)
                    let copiedData = try Data(contentsOf: tempFilePath)

                    guard originalData == copiedData else {
                        try? fileManager.removeItem(at: tempFilePath)
                        throw NSError(
                            domain: "MigrationError", code: 1,
                            userInfo: [NSLocalizedDescriptionKey: "File integrity check failed"])
                    }

                    // Move from temp to final location
                    try fileManager.moveItem(at: tempFilePath, to: newFilePath)

                    // Create backup copy
                    try? fileManager.copyItem(at: newFilePath, to: backupPath)

                    completedFiles.append(fileName)
                    migratedCount += 1

                    logInfo("Migrated: \(fileName) (\(migratedCount)/\(currentState.totalFiles))")
                } catch {
                    failedCount += 1
                    logError("ERROR: Failed to migrate \(fileName): \(error)")
                }

                // Save checkpoint every 5 files or if interrupted
                if (index + 1) % 5 == 0 {
                    let checkpointState = MigrationState(
                        version: MigrationState.currentVersion,
                        startTime: currentState.startTime,
                        completedFiles: completedFiles,
                        totalFiles: currentState.totalFiles,
                        isComplete: false,
                        lastCheckpoint: Date()
                    )
                    saveMigrationState(checkpointState)
                    logInfo("Checkpoint saved: \(completedFiles.count)/\(currentState.totalFiles)")
                }
            }
        }

        // Mark migration as complete
        let finalState = MigrationState(
            version: MigrationState.currentVersion,
            startTime: currentState.startTime,
            completedFiles: completedFiles,
            totalFiles: currentState.totalFiles,
            isComplete: true,
            lastCheckpoint: Date()
        )
        saveMigrationState(finalState)

        logInfo("Migration complete: \(migratedCount) migrated, \(failedCount) failed")

        // Clean up legacy directory if no failures
        if failedCount == 0 {
            cleanupLegacyDirectory()
        }
    }

    private func verifyMigrationIntegrity() {
        logInfo("Verifying migration integrity...")

        var allLegacyFiles = Set<String>()

        // Collect files from both legacy directories
        do {
            if fileManager.fileExists(atPath: legacyImagesDirectory.path) {
                let legacyFiles = Set(
                    try fileManager.contentsOfDirectory(atPath: legacyImagesDirectory.path))
                allLegacyFiles.formUnion(legacyFiles)
            }

            if fileManager.fileExists(atPath: legacyImportImagesDirectory.path) {
                let importFiles = Set(
                    try fileManager.contentsOfDirectory(atPath: legacyImportImagesDirectory.path))
                allLegacyFiles.formUnion(importFiles)
            }
        } catch {
            logError("ERROR: Failed to read legacy directories: \(error)")
            return
        }

        guard !allLegacyFiles.isEmpty else {
            logInfo("No legacy directories to verify against")
            return
        }

        do {
            let migratedFiles = Set(
                try fileManager.contentsOfDirectory(atPath: imagesDirectory.path))

            let missingFiles = allLegacyFiles.subtracting(migratedFiles)

            if missingFiles.isEmpty {
                logInfo("Migration integrity verified - all files present")
                cleanupLegacyDirectory()
            } else {
                logWarning("WARNING: Missing \(missingFiles.count) files, re-triggering migration")
                // Re-trigger migration for missing files
                performMigrationWithCheckpoints(
                    files: Array(missingFiles),
                    currentState: MigrationState(
                        version: MigrationState.currentVersion,
                        startTime: Date(),
                        completedFiles: [],
                        totalFiles: missingFiles.count,
                        isComplete: false,
                        lastCheckpoint: Date()
                    ))
            }
        } catch {
            logError("ERROR: Failed to verify migration integrity: \(error)")
        }
    }

    private func cleanupLegacyDirectory() {
        do {
            try fileManager.removeItem(at: legacyImagesDirectory)
            logInfo("Cleaned up legacy directory")
        } catch {
            logWarning("WARNING: Failed to clean up legacy directory: \(error)")
        }
    }

    private func loadMigrationState() -> MigrationState? {
        guard fileManager.fileExists(atPath: migrationStateURL.path) else {
            return nil
        }

        // Check if migration was interrupted (lock file exists)
        if !fileManager.fileExists(atPath: migrationLockURL.path) {
            // Migration completed normally, clean up state
            removeMigrationState()
            return nil
        }

        do {
            let data = try Data(contentsOf: migrationStateURL)
            let state = try JSONDecoder().decode(MigrationState.self, from: data)

            // Check if state is too old
            if Date().timeIntervalSince(state.lastCheckpoint) > 3600 {
                logWarning("WARNING: Migration state is stale, starting fresh")
                removeMigrationState()
                return nil
            }

            return state.isComplete ? nil : state
        } catch {
            logError("ERROR: Failed to load migration state: \(error)")
            removeMigrationState()
            return nil
        }
    }

    private func saveMigrationState(_ state: MigrationState) {
        do {
            let data = try JSONEncoder().encode(state)
            try data.write(to: migrationStateURL)
        } catch {
            logError("ERROR: Failed to save migration state: \(error)")
        }
    }

    private func removeMigrationState() {
        try? fileManager.removeItem(at: migrationStateURL)
    }

    private func createMigrationLock() {
        let lockData = "Migration in progress - \(Date())".data(using: .utf8) ?? Data()
        try? lockData.write(to: migrationLockURL)
    }

    private func cleanupMigrationState() {
        try? fileManager.removeItem(at: migrationStateURL)
        try? fileManager.removeItem(at: migrationLockURL)
        logInfo("Cleaned up migration state files")
    }

    func saveImageData(_ data: Data, withName name: String? = nil) -> String? {
        let fileName = name ?? "\(UUID().uuidString).jpg"
        let primaryPath = imagesDirectory.appendingPathComponent(fileName)
        let backupPath = backupDirectory.appendingPathComponent(fileName)

        do {
            // Save to primary location
            try data.write(to: primaryPath)

            // Create backup copy
            try data.write(to: backupPath)

            logInfo("Saved image with backup: \(fileName)")
            return fileName
        } catch {
            logError("ERROR: Failed to save image \(fileName): \(error)")
            return nil
        }
    }

    func loadImageData(fromPath path: String) -> Data? {
        let primaryPath = getFullPath(from: path)
        let backupPath = backupDirectory.appendingPathComponent(getRelativePath(from: path))

        // Try primary location first
        if fileManager.fileExists(atPath: primaryPath),
            let data = try? Data(contentsOf: URL(fileURLWithPath: primaryPath))
        {
            return data
        }

        // Fallback to backup location
        if fileManager.fileExists(atPath: backupPath.path),
            let data = try? Data(contentsOf: backupPath)
        {
            logInfo("Restored image from backup: \(path)")

            // Restore to primary location
            try? data.write(to: URL(fileURLWithPath: primaryPath))

            return data
        }

        return nil
    }

    func loadThumbnail(fromPath path: String, targetSize: CGSize) async -> UIImage? {
        let cacheKey = "\(path)-\(targetSize.width)x\(targetSize.height)" as NSString

        if let cachedImage = thumbnailCache.object(forKey: cacheKey) {
            return cachedImage
        }

        guard let imageData = loadImageData(fromPath: path) else {
            return nil
        }

        let options: [CFString: Any] = [
            kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
            kCGImageSourceCreateThumbnailWithTransform: true,
            kCGImageSourceShouldCacheImmediately: true,
            kCGImageSourceThumbnailMaxPixelSize: max(targetSize.width, targetSize.height)
                * UIScreen.main.scale,
        ]

        guard let imageSource = CGImageSourceCreateWithData(imageData as CFData, nil) else {
            return UIImage(data: imageData)
        }

        let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [CFString: Any]
        let orientation = properties?[kCGImagePropertyOrientation] as? UInt32 ?? 1

        if let cgImage = CGImageSourceCreateThumbnailAtIndex(
            imageSource, 0, options as CFDictionary)
        {
            let imageOrientation = UIImage.Orientation(rawValue: Int(orientation - 1)) ?? .up
            let thumbnail = UIImage(
                cgImage: cgImage, scale: UIScreen.main.scale, orientation: imageOrientation)

            thumbnailCache.setObject(thumbnail, forKey: cacheKey)
            return thumbnail
        } else {
            if let fallbackImage = UIImage(data: imageData) {
                thumbnailCache.setObject(fallbackImage, forKey: cacheKey)
                return fallbackImage
            }
        }

        return nil
    }

    func imageExists(atPath path: String) -> Bool {
        let primaryPath = getFullPath(from: path)
        let backupPath = backupDirectory.appendingPathComponent(getRelativePath(from: path))

        return fileManager.fileExists(atPath: primaryPath)
            || fileManager.fileExists(atPath: backupPath.path)
    }

    func deleteImage(atPath path: String) -> Bool {
        let primaryPath = getFullPath(from: path)
        let backupPath = backupDirectory.appendingPathComponent(getRelativePath(from: path))

        var success = true

        // Delete from primary location
        if fileManager.fileExists(atPath: primaryPath) {
            do {
                try fileManager.removeItem(atPath: primaryPath)
            } catch {
                logError("ERROR: Failed to delete primary image at \(primaryPath): \(error)")
                success = false
            }
        }

        // Delete from backup location
        if fileManager.fileExists(atPath: backupPath.path) {
            do {
                try fileManager.removeItem(at: backupPath)
            } catch {
                logError("ERROR: Failed to delete backup image at \(backupPath.path): \(error)")
                success = false
            }
        }

        return success
    }

    func deleteImages(atPaths paths: [String]) {
        for path in paths {
            _ = deleteImage(atPath: path)
        }
    }

    func getFullPath(from relativePath: String) -> String {
        // If it's already a full path, check if it's legacy and needs migration
        if relativePath.hasPrefix("/") {
            // If it's pointing to legacy Documents directory, redirect to new location
            if relativePath.contains("Documents/OpenClimbImages") {
                let fileName = URL(fileURLWithPath: relativePath).lastPathComponent
                return imagesDirectory.appendingPathComponent(fileName).path
            }
            return relativePath
        }

        // For relative paths, use the persistent Application Support location
        return imagesDirectory.appendingPathComponent(relativePath).path
    }

    func getRelativePath(from fullPath: String) -> String {
        if !fullPath.hasPrefix("/") {
            return fullPath
        }
        return URL(fileURLWithPath: fullPath).lastPathComponent
    }

    func performMaintenance() {
        logInfo("Starting image maintenance...")

        syncBackups()
        validateImageIntegrity()
        cleanupOrphanedFiles()
    }

    private func syncBackups() {
        do {
            let primaryFiles = try fileManager.contentsOfDirectory(atPath: imagesDirectory.path)
            let backupFiles = Set(try fileManager.contentsOfDirectory(atPath: backupDirectory.path))

            for fileName in primaryFiles {
                if !backupFiles.contains(fileName) {
                    let primaryPath = imagesDirectory.appendingPathComponent(fileName)
                    let backupPath = backupDirectory.appendingPathComponent(fileName)

                    try? fileManager.copyItem(at: primaryPath, to: backupPath)
                    logInfo("Created missing backup for: \(fileName)")
                }
            }
        } catch {
            logError("ERROR: Failed to sync backups: \(error)")
        }
    }

    private func validateImageIntegrity() {
        do {
            let files = try fileManager.contentsOfDirectory(atPath: imagesDirectory.path)
            var validFiles = 0

            for fileName in files {
                let filePath = imagesDirectory.appendingPathComponent(fileName)
                if let data = try? Data(contentsOf: filePath), !data.isEmpty {
                    // Basic validation - check if file has content and is reasonable size
                    if data.count > 100 {  // Minimum viable image size
                        validFiles += 1
                    }
                }
            }

            logInfo("Validated \(validFiles) of \(files.count) image files")
        } catch {
            logError("ERROR: Failed to validate images: \(error)")
        }
    }

    private func cleanupOrphanedFiles() {
        logInfo("Cleanup would require coordination with data manager")
    }

    func getStorageInfo() -> (primaryCount: Int, backupCount: Int, totalSize: Int64) {
        let primaryCount =
            ((try? fileManager.contentsOfDirectory(atPath: imagesDirectory.path)) ?? []).count
        let backupCount =
            ((try? fileManager.contentsOfDirectory(atPath: backupDirectory.path)) ?? []).count

        var totalSize: Int64 = 0
        [imagesDirectory, backupDirectory].forEach { directory in
            if let enumerator = fileManager.enumerator(
                at: directory, includingPropertiesForKeys: [.fileSizeKey])
            {
                for case let url as URL in enumerator {
                    if let size = try? url.resourceValues(forKeys: [.fileSizeKey]).fileSize {
                        totalSize += Int64(size)
                    }
                }
            }
        }

        return (primaryCount, backupCount, totalSize)
    }

    private func logDirectoryInfo() {
        let info = getStorageInfo()
        let previousDir = findPreviousAppSupportImages()
        logInfo(
            """
            Ascently Image Storage:
            - App Support: \(appSupportDirectory.path)
            - Images: \(imagesDirectory.path) (\(info.primaryCount) files)
            - Backups: \(backupDirectory.path) (\(info.backupCount) files)
            - Previous Dir: \(previousDir?.path ?? "None found")
            - Legacy Dir: \(legacyImagesDirectory.path) (exists: \(fileManager.fileExists(atPath: legacyImagesDirectory.path)))
            - Legacy Import Dir: \(legacyImportImagesDirectory.path) (exists: \(fileManager.fileExists(atPath: legacyImportImagesDirectory.path)))
            - Total Size: \(info.totalSize / 1024)KB
            """)
    }

    func forceRecoveryMigration() {
        logInfo("FORCE RECOVERY: Starting manual migration recovery...")

        // Remove any stale state
        removeMigrationState()
        try? fileManager.removeItem(at: migrationLockURL)

        // Force fresh migration
        startNewMigration()

        logInfo("FORCE RECOVERY: Migration recovery completed")
    }

    func saveImportedImage(_ imageData: Data, filename: String) throws -> String {
        let imagePath = imagesDirectory.appendingPathComponent(filename)
        let backupPath = backupDirectory.appendingPathComponent(filename)

        // Save to main directory
        try imageData.write(to: imagePath)

        // Create backup
        try? imageData.write(to: backupPath)

        logInfo("Imported image: \(filename)")
        return filename
    }

    func emergencyImageRestore() {
        logError("EMERGENCY: Attempting image restoration...")

        // Try to restore from backup directory
        do {
            let backupFiles = try fileManager.contentsOfDirectory(atPath: backupDirectory.path)
            var restoredCount = 0

            for fileName in backupFiles {
                let backupPath = backupDirectory.appendingPathComponent(fileName)
                let primaryPath = imagesDirectory.appendingPathComponent(fileName)

                // Only restore if primary doesn't exist
                if !fileManager.fileExists(atPath: primaryPath.path) {
                    try? fileManager.copyItem(at: backupPath, to: primaryPath)
                    restoredCount += 1
                }
            }

            logError("EMERGENCY: Restored \(restoredCount) images from backup")
        } catch {
            logError("EMERGENCY: Failed to restore from backup: \(error)")
        }

        // Try previous Application Support directories first
        if let previousAppSupportImages = findPreviousAppSupportImages() {
            logError("EMERGENCY: Found previous Application Support images, migrating...")
            migratePreviousAppSupportImages(from: previousAppSupportImages)
            return
        }

        // Try legacy migration as last resort
        if fileManager.fileExists(atPath: legacyImagesDirectory.path)
            || fileManager.fileExists(atPath: legacyImportImagesDirectory.path)
        {
            logError("EMERGENCY: Attempting legacy migration as fallback...")
            forceRecoveryMigration()
        }
    }

    func debugSafeInitialization() -> Bool {
        logDebug("DEBUG SAFE: Performing debug-safe initialization check...")

        // Check if we're in a debug environment
        #if DEBUG
            logDebug("DEBUG SAFE: Debug environment detected")

            if fileManager.fileExists(atPath: migrationLockURL.path) {
                logDebug("DEBUG SAFE: Found migration lock - likely debug interruption")

                Thread.sleep(forTimeInterval: 1.0)

                // Try emergency recovery
                emergencyImageRestore()

                // Clean up lock
                try? fileManager.removeItem(at: migrationLockURL)

                return true
            }
        #endif

        // Check if primary storage is empty but backup exists
        let primaryEmpty =
            (try? fileManager.contentsOfDirectory(atPath: imagesDirectory.path).isEmpty) ?? true
        let backupHasFiles =
            !((try? fileManager.contentsOfDirectory(atPath: backupDirectory.path)) ?? []).isEmpty

        if primaryEmpty && backupHasFiles {
            logDebug("DEBUG SAFE: Primary empty but backup exists - restoring")
            emergencyImageRestore()
            return true
        }

        // Check if primary storage is empty but previous Application Support images exist
        if primaryEmpty, let previousAppSupportImages = findPreviousAppSupportImages() {
            logDebug("DEBUG SAFE: Primary empty but found previous Application Support images")
            migratePreviousAppSupportImages(from: previousAppSupportImages)
            return true
        }

        return false
    }

    func validateStorageIntegrity() -> Bool {
        let primaryFiles = Set(
            (try? fileManager.contentsOfDirectory(atPath: imagesDirectory.path)) ?? [])
        let backupFiles = Set(
            (try? fileManager.contentsOfDirectory(atPath: backupDirectory.path)) ?? [])

        // Check if we have more backups than primary files (sign of corruption)
        if backupFiles.count > primaryFiles.count + 5 {
            logInfo(
                "WARNING INTEGRITY: Backup count significantly exceeds primary - potential corruption"
            )
            return false
        }

        // Check if primary is completely empty but we have data elsewhere
        if primaryFiles.isEmpty && !backupFiles.isEmpty {
            logWarning("WARNING INTEGRITY: Primary storage empty but backups exist")
            return false
        }

        return true
    }

    func findPreviousAppSupportImages() -> URL? {
        // Get the Application Support base directory
        guard
            let appSupportBase = fileManager.urls(
                for: .applicationSupportDirectory, in: .userDomainMask
            ).first
        else {
            logError("ERROR: Could not access Application Support directory")
            return nil
        }

        // Look for OpenClimb directories in Application Support
        do {
            let contents = try fileManager.contentsOfDirectory(
                at: appSupportBase, includingPropertiesForKeys: nil)

            for url in contents {
                var isDirectory: ObjCBool = false
                guard fileManager.fileExists(atPath: url.path, isDirectory: &isDirectory),
                    isDirectory.boolValue
                else {
                    continue
                }

                // Check if it's an OpenClimb or Ascently directory but not the current one
                if (url.lastPathComponent.contains("OpenClimb")
                    || url.lastPathComponent.contains("Ascently"))
                    && url.path != appSupportDirectory.path
                {
                    let imagesDir = url.appendingPathComponent(imagesDirectoryName)

                    if fileManager.fileExists(atPath: imagesDir.path) {
                        let imageFiles =
                            (try? fileManager.contentsOfDirectory(atPath: imagesDir.path)) ?? []
                        if !imageFiles.isEmpty {
                            return imagesDir
                        }
                    }
                }
            }
        } catch {
            logError("ERROR: Error scanning for previous Application Support directories: \(error)")
        }
        return nil
    }

    private func migratePreviousAppSupportImages(from sourceDirectory: URL) {
        logInfo("Migrating images from previous Application Support directory")

        do {
            let imageFiles = try fileManager.contentsOfDirectory(atPath: sourceDirectory.path)

            for fileName in imageFiles {
                autoreleasepool {
                    let sourcePath = sourceDirectory.appendingPathComponent(fileName)
                    let destinationPath = imagesDirectory.appendingPathComponent(fileName)
                    let backupPath = backupDirectory.appendingPathComponent(fileName)

                    // Skip if already exists in destination
                    if fileManager.fileExists(atPath: destinationPath.path) {
                        return
                    }

                    do {
                        // Copy to main directory
                        try fileManager.copyItem(at: sourcePath, to: destinationPath)

                        // Create backup
                        try? fileManager.copyItem(at: sourcePath, to: backupPath)

                        logInfo("Migrated: \(fileName)")
                    } catch {
                        logError("ERROR: Failed to migrate \(fileName): \(error)")
                    }
                }
            }

            logInfo("Completed migration from previous Application Support directory")
        } catch {
            logError("ERROR: Failed to migrate from previous Application Support: \(error)")
        }
    }

    private func logInfo(_ message: String) {
        AppLogger.info(message, tag: logTag)
    }

    private func logWarning(_ message: String) {
        AppLogger.warning(message, tag: logTag)
    }

    private func logError(_ message: String) {
        AppLogger.error(message, tag: logTag)
    }

    private func logDebug(_ message: String) {
        AppLogger.debug(message, tag: logTag)
    }
}
