import CloudKit

/// Service for fetching shared cards from CloudKit public database.
struct ClipCloudKitService: Sendable {
    private let database: CKDatabase

    init(containerID: String = ClipIdentifiers.cloudKitContainerIdentifier) {
        self.database = CKContainer(identifier: containerID).publicCloudDatabase
    }

    /// Fetches a shared card from CloudKit by record name.
    /// - Parameter recordName: The UUID string identifying the record.
    /// - Returns: A snapshot of the shared card data.
    func fetchSharedCard(recordName: String) async throws -> SharedCardSnapshot {
        let recordID = CKRecord.ID(recordName: recordName)

        let record: CKRecord
        do {
            record = try await database.record(for: recordID)
        } catch {
            throw ClipError.fetchFailed
        }

        guard let vCardData = record["vCardData"] as? String else {
            throw ClipError.invalidRecord
        }

        if let expiresAt = record["expiresAt"] as? Date, expiresAt < .now {
            throw ClipError.expired
        }

        let displayName = record["displayName"] as? String
        let role = record["role"] as? String
        let company = record["company"] as? String
        let photoData = dataFromPhotoAsset(record["photoAsset"] as? CKAsset)

        return SharedCardSnapshot(
            recordName: recordName,
            vCardData: vCardData,
            displayName: displayName,
            role: role,
            company: company,
            photoData: photoData
        )
    }

    /// Deletes a shared card from CloudKit after it is saved to Contacts.
    func deleteSharedCard(recordName: String) async throws {
        let recordID = CKRecord.ID(recordName: recordName)
        do {
            _ = try await database.deleteRecord(withID: recordID)
        } catch {
            throw ClipError.deleteFailed
        }
    }

    private func dataFromPhotoAsset(_ asset: CKAsset?) -> Data? {
        guard let fileURL = asset?.fileURL else { return nil }
        return try? Data(contentsOf: fileURL)
    }
}
