import ComposableArchitecture
import Foundation
import GenAPI

/*
 Clip history that attributes a clip to the base clip if
 it's coming from an extension, edit, or future edit modes.

 The `clips` array comes from the API response, while
 `rootClip` and `rootClipContinueAt` are helpers
 to easily display base clip info.
 */
public struct ClipHistory: Equatable, Hashable {
    public var clips: [ClipHistoryItem]

    public var isRoot: Bool {
        clips.isEmpty
    }

    // Used to easily show the base clip for an extension/infill/etc.
    public var rootClip: ClipID? {
        clips.first?.id
    }

    // Used to show what time the clip was extended from
    public var rootClipContinueAt: Double? {
        clips.first?.continueAt
    }

    // Returns the generation number of this clip in its ancestry chain
    // For example: If this clip was extended from another clip, which was extended from an original clip,
    // this would return 3 (original = 1, first extension = 2, this clip = 3).
    // This can be used to say "Part 3" on an edited clip, for example.
    public var generationNumber: Int? {
        clips.count + 1
    }
}

extension ClipHistory {
    init?(_ remote: GenAPI.GeneratedClipSchema) throws {
        guard let history = remote.metadata.history else { return nil }
        clips = history.compactMap { clipHistory in
            if let stringId = clipHistory.string {
                return .init(stringId, 0)
            } else if let object = clipHistory.object,
                      let id = object["id"]?.stringValue,
                      let continueAt = object["continue_at"]?.doubleValue
            {
                return ClipHistoryItem(id, continueAt)
            }
            return nil
        }
    }
}

public struct ClipHistoryItem: Equatable, Hashable, Decodable {
    public var id: ClipID
    public var continueAt: Double
}

extension ClipHistoryItem {
    init(_ id: String, _ continueAt: Double) {
        self.id = ClipID(remoteId: id)
        self.continueAt = continueAt
    }
}
