const Connector = require("./Connector")
const config = require('../../config.json')
const boskrypt = require('../../boskrypt')
const md5 = require('md5')
const axios = require('axios')
const puppeteer = require('puppeteer')
function sleep(ms) { return new Promise(r=>setTimeout(r, ms))}
// [ "ecityruf", "123456789" ]
class eMessagePuppeteerConnectorBase extends Connector {
  constructor (amqpConnMngr) {
    super(amqpConnMngr)
    this.name = "em-puppet"
    this.defaultServiceName = ""
    this.duplexCapable = true
    this.supportBOSkrypt = true
    this.configKey = "emPuppettering"
  }
  async transmitMessage(msg, params) {
    const UUID = this.name+':'+md5(JSON.stringify([this.name,...params]))
    const target = params[0]

    const overwriteIdentifier = target.indexOf('#') > -1
    //if (target.split('#').length !== 2) throw 'No valid eMessage Parameter <serviceName#identifier>'
    const serviceName = overwriteIdentifier ? target.split('#')[ 0 ] : this.defaultServiceName,
          identifier = overwriteIdentifier ? target.split('#')[ 1 ] : target

    const $device = msg.routingParams.device
    let payloadBuffer = Buffer.from(msg.payload)
    const boskryptSupport = require("../DeviceRegistry").Devices[ $device ].supportBOSkrypt || false
    console.log('device supports boskrypt', boskryptSupport)
    if (boskryptSupport && !!config.boskrypt && config.boskrypt.enabled) {
        //payloadBuffer
        const keyTable = config.boskrypt.keys
        const FunkrufNummer = "em-"+identifier
        console.log('LUT ', FunkrufNummer, 'key=', keyTable[ FunkrufNummer ])
        if (!!keyTable[ FunkrufNummer ]) {
            payloadBuffer = Buffer.from(boskrypt.encrypt(payloadBuffer, keyTable[ FunkrufNummer ], 0))
        }
    }

    let sendPromise = () => new Promise(async (res, rej) => {
      const browser = await puppeteer.launch({ headless: true })
      this.connectorRegistry.reportState(msg, UUID, 'puppettering')
      const page = await browser.newPage()
      await page.goto('https://ruf.emessage.de/')
      await sleep(1e3)
      await page.reload()

      const pagerNumberInput = 'input[formcontrolname="eID"]'
      await page.waitForSelector(pagerNumberInput)
      await page.type(pagerNumberInput, identifier)
      await sleep(1e3)

      const validatePagerNumberButton = 'form > div:nth-child(2) > button:nth-child(1)'
      await page.waitForSelector(validatePagerNumberButton)
      await page.click(validatePagerNumberButton)
      await sleep(1e3)
  
      const localStorage = await page.evaluate(() => Object.assign({}, window.localStorage))

      console.log(localStorage)
      if (!!localStorage['token:ruf']) 
      await browser.close()
      return axios.post('https://api.emessage.de/rs/ruf/send', {
        messageText: payloadBuffer.toString('ascii'),
        identifier
      }, {
        headers: {
          'Authorization': `Bearer ${ localStorage['token:ruf'] }`
        } 
      })
      .then((sndMessageReq) => { // extract tracking ID from response
        if (sndMessageReq.data.apiStatusCode != 200) { throw sndMessageReq }
        let msgTrackID = sndMessageReq.data.data.trackingId
        console.log('TRACKING ID', msgTrackID, sndMessageReq.data.data.recipients)
        return res(msgTrackID)
      })
      .catch((err) => {
        console.error(err)
        this.connectorRegistry.reportFail(msg, UUID)
        return rej(err)
      })

/*
      const pageContentInput = 'textarea[formcontrolname="message"]'
      await page.waitForSelector(pageContentInput)
      await page.type(pageContentInput, payloadBuffer.toString('ascii'))
      await sleep(1e3)
  
      const sendPageButton = 'form > div:nth-child(3) > button:nth-child(2)'
      await page.waitForSelector(sendPageButton)
      await page.click(sendPageButton)
      await sleep(1e3)
  
      const messageSentResult = '.response-wrapper > div > p'
      await page.waitForSelector(messageSentResult)
      
      let $messageSentResult = await page.$(messageSentResult)
      let value = await page.evaluate(el => el.textContent, $messageSentResult)
      // pageSendForm:messageSentResult
      if (value.indexOf("Ihr Ruf wurde erfolgreich gesendet") > -1) {
          await browser.close()
          return res(true)
      } else {
        await browser.close()
        return rej(value)
      }
      */
    })

    try {
      await sendPromise()
      .then(_=>{
        this.connectorRegistry.reportState(msg, UUID, 'transit')
        return true
      })
    } catch (e1) {
      console.error(e1)
      try {
        await sendPromise()
        .then(_=>{
          this.connectorRegistry.reportState(msg, UUID, 'transit')
          return true
        })
      } catch (e2) {
        console.error(e2)
        await sendPromise()
        .then(_=>{
          this.connectorRegistry.reportState(msg, UUID, 'transit')
          return true
        })
        .catch((err) => {
          console.error(err)
          this.connectorRegistry.reportFail(msg, UUID)
          return false
        })
      }
    }
  }
}

class eMessagePuppeteerConnectorCityruf extends eMessagePuppeteerConnectorBase {
  constructor (amqpConnMngr) {
    super(amqpConnMngr)
    this.name = "em-p-cityruf"
    this.defaultServiceName = "1"
    this.duplexCapable = true
    this.supportBOSkrypt = true
    this.configKey = "emPuppettering"
  }
}
class eMessagePuppeteerConnectorTwoWays extends eMessagePuppeteerConnectorBase {
  constructor (amqpConnMngr) {
    super(amqpConnMngr)
    this.name = "em-p-twoways"
    this.defaultServiceName = "7"
    this.duplexCapable = true
    this.supportBOSkrypt = true
    this.configKey = "emPuppettering"
  }
}


module.exports = {
  eMessagePuppeteerConnectorBase,
  eMessagePuppeteerConnectorCityruf,
  eMessagePuppeteerConnectorTwoWays
}
