import { jsPDF } from 'jspdf'
import ugh from 'ugh'

/**
 * Take an svg template and list of inputs and convert it into a fully loaded template to print a PDF
 * @function
 * @category PDF
 * @since 1.12.0
 * @param {String} svg - Stringified svg used as a template for creating pdf
 * @param {Object[]} inputs - Array of inputs that fill in the svg elements required: { id: string, type: 'text' | 'image', content: canvas | string, uri: string }
 * @param {Object} opts - Non template options: { fileName: string }
 * @returns {Object} Template ready to be used by `printPDF`
 */
export function convertSvgToPDFTemplate (svgString, inputs, opts = {}) {
  const { fileName } = opts
  const parser = new DOMParser()
  const svgDoc = parser.parseFromString(svgString, 'application/xml')
  const svgContainer = svgDoc.children[0]
  const svgHeight = svgContainer.getAttribute('height')
  const svgWidth = svgContainer.getAttribute('width')

  // calc unit from svg
  let unit

  if (svgHeight.split('mm').length > 1) unit = 'mm'
  else if (svgHeight.split('cm').length > 1) unit = 'cm'
  else if (svgHeight.split('m').length > 1) unit = 'm'
  else if (svgHeight.split('px').length > 1) unit = 'px'
  else if (svgHeight.split('pt').length > 1) unit = 'pt'
  else if (svgHeight.split('in').length > 1) unit = 'in'
  const numberify = string => {
    const [numberAsString] = string.split(unit) // closure, order matters

    return Number(numberAsString)
  }
  // calc dimensions from svg
  const height = numberify(svgHeight)
  const width = numberify(svgWidth)
  const orientation = width > height ? 'landscape' : 'portrait'
  const dimensions = [height, width]

  const elements = inputs.map(input => {
    const { content, id, type } = input
    const element = svgDoc.getElementById(id)

    if (!element) {
      ugh.warn(`Element with id '${id}' is missing from svg document`)

      return undefined // this will be filtered out
    }
    const x = numberify(element.getAttribute('x'))
    const y = numberify(element.getAttribute('y'))
    const height = numberify(element.getAttribute('height'))
    const width = numberify(element.getAttribute('width'))
    const config = {
      id,
      type,
      content,
      x,
      y,
      height,
      width
    }

    return config
  }).filter(element => element)

  const template = {
    elements,
    dimensions,
    orientation,
    unit,
    fileName
  }

  return template
}

/**
 * Build a PDF from a template and print locally
 * @function
 * @category PDF
 * @since 1.12.0
 * @param {Object} template - { elements, dimensions, orientation, unit, fileName }
 * @param {Object} opts - PDF options: { hideLogo: false }
 * @returns {Object}
 */
export async function printPDFTemplate (template, passedOpts) {
  const opts = {
    hideLogo: false,
    ...passedOpts
  }
  const {
    dimensions,
    elements = [],
    fileName = 'ol-kit-map',
    orientation = 'landscape',
    unit = 'px'
  } = template
  const doc = new jsPDF({
    orientation,
    unit,
    format: dimensions
  })

  elements.forEach(element => {
    const {
      id,
      type,
      content,
      x,
      y,
      height,
      width,
      uri
    } = element

    if (type === 'image') {
      // http://raw.githack.com/MrRio/jsPDF/master/docs/module-addImage.html
      if (uri) {
        const image = new Image()

        image.src = uri
        doc.addImage(image, 'JPEG', x, y, width, height, id, 'NONE', 0)
      } else {
        // canvas print
        doc.addImage(content, 'JPEG', x, y, width, height, id, 'NONE', 0)
      }
    } else if (type === 'text') {
      doc.text(content, x, y)
    }
  })

  if (!opts.hideLogo) {
    const image = new Image()

    image.src = 'https://ol-kit.com/favicon.ico'
    doc.addImage(image, 'JPEG', 0, 0, 30, 30, '_ol_kit_logo', 'NONE', 0)
  }

  // download pdf
  doc.save(fileName)
}