import Foundation

class Tag: Item, LocalizedItem {

    override var itemType: ItemType { .tag }

    @Published
    var isVisible: Bool

    @Published
    var german: LocalizedTag

    @Published
    var english: LocalizedTag

    var savedData: Data?

    override init(content: Content, id: String) {
        self.isVisible = true
        self.english = .init(content: content, urlComponent: id, name: id)
        let deId = id + "-" + ContentLanguage.german.rawValue
        self.german = .init(content: content, urlComponent: deId, name: deId)
        super.init(content: content, id: id)
    }

    init(content: Content, id: String, isVisible: Bool = true, german: LocalizedTag, english: LocalizedTag) {
        self.isVisible = isVisible
        self.german = german
        self.english = english
        super.init(content: content, id: id)
    }

    func isValid(id: String) -> Bool {
        content.isValidIdForTagOrPageOrPost(id) &&
        content.isNewIdForTag(id)
    }

    @discardableResult
    func update(id newId: String) -> Bool {
        guard content.storage.move(tag: identifier, to: newId) else {
            print("Failed to move files of tag \(identifier)")
            return false
        }
        identifier = newId
        return true
    }

    // MARK: Paths

    func filePathRelativeToOutputFolder(for language: ContentLanguage) -> String {
        makeCleanRelativePath(internalPath(for: language))
    }

    private func internalPath(for language: ContentLanguage) -> String {
        content.settings.paths.tagsOutputFolderPath + "/" + localized(in: language).urlComponent
    }

    override func absoluteUrl(in language: ContentLanguage) -> String {
        makeCleanAbsolutePath(internalPath(for: language))
    }

    override func title(in language: ContentLanguage) -> String {
        localized(in: language).title
    }

    override var itemReference: ItemReference {
        .tagPage(self)
    }

    func contains(urlComponent: String) -> Bool {
        german.urlComponent == urlComponent || english.urlComponent == urlComponent
    }

    func remove(_ file: FileResource) {
        english.linkPreview.remove(file)
        german.linkPreview.remove(file)
    }
}

// MARK: Storage

extension Tag: StorageItem {

    convenience init(context: LoadingContext, id: String, data: Data) {
        self.init(
            content: context.content,
            id: id,
            isVisible: data.isVisible ?? true,
            german: .init(context: context, data: data.german),
            english: .init(context: context, data: data.english))
        savedData = data
    }

    struct Data: Codable, Equatable {
        // Defaults to true if unset
        let isVisible: Bool?
        let german: LocalizedTag.Data
        let english: LocalizedTag.Data
    }

    var data: Data {
        .init(
            isVisible: isVisible ? nil : false,
            german: german.data,
            english: english.data)
    }

    func saveToDisk(_ data: Data) -> Bool {
        content.storage.save(tag: data, for: identifier)
    }
}
