import Foundation

final class FeedPageGenerator {

    let results: PageGenerationResults

    let content: Content

    init(content: Content, results: PageGenerationResults) {
        self.content = content
        self.results = results
    }

    private func makeHeaders(requiredItems: Set<KnownHeaderElement>, results: PageGenerationResults) -> Set<HeaderElement> {
        var result = content.postPageHeaders
        for item in requiredItems {
            guard let header = item.header(content: content) else {
                results.warning("Header \(item) not configured in settings")
                continue
            }
            result.insert(header)
        }
        return result
    }

    func generatePage(language: ContentLanguage,
                      posts: [FeedEntryData],
                      title: String?,
                      description: String?,
                      image: FileResource?,
                      pageUrl: String,
                      pageTitle: String?,
                      pageNumber: Int,
                      totalPages: Int,
                      languageButtonUrl: String,
                      linkPrefix: String) -> String {
        var footer = ""
        var requiredHeaders = Set<KnownHeaderElement>()
        if posts.contains(where: { $0.requiresSwiper }) {
            // Sort swiper style sheet before default style sheet
            requiredHeaders.formUnion([.swiperJs, .swiperCss])
            footer = swiperInitScript(posts: posts)
        }
        let headers = makeHeaders(requiredItems: requiredHeaders, results: results)
        results.require(files: headers.compactMap { $0.requiredFile })
        results.require(headers: requiredHeaders)

        let iconUrl = content.settings.navigation.localized(in: language).rootUrl
        let languageButton = NavigationBar.Link(
            text: language.next.rawValue,
            url: languageButtonUrl)

        let imageUrl = image?.linkPreviewImage(results: results)

        let requiredIcons: Set<PageIcon> = posts.reduce(into: []) { icons, post in
            icons.formUnion(post.labels.map { $0.icon })
        }

        let pageHeader = PageHeader(
            language: language,
            title: title ?? pageTitle,
            description: description,
            image: imageUrl,
            pageUrl: pageUrl,
            iconUrl: iconUrl,
            languageButton: languageButton,
            links: content.navigationBar(in: language),
            headers: headers,
            icons: requiredIcons)

        let page = GenericPage(
            header: pageHeader,
            additionalFooter: footer) { content in
                if let pageTitle {
                    content += "<h1 class='separated-headline'>\(pageTitle)</h1>\n"
                }
                for post in posts {
                    content += FeedEntry(data: post).content
                }
                if totalPages > 1 {
                    content += PostFeedPageNavigation(
                        linkPrefix: linkPrefix,
                        currentPage: pageNumber,
                        numberOfPages: totalPages).content
                }
            }
        return page.content
    }

    func swiperInitScript(posts: [FeedEntryData]) -> String {
        let ids = posts.filter { $0.requiresSwiper }.map { $0.entryId }
        return ImageGallery.combinedFootor(ids: ids)
    }
}
