import { uploadMedia, deleteFile } from '../base/media/upload.mjs'
import config from '../base/config.mjs'
import AlphabeticID from './id.mjs'

export default class IndexPost {
  constructor(opts = {}) {
    Object.assign(this, {
      frontend: opts.frontend,
      uploadMedia: uploadMedia,
      deleteFile: deleteFile,
    })
  }

  register(server) {
    this.serve = server.routes.serve
    server.flaska.post('/', [
      server.formidable({ maxFileSize: 8 * 1024 * 1024, }),
    ], this.createNewLink.bind(this))
  }

  hasErrors(ctx, hasMedia) {
    if (!ctx.req.body.video) {
      return 'Missing video link'
    }

    if (!ctx.req.body.video.startsWith('http')
        || !(ctx.req.body.video.includes('mp4')
          || ctx.req.body.video.includes('webm'))) {
      return 'Video link has to be a valid full url and contain mp4 or webm in it'
    }

    if (!ctx.req.body.image && !hasMedia) {
      return 'Missing image link or file'
    }
    
    if (ctx.req.body.image) {
      if (!ctx.req.body.image.startsWith('http')
          || !(ctx.req.body.image.includes('jpg')
            || ctx.req.body.image.includes('jpeg')
            || ctx.req.body.image.includes('webp')
            || ctx.req.body.image.includes('png')
            )
          ) {
        return 'Image link has to be a valid full url and contain jpg, jpeg, webp or png'
      }
    }
  }

  async getLink(ctx) {
    
    return this.serve.serveIndex(ctx)
  }

  /** POST: / */
  async createNewLink(ctx) {
    ctx.state.video = ctx.req.body.video
    ctx.state.image = ctx.req.body.image

    let rateLimited = false
    let redisKey = 'ratelimit_' + ctx.req.ip.replace(/:/g, '-')

    try {
      let val = (await ctx.redis.get(redisKey))
      console.log(redisKey, val)
      val = val && Number(val) || 0
      if (val > 3) {
        rateLimited = true
      } else if (val > 2) {
        await ctx.redis.setex(redisKey, 60 * 15, val + 1)
        rateLimited = true
      } else {
        await ctx.redis.setex(redisKey, 15, val + 1)
      }
    } catch (err) {
      ctx.log.error(err, 'Error checking rate limit for ' + redisKey)
    }

    if (rateLimited) {
      ctx.state.error = 'You have reached rate limit. Please wait at least 15 minutes.'
      return this.serve.serveIndex(ctx)
    }

    let hasMedia = ctx.req.files.media && ctx.req.files.media.size
    let redirect = ''
    let error = this.hasErrors(ctx, hasMedia)

    if (!error && hasMedia) {
      try {
        let temp = await this.uploadMedia(ctx.req.files.media)
        ctx.state.image = ctx.req.body.image = 'https://cdn.nfp.is' + temp.sizes.small.jpeg.path

        await this.deleteFile(temp.filename).catch(err => {
          ctx.log.error(err, 'Error removing ' + temp.filename)
        })
      }
      catch (err) {
        ctx.log.error(err)
        error = 'Unable to upload file: ' + err.message
      }
    }
    if (!error) {
      redirect = `${this.frontend}/?v=${ctx.state.video}&i=${ctx.state.image}`
    }

    if (!error) {
      try {
        let id = 'health'
        while (id === health) {
          let params = [
            ctx.state.video,
            ctx.state.image,
            ctx.req.ip,
          ]
          let res = await ctx.db.safeCallProc('discord_embed.link_add', params)
          id = AlphabeticID.encode(res.first[0].id + 3843)
        }
        redirect = `${this.frontend}/${id}`
      }
      catch (err) {
        ctx.log.error(err)
        error = 'Error while generating shortened link.'
      }
    }

    if (redirect && !error) {
      ctx.status = 302
      ctx.headers['Location'] = redirect
      ctx.type = 'text/html; charset=utf-8'
      ctx.body = `
Redirecting
<a href="${redirect}">Click here if it doesn't redirect</a>
`
    }
    ctx.state.error = error
    return this.serve.serveIndex(ctx)
  }
}
// https://litter.catbox.moe/cnl6hy.mp4