import Foundation
import GenAPI

/*
 Concat history is a property on songs that are products of a concat operation.
 For example, the Extend flow concatenates when the user selects the extension
 to add to the song.

 The response is an ordered list of all the songs, whether full songs or extensions,
 that were used to create the song. The first item is the original song, and so on.

 For now, we're just parsing the IDs of the clips, since we only use this property
 to find the "root clip" of any song.
 */
public extension Clip {
    // If the clip is a product of a concat operation, the concat history will
    // contain all the clips that were used to create the song. The first item
    // is the original song, and so on. The root clip in this case would
    // be the first item in the array.
    var rootClipId: ClipID? {
        return concatHistory?.rootClipId
    }
}

public struct ConcatHistory: Equatable, Hashable {
    public var clips: [ConcatHistoryItem]

    // The root clip is the first clip in the concat chain
    public var rootClipId: ClipID? {
        clips.first?.id
    }
}

extension ConcatHistory {
    init?(_ remote: GenAPI.GeneratedClipSchema) throws {
        guard let concatHistory = remote.metadata.concatHistory else { return nil }
        clips = concatHistory.compactMap { concatHistory in
            if let stringId = concatHistory.string {
                return .init(stringId, nil, nil, nil, nil)
            } else if let object = concatHistory.object,
                      let id = object["id"]?.stringValue,
                      let continueAt = object["continue_at"]?.doubleValue,
                      let type = object["type"]?.stringValue,
                      let source = object["source"]?.stringValue,
                      let infill = object["infill"]?.boolValue
            {
                return .init(id, continueAt, type, source, infill)
            }
            return nil
        }
    }
}

public struct ConcatHistoryItem: Equatable, Hashable, Decodable {
    public var id: ClipID
    public var continueAt: Double?
    public var typeValue: String?
    public var source: String?
    public var infill: Bool?
}

extension ConcatHistoryItem {
    init(
        _ id: String,
        _ continueAt: Double?,
        _ type: String?,
        _ source: String?,
        _ infill: Bool?
    ) {
        self.id = ClipID(remoteId: id)
        self.continueAt = continueAt
        self.typeValue = type
        self.source = source
        self.infill = infill
    }
}
