//
//  CoreDataDelegete.swift
//  MusicPlayer
//
//  Created by Mr.Zhou on 2024/4/1.
//

import Foundation
import CoreData
// MARK: - CoreDataManageableDelegate 数据库管理协议
///数据库管理协议，继承NSFetchRequestResult，方便调用更多方法
protocol MP_CoreDataManageableDelegate: NSFetchRequestResult {
    ///实体名
    static var entityName: String { get }
}
///扩展数据库管理协议，继承NSManagedObject时，默认实现以下内容
extension MP_CoreDataManageableDelegate where Self: NSManagedObject {
    //根据类名设置实体名
    static var entityName: String {
        return String(describing: self)
    }
    //标准检索
    static var fetchRequest: NSFetchRequest<Self> {
        return NSFetchRequest<Self>(entityName: entityName)
    }
}
// MARK: - CoreDataOperationDelegate 数据库操作协议
///数据库操作协议，创建，查询，删除，保存等
protocol MP_CoreDataOperationDelegate {
    //关联一个继承CoreDataManageableDelegate协议的实体，与泛型相似
    associatedtype ManagedObject: MP_CoreDataManageableDelegate, NSManagedObject
    //创建实体
    static func create() -> ManagedObject
    //查询指定条件实体
    static func fetch(predicate: NSPredicate?, completion: @escaping ([ManagedObject]) -> Void)
    //查询全部实体
    static func fetchAll(completion: @escaping ([ManagedObject]) -> Void)
    //删除实体
    static func delete(_ object: ManagedObject)
    //表保存
    static func save(_ isBackTheard:Bool)
}
///扩展数据库操作协议，默认实现协议方法
extension MP_CoreDataOperationDelegate {
    
    /// 创建实体
    /// - Returns: 返回的实体
    static func create() -> ManagedObject {
        //创建一个对应的实体
        guard let entity = NSEntityDescription.entity(forEntityName: ManagedObject.entityName, in: MP_CoreDataHandlerManager.shared.context) else {
            fatalError("Failed to find entity description for \(ManagedObject.entityName)")
        }
        return ManagedObject(entity: entity, insertInto: MP_CoreDataHandlerManager.shared.context)
    }
    
    /// 查询指定条件实体 (异步)
    /// - Parameter predicate: 条件语句
    /// - Parameter completion: 查询完成后回调，在主线程执行
    static func fetch(predicate: NSPredicate? = nil, completion: @escaping ([ManagedObject]) -> Void) {
        let fetchRequest = ManagedObject.fetchRequest
        fetchRequest.predicate = predicate
        // 使用 perform 方法异步执行查询
        MP_CoreDataHandlerManager.shared.context.perform {
            do {
                let results = try MP_CoreDataHandlerManager.shared.context.fetch(fetchRequest)
                // 回到主线程调用 completion 闭包
                DispatchQueue.main.async {
                    completion(results)
                }
            } catch {
                print("Failed to fetch \(ManagedObject.entityName): \(error)")
                DispatchQueue.main.async {
                    completion([]) // 查询失败，返回空数组
                }
            }
        }
    }

    /// 查询全部实体 (异步)
    /// - Parameter completion: 查询完成后回调，在主线程执行
    static func fetchAll(completion: @escaping ([ManagedObject]) -> Void) {
        let fetchRequest = ManagedObject.fetchRequest
        // 使用 perform 方法异步执行查询
        MP_CoreDataHandlerManager.shared.context.perform {
            do {
                let results = try MP_CoreDataHandlerManager.shared.context.fetch(fetchRequest)
                // 回到主线程调用 completion 闭包
                DispatchQueue.main.async {
                    completion(results)
                }
            } catch {
                print("Failed to fetch \(ManagedObject.entityName): \(error)")
                DispatchQueue.main.async {
                    completion([]) // 查询失败，返回空数组
                }
            }
        }
    }
    /// 从表删除实体
    /// - Parameter object: 指定的实体
    static func delete(_ object: ManagedObject) {
        //实现线程安全
        MP_CoreDataHandlerManager.shared.context.perform {
            MP_CoreDataHandlerManager.shared.context.delete(object)
            save()
        }
    }
    
    /// 表执行保存
    static func save(_ isBackTheard:Bool = false) {
        if isBackTheard {
            MP_CoreDataHandlerManager.shared.saveContextInBackground()
        }else {
            MP_CoreDataHandlerManager.shared.saveContext()
        }
    }
}
