/* eslint-disable implicit-arrow-linebreak */
/* eslint-disable class-methods-use-this */
/* eslint-disable import/prefer-default-export */

import { getObjectValueByPath } from 'vuetify/lib/util/helpers'
import { consoleError, consoleWarn } from 'vuetify/lib/util/console'
import { Service } from '../service'

const LANG_PREFIX = '$shipnity.'
const fallback = Symbol('Lang fallback')

function getTranslation (locale, key, usingDefault = false, defaultLocale) {
  const shortKey = key.replace(LANG_PREFIX, '')
  let translation = getObjectValueByPath(locale, shortKey, fallback)

  if (translation === fallback) {
    if (usingDefault) {
      consoleError(`Translation key "${shortKey}" not found in fallback`)
      translation = key
    } else {
      consoleWarn(`Translation key "${shortKey}" not found, falling back to default`)
      translation = getTranslation(defaultLocale, key, true, defaultLocale)
    }
  }

  return translation
}

export class Lang extends Service {
  constructor (preset) {
    super()
    this.defaultLocale = 'en'
    const {
      current,
      locales,
      t
    } = preset[Lang.property]
    this.current = current
    this.locales = locales
    this.translator = t || this.defaultTranslator
  }

  currentLocale (key) {
    const translation = this.locales[this.current]
    const defaultLocale = this.locales[this.defaultLocale]
    return getTranslation(translation, key, false, defaultLocale)
  }

  t (key, ...params) {
    if (!key.startsWith(LANG_PREFIX)) return this.replace(key, params)
    return this.translator(key, ...params)
  }

  defaultTranslator (key, ...params) {
    return this.replace(this.currentLocale(key), params)
  }

  replace (str, params) {
    return str.replace(/\{(\d+)\}/g, (match, index) =>
      /* istanbul ignore next */
      String(params[+index]))
  }
}
Lang.property = 'lang'
