import path from 'path'
import { HttpError } from 'flaska'
import Parent from '../base/serve.mjs'
import fs from 'fs/promises'
import fsSync from 'fs'
import dot from 'dot'
import config from '../base/config.mjs'
import AlphabeticID from './id.mjs'

export default class ServeHandler extends Parent {
  loadTemplate(indexFile) {
    this.template = dot.template(indexFile.toString(), { argName: [
      'imageLink',
      'videoLink',
      'error',
      'siteUrl',
      'siteUrlBase',
      'version',
      'nonce',
      'in_debug',
      'inputVideo',
      'inputImage'
    ] })
  }

  register(server) {
    super.register(server)
    server.flaska.onerror(this.serveError.bind(this))
  }

  serveError(err, ctx) {
    ctx.log.error(err)

    if (err instanceof HttpError) {
      ctx.status = err.status
      ctx.state.error = err.message
    } else {
      ctx.status = 500
      ctx.state.error = 'Unknown error occured'
    }
    
    let videoLink = ctx.query.get('v') || ''
    let imageLink = ctx.query.get('i') || ''

    ctx.body = this.template({
      videoLink: videoLink,
      imageLink: imageLink,
      error: ctx.state.error || '',
      inputVideo: ctx.state.video || videoLink || '',
      inputImage: ctx.state.image || imageLink || '',
      siteUrl: this.frontend + ctx.url,
      siteUrlBase: this.frontend + '/',
      version: this.version,
      nonce: ctx.state.nonce,
      in_debug: config.get('NODE_ENV') === 'development' && false,
    })
    ctx.type = 'text/html; charset=utf-8'
  }

  async serveIndex(ctx) {
    if (config.get('NODE_ENV') === 'development') {
      let indexFile = await fs.readFile(path.join(this.root, 'index.html'))
      this.loadTemplate(indexFile)
    }

    let videoLink = ctx.query.get('v') || ''
    let imageLink = ctx.query.get('i') || ''

    if (!ctx.state.error) {
      if (ctx.url.match(/^\/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]+$/) && ctx.url.length < 7) {
        try {
          let id = AlphabeticID.decode(ctx.url.slice(1))
          if (id) {
            let res = await ctx.db.safeCallProc('discord_embed.link_get', [id - 3843])
            if (res.first.length) {
              videoLink = ctx.state.video = res.first[0].video_link
              if (!ctx.state.video.startsWith('https://cdn.discordapp.com')
                  && !ctx.state.video.includes('catbox.')
                  && ctx.state.video.includes('?')) {
                videoLink = this.frontend + '/video/' + ctx.url.slice(1) + '.webm'
              }
              imageLink = res.first[0].image_link
            } else {
              ctx.status = 404
            }
          }
        } catch (err) {
          ctx.log.error(err, 'Unable to fetch resource ' + ctx.url.slice(1))
          ctx.state.error = 'Unknown error while fetching link.'
        }
      } else if (ctx.url !== '/') {
        ctx.status = 404
      }
    }

    if (videoLink.startsWith('https://cdn.discordapp.com')) {
      videoLink = videoLink.replace('https://cdn.discordapp.com', 'https://discordproxy.nfp.is')
    }

    let payload = {
      videoLink: videoLink,
      imageLink: imageLink,
      error: ctx.state.error || '',
      inputVideo: ctx.state.video || videoLink || '',
      inputImage: ctx.state.image || imageLink || '',
      siteUrl: this.frontend + ctx.url,
      siteUrlBase: this.frontend + '/',
      version: this.version,
      nonce: ctx.state.nonce,
      in_debug: config.get('NODE_ENV') === 'development' && false,
    }

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