import Foundation
import SwiftUI

final class LocalizedPost: ChangeObservingItem {

    @Published
    var title: String?

    @Published
    var text: String

    @Published
    var lastModified: Date?

    @Published
    var images: [FileResource]

    /// The labels to show beneath the title
    @Published
    var labels: [ContentLabel]

    /// The text to show for the link to the `linkedPage`
    @Published
    var pageLinkText: String?

    @Published
    var linkPreview: LinkPreview

    init(content: Content,
         title: String? = nil,
         text: String,
         lastModified: Date? = nil,
         images: [FileResource] = [],
         labels: [ContentLabel] = [],
         pageLinkText: String? = nil,
         linkPreview: LinkPreview = .init()) {
        self.title = title
        self.text = text
        self.lastModified = lastModified
        self.images = images
        self.labels = labels
        self.pageLinkText = pageLinkText
        self.linkPreview = linkPreview
        super.init(content: content)
    }

    func contains(_ string: String) -> Bool {
        if let title, title.contains(string) {
            return true
        }
        return text.contains(string)
    }

    func remove(_ file: FileResource) {
        if images.contains(file) {
            images.remove(file)
        }
        linkPreview.remove(file)
    }

    func makePage(urlString: String) -> LocalizedPage {
        .init(content: content,
              urlString: urlString,
              title: title ?? "Title",
              lastModified: lastModified,
              originalUrl: nil,
              linkPreview: linkPreview,
              hideTitle: false)
    }

    // MARK: Images

    var hasImages: Bool {
        images.contains { $0.type.isImage }
    }

    var hasVideos: Bool {
        images.contains { $0.type.isVideo }
    }
}

// MARK: Storage

extension LocalizedPost {

    convenience init(context: LoadingContext, data: Data) {
        self.init(
            content: context.content,
            title: data.title,
            text: data.text,
            lastModified: data.lastModifiedDate,
            images: data.images.compactMap(context.postMedia),
            labels: data.labels?.compactMap { ContentLabel(context: context, data: $0) } ?? [],
            pageLinkText: data.pageLinkText,
            linkPreview: .init(context: context, data: data.linkPreview))
    }

    var data: Data {
        .init(images: images.map { $0.identifier },
              labels: labels.map { $0.data }.nonEmpty,
              title: title,
              text: text,
              lastModifiedDate: lastModified,
              pageLinkText: pageLinkText,
              linkPreview: linkPreview.data)
    }

    /// The structure to store the metadata of a localized post
    struct Data: Codable, Equatable {
        let images: [String]
        let labels: [ContentLabel.Data]?
        let title: String?
        let text: String
        let lastModifiedDate: Date?
        let pageLinkText: String?
        let linkPreview: LinkPreview.Data
    }
}
