//
//  MediaDownloader.swift
//  WoWonder
//
//  Created by iMac on 06/06/24.
//  Copyright © 2024 ScriptSun. All rights reserved.
//

import Foundation
import UIKit
import Alamofire
import Photos

class MediaDownloader {
    
    static let shared = MediaDownloader()
    let fileManager = FileManager.default
    
    private init() {}
    
    // MARK: - Media Cache
    
    private var mediaCache: [String: String] {
        get {
            return UserDefaults.standard.dictionary(forKey: "mediaCache") as? [String: String] ?? [:]
        }
        set {
            UserDefaults.standard.setValue(newValue, forKey: "mediaCache")
        }
    }
    
    func getCachedLocalURL(for url: URL) -> URL? {
        let urlString = url.absoluteString
        if let localPath = mediaCache[urlString] {
            return self.getDocumentDirectoryPath().appendingPathComponent(localPath)
        }
        return nil
    }
    
    func cacheLocalURL(_ localPath: String, for url: URL) {
        let urlString = url.absoluteString
        mediaCache[urlString] = localPath
    }
    
    // MARK: - File Download
    
    func getDocumentDirectoryPath() -> URL {
        let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
        return documentsDirectory
    }
    
    func downloadFile(from url: URL, progressHandler: @escaping (Float) -> Void, completionHandler: @escaping (Result<URL, Error>) -> Void) {
        // Check if media is already downloaded
        if let localURL = getCachedLocalURL(for: url), fileManager.fileExists(atPath: localURL.path) {
            completionHandler(.success(localURL))
            return
        }
        
        // If media not found in cache, start downloading
        let localPath = self.getDocumentDirectoryPath().appendingPathComponent(url.lastPathComponent)
        
        let destination: DownloadRequest.Destination = { _, _ in
            return (localPath, [.removePreviousFile, .createIntermediateDirectories])
        }
        
        AF.download(url, to: destination).downloadProgress { progress in
            progressHandler(Float(progress.fractionCompleted))
        }.response { response in
            if let error = response.error {
                completionHandler(.failure(error))
            } else {
                self.cacheLocalURL(localPath.lastPathComponent, for: url) // Cache the local URL
                completionHandler(.success(localPath))
            }
        }
    }
    
    // MARK: - Media Saving
    
    func saveImageToPhotos(image: UIImage, completion: @escaping (Bool, Error?) -> Void) {
        if let compressedImageData = image.jpegData(compressionQuality: 1), let compressedImage = UIImage(data: compressedImageData) {
            PHPhotoLibrary.requestAuthorization { status in
                if status == .authorized {
                    UIImageWriteToSavedPhotosAlbum(compressedImage, nil, nil, nil)
                    completion(true, nil)
                } else {
                    completion(false, NSError(domain: "MediaDownloader", code: 1, userInfo: [NSLocalizedDescriptionKey: "Permission denied"]))
                }
            }
        }
    }
    
    func saveVideoToPhotos(videoURL: URL, completion: @escaping (Bool, Error?) -> Void) {
        PHPhotoLibrary.requestAuthorization { status in
            if status == .authorized {
                PHPhotoLibrary.shared().performChanges({
                    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
                }) { saved, error in
                    if saved {
                        completion(true, nil)
                    } else {
                        completion(false, error)
                    }
                }
            } else {
                completion(false, NSError(domain: "MediaDownloader", code: 1, userInfo: [NSLocalizedDescriptionKey: "Permission denied"]))
            }
        }
    }
    
}
