import Foundation
import Combine

class Item: ChangeObservingItem, Identifiable {

    /// A dummy property to force views to update when properties change
    @Published
    private var changeToggle = false

    /// A session-id for the item for identification
    let id = UUID()

    /// The unique, persistent identifier of the item
    ///
    /// This identifier is not used for `Identifiable`, since it may be changed through the UI.
    @Published
    var identifier: String

    init(content: Content, id: String) {
        self.identifier = id
        super.init(content: content)

        observeChanges()
    }

    // MARK: Paths

    func makeCleanAbsolutePath(_ path: String) -> String {
        "/" + makeCleanRelativePath(path)
    }

    func makeCleanRelativePath(_ path: String) -> String {
        path.components(separatedBy: "/").filter { !$0.isEmpty }.joined(separator: "/")
    }

    func title(in language: ContentLanguage) -> String {
        fatalError()
    }

    func absoluteUrl(in language: ContentLanguage) -> String {
        fatalError()
    }

    var itemType: ItemType {
        fatalError()
    }

    var itemReference: ItemReference {
        fatalError()
    }

    var itemId: ItemId {
        .init(type: itemType, id: identifier)
    }
}

extension Item: Equatable {

    static func == (lhs: Item, rhs: Item) -> Bool {
        lhs.id == rhs.id
    }
}

extension Item: Hashable {

    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

extension Item: Comparable {

    static func < (lhs: Item, rhs: Item) -> Bool {
        lhs.identifier < rhs.identifier && lhs.itemType < rhs.itemType
    }
}
