import Foundation
import SwiftUI
import Combine

final class Content: ObservableObject {

    @ObservedObject
    var storage: Storage

    @Published
    var settings: Settings

    @Published
    var posts: [Post]

    @Published
    var pages: [Page]

    @Published
    var tags: [Tag]

    @Published
    var files: [FileResource]

    @Published
    var tagOverview: TagOverviewPage?

    @Published
    var results: GenerationResults

    @Published
    var generationStatus: String = "Ready to generate"

    @Published
    private(set) var isGeneratingWebsite = false

    @Published
    private(set) var shouldGenerateWebsite = false

    let imageGenerator: ImageGenerator

    init(settings: Settings,
         posts: [Post],
         pages: [Page],
         tags: [Tag],
         files: [FileResource],
         tagOverview: TagOverviewPage?) {
        self.settings = settings
        self.posts = posts
        self.pages = pages
        self.tags = tags
        self.files = files
        self.tagOverview = tagOverview
        self.results = .init()

        let storage = Storage()
        self.storage = storage
        self.imageGenerator = ImageGenerator(
            storage: storage,
            settings: settings)
    }

    init() {
        let settings = Settings.default
        self.settings = settings
        self.posts = []
        self.pages = []
        self.tags = []
        self.files = []
        self.tagOverview = nil
        self.results = .init()

        let storage = Storage()
        self.storage = storage
        self.imageGenerator = ImageGenerator(
            storage: storage,
            settings: settings)
    }

    private func clear() {
        self.settings = .default
        self.posts = []
        self.pages = []
        self.tags = []
        self.files = []
        self.tagOverview = nil
        self.results = .init()
    }

    var images: [FileResource] {
        files.filter { $0.type.isImage }
    }

    func set(isGenerating: Bool) {
        self.isGeneratingWebsite = isGenerating
    }

    func set(shouldGenerate: Bool) {
        self.shouldGenerateWebsite = shouldGenerate
    }

    func add(_ file: FileResource) {
        // TODO: Insert at correct index?
        files.insert(file, at: 0)
    }

    func add(_ page: Page) {
        // TODO: Insert at correct index?
        pages.insert(page, at: 0)
    }

    func update(contentPath: URL) {
        guard storage.save(contentPath: contentPath) else {
            return
        }
        clear()
        do {
            try loadFromDisk()
        } catch {
            print("Failed to reload content: \(error)")
        }
    }

    func remove(_ file: FileResource) {
        files.remove(file)
        #warning("Remove file from required files, thumbnails, post images, etc.")
    }
}
