const config = require('../../config')
const logger = require('../../config/logger')
const authorisedRequest = require('../lib/authorised-request')

let redisClient

function getMetadata (path, key) {
  const ttl = config.redis.metadataTtl
  const url = `${config.apiRoot}/metadata/${path}/`

  if (redisClient) {
    return new Promise((resolve, reject) => {
      redisClient.get(url, (err, data) => {
        if (!err && data) {
          data = JSON.parse(data)
          module.exports[key] = data
          resolve(data)
        } else {
          authorisedRequest(null, url)
          .then((responseData) => {
            module.exports[key] = responseData
            redisClient.setex(url, ttl, JSON.stringify(responseData))
            resolve(responseData)
          })
          .catch((reponseError) => {
            logger.error('Error fetching metadataRepository for url: %s', url)
            reject(reponseError)
            throw reponseError
          })
        }
      })
    })
  }

  return authorisedRequest(null, url)
    .then((responseData) => {
      module.exports[key] = responseData
      return responseData
    })
    .catch((err) => {
      logger.error('Error fetching metadataRepository for url: %s', url)
      throw err
    })
}

module.exports.getMetadataItem = function (table, id) {
  const url = `${config.apiRoot}/metadata/${table}/`

  return new Promise((resolve, reject) => {
    authorisedRequest(null, url)
    .then((data) => {
      data.forEach((item) => {
        if (item.id === id) {
          resolve(item)
        }
      })
    })
    .catch((error) => {
      reject(error)
    })
  })
}

const metadataItems = [
  ['sector', 'sectorOptions'],
  ['turnover', 'turnoverOptions'],
  ['uk-region', 'regionOptions'],
  ['country', 'countryOptions'],
  ['employee-range', 'employeeOptions'],
  ['business-type', 'businessTypeOptions'],
  ['team', 'teams'],
  ['interaction-type', 'interactionTypeOptions'],
  ['service-delivery-status', 'serviceDeliveryStatusOptions'],
  ['service', 'serviceDeliveryServiceOptions'],
  ['event', 'eventOptions'],
  ['headquarter-type', 'headquarterOptions'],
  ['referral-source-activity', 'referralSourceActivityOptions'],
  ['referral-source-marketing', 'referralSourceMarketingOptions'],
  ['referral-source-website', 'referralSourceWebsiteOptions'],
  ['investment-business-activity', 'businessActivityOptions'],
  ['investment-type', 'investmentTypeOptions'],
  ['investment-project-stage', 'investmentProjectStage'],
  ['fdi-type', 'fdiOptions'],
  ['non-fdi-type', 'nonFdiOptions'],
  ['salary-range', 'salaryRangeOptions'],
  ['investment-strategic-driver', 'strategicDriverOptions'],
  ['investment-project-stage', 'investmentStageOptions'],
]

const restrictedServiceKeys = [
  'Account Management',
  'Bank Referral',
  'Digital Trade Advisers One-to-One',
  'Events – Overseas',
  'Events - UK Based',
  'Events – Webinars',
  'First Time Exporters - Export Insight Visits',
  'First Time Exporters – Export Savvy',
  'Language and Culture Advisers One-to-One',
  'Market Selection Service (MSS)',
  'Market Visit Support (MVS)',
  'Onward Referral',
  'Open to Export Assist (OtE)',
  'Outward Missions',
  'Overseas Business Network Advisers One-to-One',
  'Overseas Market Introduction Service (OMIS)',
  'Postgraduates for International Business - Placement',
  'Significant Assistance (PIMS)',
  'Trade - ECR Web Action Plan',
  'UK Region Local]']

module.exports.setRedisClient = (client) => {
  redisClient = client
}

module.exports.fetchAll = (cb) => {
  // todo
  // refactor to create an array of jobs to do and then use promise all
  // before returning back via a promise.

  let caughtErrors
  let totalRequests = 0
  let completeRequests = 0

  function checkResults () {
    completeRequests += 1
    if (completeRequests === totalRequests) {
      logger.debug('All metadataRepository requests complete')
      cb(caughtErrors)
    }
  }

  for (const item of metadataItems) {
    totalRequests += 1
    getMetadata(item[0], item[1])
      .then((data) => {
        if (item[2]) {
          item[2](data)
        }

        checkResults()
      })
      .catch((err) => {
        caughtErrors = caughtErrors || []
        caughtErrors.push(err)
        checkResults()
      })
  }
}

module.exports.REASONS_FOR_ARCHIVE = [
  'Company is dissolved',
  'Other',
]

module.exports.getServices = function (token) {
  return authorisedRequest(token, `${config.apiRoot}/metadata/service/`)
}

module.exports.initialiseRestrictedServiceOptions = function () {
  authorisedRequest(null, `${config.apiRoot}/metadata/service/`)
  .then((data) => {
    module.exports.serviceDeliveryServiceOptions = data.filter(service => restrictedServiceKeys.includes(service.name))
  })
}

module.exports.getIdForName = function (options, name) {
  if (!name) return null
  const _name = name.toLowerCase()
  for (const option of options) {
    if (_name === option.name.toLowerCase()) {
      return option
    }
  }
}

@@ -2733,16 +2733,70 @@
 ions'%5D,%0A
+  %5B'order-service-type', 'orderServiceTypesOptions'%5D,%0A
 %5D%0A%0Aconst

Add order service types to cached metadata