import Foundation

class GIFStorageService {
    static let shared = GIFStorageService()
    
    // Use constant App Group ID to ensure consistency across targets
    private let userDefaults = UserDefaults(suiteName: appGroupID)
    
    // Use a consistent key for saved GIFs across all extensions
    private let savedGIFsKey = "sharedGIFs"
    private let pendingGIFsKey = "pendingGIFs"
    
    private init() {
        // Make sure the shared UserDefaults exists
        if userDefaults == nil {
            print("ERROR: Could not create UserDefaults with app group. GIFs will not be shared between extensions!")
        } else {
            print("Successfully connected to shared UserDefaults")
        }
        
        // Process any pending GIFs from the Share Extension
        checkForSharedGIFs()
        
        // Log the number of GIFs found
        let count = fetchGIFs().count
        print("Found \(count) GIFs in shared storage")
    }
    
    func saveGIF(data: Data, fromURL urlString: String, completion: @escaping (GIF?) -> Void) {
        // First store the GIF data to disk
        guard let localPath = GIFFileManager.shared.storeGIF(data: data, fromURL: urlString) else {
            completion(nil)
            return
        }
        
        // Create and save the GIF model
        let gif = GIF(localFilePath: localPath, originalURL: urlString)
        
        var savedGIFs = fetchGIFs()
        
        // Don't save duplicates of the same URL
        if !savedGIFs.contains(where: { $0.originalURL == urlString }) {
            savedGIFs.append(gif)
            saveToUserDefaults(gifs: savedGIFs)
        }
        
        // Perform cleanup if needed
        GIFFileManager.shared.performStorageCleanupIfNeeded()
        
        completion(gif)
    }
    
    func fetchGIFs() -> [GIF] {
        guard let userDefaultsInstance = userDefaults else {
            print("ERROR: UserDefaults is nil, cannot fetch GIFs")
            return []
        }
        
        guard let data = userDefaultsInstance.data(forKey: savedGIFsKey) else {
            print("No GIFs data found in UserDefaults for key: \(savedGIFsKey)")
            return []
        }
        
        do {
            let gifs = try JSONDecoder().decode([GIF].self, from: data)
            print("Fetched \(gifs.count) GIFs from shared storage")
            
            // Debug IDs
            if !gifs.isEmpty {
                print("GIF IDs: \(gifs.map { $0.id.uuidString.prefix(8) }.joined(separator: ", "))")
            }
            
            // Filter out any GIFs whose files no longer exist
            let validGIFs = gifs.filter { 
                let exists = GIFFileManager.shared.fileExists(at: $0.localFilePath)
                if !exists {
                    print("Warning: GIF file not found at path: \($0.localFilePath)")
                }
                return exists
            }
            
            // If we filtered any out, save the updated list
            if validGIFs.count != gifs.count {
                print("Removed \(gifs.count - validGIFs.count) invalid GIFs from storage")
                saveToUserDefaults(gifs: validGIFs)
            }
            
            return validGIFs.sorted(by: { $0.createdAt > $1.createdAt })
        } catch {
            print("ERROR: Failed to decode GIFs from UserDefaults: \(error)")
            return []
        }
    }
    
    func deleteGIF(with id: UUID) {
        var savedGIFs = fetchGIFs()
        
        // Find the GIF to delete
        if let gifToDelete = savedGIFs.first(where: { $0.id == id }) {
            print("Deleting GIF with ID: \(id), path: \(gifToDelete.localFilePath)")
            
            // Delete the file from storage
            let fileDeleted = GIFFileManager.shared.deleteGIF(at: gifToDelete.localFilePath)
            if fileDeleted {
                print("Successfully deleted GIF file from storage")
            } else {
                print("Warning: Failed to delete GIF file at path: \(gifToDelete.localFilePath)")
            }
            
            // Remove from the list regardless of whether file deletion succeeded
            let countBefore = savedGIFs.count
            savedGIFs.removeAll(where: { $0.id == id })
            
            if savedGIFs.count < countBefore {
                print("Removed GIF from saved list, count before: \(countBefore), after: \(savedGIFs.count)")
                saveToUserDefaults(gifs: savedGIFs)
            } else {
                print("Error: GIF with ID \(id) was not found in memory array")
            }
        } else {
            print("Error: Could not find GIF with ID \(id) to delete")
        }
    }
    
    func clearAllGIFs() {
        // Delete all GIF files
        fetchGIFs().forEach { gif in
            GIFFileManager.shared.deleteGIF(at: gif.localFilePath)
        }
        
        // Clear the list
        saveToUserDefaults(gifs: [])
    }
    
    private func saveToUserDefaults(gifs: [GIF]) {
        do {
            let data = try JSONEncoder().encode(gifs)
            userDefaults?.set(data, forKey: savedGIFsKey)
            print("Successfully saved \(gifs.count) GIFs to shared storage")
            
            // Force UserDefaults to synchronize to ensure immediate visibility across extensions
            if userDefaults?.synchronize() == true {
                print("UserDefaults successfully synchronized")
            } else {
                print("Warning: UserDefaults synchronize may have failed")
            }
            
            // Double-check that our changes were actually saved
            if let checkData = userDefaults?.data(forKey: savedGIFsKey),
               let checkGifs = try? JSONDecoder().decode([GIF].self, from: checkData) {
                print("Verified: \(checkGifs.count) GIFs stored in UserDefaults")
            } else {
                print("ERROR: Failed to verify GIFs were saved to UserDefaults")
            }
        } catch {
            print("ERROR: Failed to encode GIFs for storage: \(error)")
        }
    }
    
    func getGIFData(for gif: GIF) -> Data? {
        return GIFFileManager.shared.loadGIFData(from: gif.localFilePath)
    }
    
    // MARK: - Share Extension Integration
    
    func checkForSharedGIFs() {
        guard let pendingGIFsData = userDefaults?.array(forKey: pendingGIFsKey) as? [[String: Any]] else {
            print("No pending GIFs found in shared storage")
            return
        }
        
        guard !pendingGIFsData.isEmpty else {
            print("Pending GIFs array is empty")
            return
        }
        
        print("Found \(pendingGIFsData.count) pending GIFs to process")
        
        var savedGIFs = fetchGIFs()
        var newGIFsAdded = false
        
        for gifInfo in pendingGIFsData {
            if let localFilePath = gifInfo["localFilePath"] as? String,
               let originalURL = gifInfo["originalURL"] as? String,
               let createdAt = gifInfo["createdAt"] as? TimeInterval {
                
                // Create a GIF object - use the provided ID if available, or create a new one
                let gifId = (gifInfo["id"] as? String).flatMap { UUID(uuidString: $0) } ?? UUID()
                let gifCreatedAt = Date(timeIntervalSince1970: createdAt)
                
                let gif = GIF(
                    localFilePath: localFilePath,
                    originalURL: originalURL,
                    id: gifId,
                    createdAt: gifCreatedAt
                )
                
                // Don't add duplicates
                if !savedGIFs.contains(where: { $0.localFilePath == localFilePath }) {
                    savedGIFs.append(gif)
                    newGIFsAdded = true
                }
            }
        }
        
        // Save updated GIFs list and clear pending ones
        if newGIFsAdded {
            print("Added \(pendingGIFsData.count) new GIFs from shared extension")
            saveToUserDefaults(gifs: savedGIFs)
        } else {
            print("No new GIFs were added from pending list")
        }
        
        // Clear pending GIFs
        userDefaults?.removeObject(forKey: pendingGIFsKey)
        userDefaults?.synchronize()
        print("Cleared pending GIFs from shared storage")
    }
}
