import path from 'path'
import striptags from 'striptags'
import Parent from '../base/serve.mjs'
import fs from 'fs/promises'
import dot from 'dot'
import config from '../base/config.mjs'

export default class ServeHandler extends Parent {
  traverseTree(set, tree) {
    for (let branch of tree) {
      if (branch.children && branch.children.length) {
        set.add(branch.id)
        this.traverseTree(set, branch.children)
      }
    }
  }

  getDescriptionFromBlocks(blocks) {
    return encodeURI(blocks
      .filter(x => x.type === 'header'
                || x.type === 'paragraph'
                || x.type === 'quote'
                || x.type === 'list'
                || x.type === 'code'
                || x.type === 'htmlraw')
      .map(x => {
        if (x.type === 'htmlraw') {
          return striptags(x.data.html)
        }
        if (x.type === 'quote') {
          return `"${x.data.text}"` + (x.data.caption ? ` - ${x.data.caption}` : '')
        }
        if (x.type === 'list') {
          return x.data.items.join('. ')
        }
        return x.data.code ? `"${x.data.code}"` : x.data.text
      })
      .map(x => striptags(x))
      .map(x => {
        console.log(x)
        return x
      })
      .filter(x => x)
      .join('. ')
      .replace('/\.+/g', '.')
    )
  }

  async serveIndex(ctx) {
    if (config.get('NODE_ENV') === 'development') {
      let indexFile = await fs.readFile(path.join(this.root, 'index.html'))
      this.template = dot.template(indexFile.toString(), { argName: ['headerDescription', 'headerImage', 'headerTitle', 'headerUrl', 'payloadData', 'payloadTree', 'version', 'nonce', 'type', 'banner', 'media', 'in_debug'] })
    }

    let payload = {
      headerDescription: 'Small fansubbing and scanlation group translating and encoding our favourite shows from Japan.',
      headerImage: this.frontend + '/assets/img/heart.png',
      headerTitle: 'NFP Moe - Anime/Manga translation group',
      headerUrl: this.frontend + ctx.url,
      payloadData: null,
      payloadTree: null,
      version: this.version,
      nonce: ctx.state.nonce,
      type: 'page',
      banner: false,
      media: false,
      in_debug: config.get('NODE_ENV') === 'development' && false,
    }

    try {
      let tree = await this.pageRoutes.getPageTree(ctx, true)
      let setOfBranches = new Set()
      this.traverseTree(setOfBranches, tree.tree)

      payload.payloadTree = JSON.stringify(tree)
      if (ctx.url === '/' || (ctx.url.startsWith('/page/') && ctx.url.lastIndexOf('/') === 5)) {
        ctx.params.path = null
        if (ctx.url.lastIndexOf('/') === 5) {
          ctx.params.path = ctx.url.slice(ctx.url.lastIndexOf('/') + 1)
        }
        let data = await this.pageRoutes.getPage(ctx, true)
        if (!data.page) {
          payload.type = 'frontpage'
        } else if (setOfBranches.has(data.page.id)) {
          payload.type = 'page_with_children'
        }

        if (data.page) {
          payload.headerTitle = data.page.name + ' - NFP Moe'
          if (data.page.content.blocks.length) {
            payload.headerDescription = this.getDescriptionFromBlocks(data.page.content.blocks) || payload.headerDescription
          }
          if (data.page.media_alt_prefix) {
            payload.headerImage = data.page.media_alt_prefix + '_small.jpg'
          }
        }
        payload.media = data.page?.media_avif_preview || false
        payload.banner = data.featured?.banner_avif_preview || data.page?.banner_avif_preview || false
        payload.payloadData = JSON.stringify(data)
      } else if (ctx.url.startsWith('/article/') && ctx.url.lastIndexOf('/') === 8) {
        ctx.params.path = ctx.url.slice(ctx.url.lastIndexOf('/') + 1)
        let data = await this.articleRoutes.getArticle(ctx, true)

        if (data.article) {
          payload.headerTitle = data.article.name + ' - NFP Moe'
          if (data.article.content.blocks.length) {
            payload.headerDescription = this.getDescriptionFromBlocks(data.article.content.blocks) || payload.headerDescription
          }
          if (data.article.media_alt_prefix) {
            payload.headerImage = data.article.media_alt_prefix + '_small.jpg'
          }
        }

        payload.media = data.article?.media_avif_preview || false
        payload.payloadData = JSON.stringify(data)
        payload.type = 'article'
      }
    } catch (e) {
      ctx.log.error(e)
    }

    ctx.body = this.template(payload)
    ctx.type = 'text/html; charset=utf-8'
  }
}