import * as RSSFeed from 'feed'
import * as xml2js from 'xml2js'
import {
    Singleton,
    appPath,
    Collection,
    Maybe,
    collect,
    Awaitable,
} from '@extollo/lib'
import {AbstractBlog, BlogBackend, BlogPostFrontMatter, isBlogPostFrontMatter} from './blog/AbstractBlog.service'

export interface FeedSub {
    category: string
    name: string
    url: string
}

@Singleton()
export class Blog extends AbstractBlog<BlogPostFrontMatter> {
    async getSubs(): Promise<Collection<FeedSub>> {
        const subs = collect<FeedSub>()
        const opml = await this.getOPML()
        for ( const row of opml.opml.body[0].outline ) {
            if ( !row.outline ) {
                subs.push({
                    category: '(uncategorized)',
                    name: row['$'].text,
                    url: row['$'].xmlUrl,
                })
                continue
            }

            let category = row['$'].text
            if ( category === 'Garrett Mills' ) category += ' (shameless plug)'
            for ( const sub of row.outline ) {
                subs.push({
                    category,
                    name: sub['$'].text,
                    url: sub['$'].xmlUrl,
                })
            }
        }
        return subs
    }

    async getOPML(): Promise<any> {
        const path = appPath('resources', 'assets', 'rss_opml.xml')
        const xmlContent = await path.read()
        return new Promise<any>((res, rej) => {
            xml2js.parseString(xmlContent, (err, result) => {
                if ( err ) {
                    rej(err)
                }

                res(result)
            })
        })
    }

    protected createFeed(lastUpdated: Maybe<Date>): Awaitable<RSSFeed.Feed> {
        const feed = new RSSFeed.Feed({
            title: 'Garrett\'s Blog',
            description: 'Write-ups and musings by Garrett Mills, often technical, sometimes not',
            id: `${this.routing.getAppUrl()}#about`,
            link: this.routing.getNamedPath('blog').toRemote,
            language: 'en',
            image: this.routing.getAssetPath('favicon', 'apple-touch-icon.png').toRemote,
            favicon: this.routing.getAssetPath('favicon', 'favicon.ico').toRemote,
            copyright: `Copyright (c) ${(new Date).getFullYear()} Garrett Mills. See website for licensing details.`,
            updated: lastUpdated,
            generator: '',
            feedLinks: {
                json: this.routing.getNamedPath('blog:json').toRemote,
                atom: this.routing.getNamedPath('blog:atom').toRemote,
                rss: this.routing.getNamedPath('blog:rss').toRemote,
            },
            author: {
                name: 'Garrett Mills',
                email: 'shout@garrettmills.dev',
                link: 'https://garrettmills.dev/#about',
            },
        })

        feed.addCategory('Technology')
        feed.addCategory('Software Development')

        return feed
    }

    protected getBackend(): BlogBackend<BlogPostFrontMatter> {
        return {
            routePrefix: '/blog',
            resourcePath: ['blog-posts'],
            author: {
                name: 'Garrett Mills',
                email: 'shout@garrettmills.dev',
                link: 'https://garrettmills.dev/#about',
            },
        }
    }

    protected isValidFrontMatter(what: unknown): what is BlogPostFrontMatter {
        return isBlogPostFrontMatter(what)
    }
}
