import Foundation
import SwiftUI

/**
 A localized page contains the page content of a single language,
 including the title, url path and required resources

 */
final class LocalizedPage: ChangeObservingItem {

    /**
     The string to use when creating the url for the page.

     Defaults to ``id`` if unset.
     */
    @Published
    var urlString: String

    /**
     The headline to use when showing the entry on it's own page
     */
    @Published
    var title: String

    @Published
    var lastModified: Date?

    /**
     The url used on the old version of the website.

     Needed to redirect links to their new locations.
     */
    let originalUrl: String?

    @Published
    var linkPreview: LinkPreview

    @Published
    var hideTitle: Bool

    @Published
    var hasContent: Bool = false

    init(content: Content,
         urlString: String,
         title: String,
         lastModified: Date? = nil,
         originalUrl: String? = nil,
         linkPreview: LinkPreview = .init(),
         hideTitle: Bool = false) {
        self.urlString = urlString
        self.title = title
        self.lastModified = lastModified
        self.originalUrl = originalUrl
        self.linkPreview = linkPreview
        self.hideTitle = hideTitle
        super.init(content: content)
    }
    
    func isValid(urlComponent: String) -> Bool {
        content.isValidIdForTagOrPageOrPost(urlComponent) &&
        !content.containsPage(withUrlComponent: urlComponent)
    }

    func update(hasContent: Bool) -> Bool {
        if self.hasContent != hasContent {
            self.hasContent = hasContent
            return true
        }
        return false
    }
}


extension LocalizedPage {

    convenience init(context: LoadingContext, data: LocalizedPage.Data) {
        self.init(
            content: context.content,
            urlString: data.url,
            title: data.title,
            lastModified: data.lastModifiedDate,
            originalUrl: data.originalURL,
            linkPreview: .init(context: context, data: data.linkPreview),
            hideTitle: data.hideTitle ?? false)
    }

    /// The structure to store the metadata of a localized page
    struct Data: Codable, Equatable {
        let url: String
        let title: String
        let linkPreview: LinkPreview.Data
        let lastModifiedDate: Date?
        let originalURL: String?
        let hideTitle: Bool?
    }

    var data: Data {
        .init(
            url: urlString,
            title: title,
            linkPreview: linkPreview.data,
            lastModifiedDate: lastModified,
            originalURL: originalUrl,
            hideTitle: hideTitle ? true : nil)
    }
}
