//
//  TSDownloadManager.swift
//  AIRingtone
//
//  Created by 100Years on 2025/3/18.
//
import Foundation

// MARK: - DownloadManager
/// 下载管理器，负责生成和管理下载任务
class DownloadManager {
    static let shared = DownloadManager()
    
    private var maxConcurrentDownloads: Int
    private let downloadQueue: OperationQueue
    private var activeDownloads: [URL: DownloadOperation] = [:]
    private var expirationInterval: TimeInterval = 7 * 24 * 60 * 60 // 默认 7 天
    
    private init() {
        self.maxConcurrentDownloads = 3 // 默认最大并发下载数为 3
        self.downloadQueue = OperationQueue()
        self.downloadQueue.maxConcurrentOperationCount = maxConcurrentDownloads
    }
    
    /// 设置最大并发下载数
    /// - Parameter count: 最大并发下载数
    func setMaxConcurrentDownloads(_ count: Int) {
        maxConcurrentDownloads = count
        downloadQueue.maxConcurrentOperationCount = count
    }
    
    /// 设置缓存文件的过期时长
    /// - Parameter interval: 过期时长（秒）
    func setExpirationInterval(_ interval: TimeInterval) {
        expirationInterval = interval
    }
    
    /// 创建下载任务
    /// - Parameter url: 下载文件的 URL
    /// - Returns: 返回 DownloadOperation，用于控制下载任务
    func downloadFile(from url: URL) -> DownloadOperation {
        if let downloadOperation = activeDownloads[url] {
            return downloadOperation
        }
        
        let downloadOperation = DownloadOperation(url: url)
        activeDownloads[url] = downloadOperation
        downloadQueue.addOperation(downloadOperation)
        return downloadOperation
    }
    
    /// 清理过期的缓存文件
    func cleanExpiredFiles() {
        let fileManager = FileManager.default
        let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
        let expirationDate = Date().addingTimeInterval(-expirationInterval)
        
        if let files = try? fileManager.contentsOfDirectory(at: cacheDirectory, includingPropertiesForKeys: [.creationDateKey], options: .skipsHiddenFiles) {
            for file in files {
                if let attributes = try? fileManager.attributesOfItem(atPath: file.path),
                   let creationDate = attributes[.creationDate] as? Date,
                   creationDate < expirationDate {
                    try? fileManager.removeItem(at: file)
                }
            }
        }
    }
    
    /// 获取本地文件路径（如果存在）
    /// - Parameter url: 文件的 URL
    /// - Returns: 本地文件路径（如果存在），否则返回 nil
    static func localFilePath(for url: URL) -> URL? {
        let cacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
        let fileName = url.lastPathComponent
        let fileURL = cacheDirectory.appendingPathComponent(fileName)
        if FileManager.default.fileExists(atPath: fileURL.path) {
            return fileURL
        }
        return nil
    }
    
    /// 清理所有下载任务
    func cleanAllTasks() {
        for (url, downloadOperation) in activeDownloads {
            downloadOperation.cancel()
            activeDownloads[url] = nil
        }
    }
    
    /// 清理某个下载任务
    /// - Parameter url: 下载任务的 URL
    func cleanTask(for url: URL) {
        if let downloadOperation = activeDownloads[url] {
            downloadOperation.cancel()
            activeDownloads[url] = nil
        }
    }
}

// MARK: - DownloadOperation
/// 下载任务，继承自 Operation
class DownloadOperation: Operation {
    private let url: URL
    private var downloadTask: URLSessionDownloadTask?
    private var resumeData: Data?
    private var isPaused: Bool = false
    
    /// 下载进度回调
    var progressHandler: ((Double) -> Void)?
    
    /// 下载完成回调
    var completionHandler: ((URL?, Error?) -> Void)?
    
    init(url: URL) {
        self.url = url
    }
    
    /// 开始下载
    func startDownload() {
        // 检查本地是否已存在文件
        if let localFilePath = DownloadManager.localFilePath(for: url) {
            completionHandler?(localFilePath, nil)
            return
        }
        
        // 如果没有本地文件，则开始下载
        let semaphore = DispatchSemaphore(value: 0)
        
        // 检查是否有断点续传数据
        if let resumeData = loadResumeData() {
            let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
            downloadTask = session.downloadTask(withResumeData: resumeData)
        } else {
            let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
            downloadTask = session.downloadTask(with: url)
        }
        
        downloadTask?.resume()
        semaphore.wait()
    }
    
    /// 暂停下载
    func pause() {
        isPaused = true
        downloadTask?.cancel { [weak self] resumeData in
            if let resumeData = resumeData {
                self?.saveResumeData(resumeData)
            }
        }
    }
    
    /// 恢复下载
    func resume() {
        isPaused = false
        if let resumeData = loadResumeData() {
            let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
            downloadTask = session.downloadTask(withResumeData: resumeData)
            downloadTask?.resume()
        }
    }
    
    /// 取消下载
    override func cancel() {
        downloadTask?.cancel()
        super.cancel()
    }
    
    /// 保存断点续传数据到文件
    private func saveResumeData(_ data: Data) {
        let resumeDataURL = getResumeDataURL()
        try? data.write(to: resumeDataURL)
    }
    
    /// 从文件加载断点续传数据
    private func loadResumeData() -> Data? {
        let resumeDataURL = getResumeDataURL()
        return try? Data(contentsOf: resumeDataURL)
    }
    
    /// 获取断点续传数据的存储路径
    private func getResumeDataURL() -> URL {
        let cacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
        let resumeDataFileName = url.lastPathComponent + ".resumeData"
        return cacheDirectory.appendingPathComponent(resumeDataFileName)
    }
}

// MARK: - URLSessionDownloadDelegate
extension DownloadOperation: URLSessionDownloadDelegate {
    /// 下载进度更新
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
        progressHandler?(progress)
    }
    
    /// 下载完成
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        if !isPaused {
            // 将文件移动到缓存目录
            let cacheDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
            let fileName = url.lastPathComponent
            let destinationURL = cacheDirectory.appendingPathComponent(fileName)
            try? FileManager.default.moveItem(at: location, to: destinationURL)
            completionHandler?(destinationURL, nil)
        }
    }
    
    /// 任务完成（包括成功或失败）
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if let error = error {
            completionHandler?(nil, error)
        }
    }
}
