'use strict'

const debug = require('debug-logfmt')('data:providers:formats')
const { default: pMap } = require('p-map')
const mql = require('@microlink/mql')
const { sortBy } = require('lodash')
const { getType } = require('mime')
const path = require('path')

const MICROLINK_CDN_URL = 'https://cdn.microlink.io/file-examples'
const DIST = path.resolve(__dirname, '../../../data/formats.json')

const fileUrls = async () =>
  (await fetch(`${MICROLINK_CDN_URL}/index.json`).then(res => res.json())).map(
    file => `${MICROLINK_CDN_URL}/${file}`
  )

const getConfidence = formats => {
  const total =
    formats.length * 3 +
    formats.reduce(
      (acc, { palette }) => (palette === undefined ? acc : acc + 1),
      0
    ) +
    formats.reduce(
      (acc, { duration }) => (duration === undefined ? acc : acc + 1),
      0
    )

  const score = formats.reduce((acc, format) => {
    if (format.size === false) --acc
    if (format.width === false) --acc
    if (format.height === false) --acc
    if (format.palette === false) --acc
    if (format.duration === false) --acc
    return acc
  }, total)

  const result = (score / total) * 100
  return { score: `${Math.round(result * 100) / 100}%` }
}

const fn = async () => {
  const urls = await fileUrls()

  const result = await pMap(
    urls,
    async fileUrl => {
      try {
        const contentType = getType(fileUrl) || 'application'
        const [type] = contentType?.split('/') || []
        const isImage = type === 'image'

        const { data, response } = await mql(
          `https://compose-html.vercel.app/?body=${fileUrl}`,
          {
            apiKey: process.env.MICROLINK_API_KEY,
            data: {
              file: {
                selector: 'body',
                type: isImage ? 'image' : 'url'
              }
            },
            ttl: 'max',
            filter: 'file',
            prerender: false,
            // force: true,
            palette: true
          }
        )

        const { file } = data

        const item = {
          url: file.url,
          extension: path.extname(fileUrl).substring(1),
          type,
          height: file.height !== null,
          width: file.width !== null,
          size: file.size !== null
        }

        if (isImage) {
          item.palette = file.palette !== null
        }

        if (file.duration !== undefined) {
          item.duration = file.duration !== null
        }

        debug(response.requestUrl, '→', item)
        return item
      } catch (err) {
        debug.error(fileUrl, err)
        return null
      }
    },
    { concurrency: 4 }
  )

  const validResults = result.filter(Boolean)
  return [getConfidence(validResults), sortBy(validResults, 'extension')]
}

module.exports = () =>
  require('../create-provider').fromCode(fn, { dist: DIST })

module.exports.dist = DIST
