import Foundation
import UIKit

var appGroupID = "group."+Bundle.main.bundleIdentifier.unsafelyUnwrapped.replacing(".iMessage", with:"")

class GIFFileManager {
    static let shared = GIFFileManager()
    
    private init() {
        createGIFsDirectoryIfNeeded()
    }
    
    // MARK: - File Storage
    
    // Always use the App Group container for consistent storage between extensions
    private var documentsDirectory: URL {
        if let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID) {
            return containerURL
        } else {
            // This should only happen if App Group capability is not properly set up
            print("ERROR: App Group container not available. GIFs will not be shared between extensions!")
            
            // Fall back to the app's documents directory if App Group is not available
            let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            return paths[0]
        }
    }
    
    private var gifsDirectory: URL {
        // Use a consistent folder name for GIFs across all extensions
        return documentsDirectory.appendingPathComponent("SharedGIFs", isDirectory: true)
    }
    
    private func createGIFsDirectoryIfNeeded() {
        let fileManager = FileManager.default
        
        if !fileManager.fileExists(atPath: gifsDirectory.path) {
            do {
                try fileManager.createDirectory(at: gifsDirectory, withIntermediateDirectories: true)
                print("Created shared GIFs directory at: \(gifsDirectory.path)")
            } catch {
                print("Error creating shared GIFs directory: \(error)")
            }
        } else {
            print("Using existing shared GIFs directory at: \(gifsDirectory.path)")
        }
    }
    
    func storeGIF(data: Data, fromURL urlString: String) -> String? {
        // Check if this is a shared GIF from the share extension
        if let sharedGIFPath = checkForSharedGIF(withURL: urlString), FileManager.default.fileExists(atPath: sharedGIFPath) {
            return sharedGIFPath
        }
        
        // Create a unique filename based on the URL hash and timestamp
        let urlHash = urlString.hashValue
        let timestamp = Int(Date().timeIntervalSince1970)
        let filename = "gif_\(urlHash)_\(timestamp).gif"
        
        let fileURL = gifsDirectory.appendingPathComponent(filename)
        
        do {
            try data.write(to: fileURL)
            return fileURL.path
        } catch {
            print("Error saving GIF to disk: \(error)")
            return nil
        }
    }
    
    func loadGIFData(from localPath: String) -> Data? {
        let url = URL(fileURLWithPath: localPath)
        
        do {
            let data = try Data(contentsOf: url)
            return data
        } catch {
            print("Error loading GIF from disk: \(error)")
            return nil
        }
    }
    
    func deleteGIF(at localPath: String) -> Bool {
        let fileManager = FileManager.default
        
        do {
            try fileManager.removeItem(atPath: localPath)
            return true
        } catch {
            print("Error deleting GIF from disk: \(error)")
            return false
        }
    }
    
    func fileExists(at localPath: String) -> Bool {
        return FileManager.default.fileExists(atPath: localPath)
    }
    
    func getAllGIFsSize() -> Int64 {
        let fileManager = FileManager.default
        let enumerator = fileManager.enumerator(at: gifsDirectory, includingPropertiesForKeys: [.fileSizeKey])
        
        var totalSize: Int64 = 0
        
        while let fileURL = enumerator?.nextObject() as? URL {
            do {
                let attributes = try fileURL.resourceValues(forKeys: [.fileSizeKey])
                if let fileSize = attributes.fileSize {
                    totalSize += Int64(fileSize)
                }
            } catch {
                print("Error calculating file size: \(error)")
            }
        }
        
        return totalSize
    }
    
    // Clean up old GIFs if storage exceeds 100 MB
    func performStorageCleanupIfNeeded() {
        let maxStorageSize: Int64 = 100 * 1024 * 1024 // 100 MB
        
        if getAllGIFsSize() > maxStorageSize {
            cleanupOldGIFs()
        }
    }
    
    private func cleanupOldGIFs() {
        let fileManager = FileManager.default
        
        do {
            // Get all files and their creation dates
            let fileURLs = try fileManager.contentsOfDirectory(at: gifsDirectory, includingPropertiesForKeys: [.creationDateKey])
            
            // Sort by creation date
            let sortedFiles = try fileURLs.sorted {
                let date1 = try $0.resourceValues(forKeys: [.creationDateKey]).creationDate ?? Date.distantPast
                let date2 = try $1.resourceValues(forKeys: [.creationDateKey]).creationDate ?? Date.distantPast
                return date1 < date2
            }
            
            // Delete the oldest 30% of files
            let filesToDelete = Int(Double(sortedFiles.count) * 0.3)
            
            for i in 0..<min(filesToDelete, sortedFiles.count) {
                try fileManager.removeItem(at: sortedFiles[i])
            }
        } catch {
            print("Error cleaning up old GIFs: \(error)")
        }
    }
    
    // Check if we already have this GIF in the shared container
    private func checkForSharedGIF(withURL urlString: String) -> String? {
        // Use our standard gifsDirectory property instead of recreating the path
        guard FileManager.default.fileExists(atPath: gifsDirectory.path) else {
            return nil
        }
        
        do {
            let fileURLs = try FileManager.default.contentsOfDirectory(at: gifsDirectory, includingPropertiesForKeys: nil)
            
            // Find any shared GIF that matches our URL (usually won't find any, but helps avoid duplicates)
            let userDefaults = UserDefaults(suiteName: appGroupID)
            if let pendingGIFs = userDefaults?.array(forKey: "pendingGIFs") as? [[String: Any]] {
                for gifInfo in pendingGIFs {
                    if let originURL = gifInfo["originalURL"] as? String,
                       let path = gifInfo["localFilePath"] as? String,
                       originURL == urlString {
                        return path
                    }
                }
            }
            
            return nil
        } catch {
            print("Error checking for shared GIFs: \(error)")
            return nil
        }
    }
}
