process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'
import * as path from 'path'
import { CONFIG_DEFAULT } from '@plastichub/osr-cli-commons'
import { resolve } from '@plastichub/osr-cli-commons/fs'

import { sync as exists } from '@plastichub/fs/exists'
import { sync as read } from '@plastichub/fs/read'
import { sync as write } from '@plastichub/fs/write'

import { logger as _logger } from '@plastichub/core/debug'

import { sanitize } from '@plastichub/osr-i18n/_cli'
import { IOptions as IOptionsI18n } from '@plastichub/osr-i18n/types'
import { translate } from '@plastichub/osr-i18n/lib/translate'

import { compileProductAssets, productGallery } from './media'
import { writeTaskConfig } from './log'

import {
  ENABLED_PRODUCTS, I18N_SOURCE_LANGUAGE, I18N_STORE,
  LANGUAGES,
  OSRL_ENV, OSRL_LANG_FLAVOR,
  OSRL_MODULE_NAME, OSR_ROOT, PRODUCTS_TARGET_SRC, PRODUCT_CONFIG, PRODUCT_HUGO_TEMPLATE, OSRL_PRODUCT_PROFILE, PRODUCT_ROOT, PRODUCT_DIR,
  OSRL_ENVIRONMENT,
  RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS,
  TranslateProductAssets,
  ConvertProductMedia,
  PopulateProductDefaults,
  RETAIL_COMPILE_CACHE
} from './config'
import { ICompileTaskOptions } from '@plastichub/osr-tasks/tasks/compile'

const logger = _logger('ph-site')

/////////////////////////////////////////////////////////////////////
//
//  Product Multi Task products[product] -> content/retail/product
export const populateProductDefaults = async (grunt, product_root, srcLang, dstLanguage) => {
  const _createFile = (file: string) => {
    file = path.resolve(path.join(product_root, file))
    if (!exists(file)) {
      write(file, '')
    }
  }
  _createFile('templates/shared/product_features.md')
}
export const compileProductTask = async (grunt, product, lang, dstLanguage, target, options: any = {}) => {
  const config = {}
  product = '' + product
  const logLevel = grunt.option('logLevel') || 'warn'
  const product_rel = product.replace('products/', '')
  const root = resolve(PRODUCT_ROOT())
  const slug = path.parse(product).base
  const debug = grunt.option('debug')
  const productConfig: any = read(PRODUCT_CONFIG(product), "json")
  if (!productConfig) {
    logger.error('Product config not found !' + product)
    return
  }
  productConfig.description = productConfig.description || ''
  const translateProductAssets = async () => {
    logger.info('Translate Product Assets ' + slug + ' ' + dstLanguage + ' ' + product_rel)
    const config: any = CONFIG_DEFAULT()
    if (dstLanguage === I18N_SOURCE_LANGUAGE) {
      return
    }
    logger.setSettings({ minLevel: RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS })
    const i18nOptions: IOptionsI18n = {
      srcLang: I18N_SOURCE_LANGUAGE,
      dstLang: dstLanguage,
      src: `${PRODUCT_DIR(product)}/specs.xlsx`,
      store: I18N_STORE(OSR_ROOT(), dstLanguage),
      dst: "${SRC_DIR}/${SRC_NAME}-${DST_LANG}${SRC_EXT}",
      query: "$[*][0,1]",
      cache: true,
      api_key: config.deepl.auth_key,
      logLevel: RETAIL_LOG_LEVEL_I18N_PRODUCT_ASSETS
    }
    return await translate(sanitize(i18nOptions) as any)
  }

  const onCompiled = async (src, dst, options, content) => {
    if (TranslateProductAssets || grunt.option('translateProductAssets')) {
      await translateProductAssets()
    }
    if (ConvertProductMedia || grunt.option('convertProductMedia')) {
      await compileProductAssets(grunt, PRODUCT_DIR(product), lang, dstLanguage)
    }
    if (PopulateProductDefaults) {
      await populateProductDefaults(grunt, PRODUCT_DIR(product), lang, dstLanguage)
    }
    // logger.warn('On Compiled Product ' + product + ' ' + dstLanguage)
  }

  let defaultOptions: any = {
    src: [path.resolve(path.join(root, PRODUCT_HUGO_TEMPLATE))],
    options: {
      cache: RETAIL_COMPILE_CACHE,
      debug,
      env: OSRL_ENVIRONMENT,
      format: 'html',
      language: OSRL_LANG_FLAVOR,
      module: OSRL_MODULE_NAME,
      output: `${target}/${product_rel}/_index.md`,
      profile: OSRL_PRODUCT_PROFILE,
      root,
      cwd: root,
      watchContent: false,
      logLevel,
      store: I18N_STORE(OSR_ROOT(), dstLanguage),
      sourceLanguage: I18N_SOURCE_LANGUAGE,
      targetLanguage: dstLanguage,
      variables: {
        root,
        product,
        product_rel,
        product_relative: '' + product_rel,
        sourceLanguage: I18N_SOURCE_LANGUAGE,
        targetLanguage: dstLanguage,
        language: dstLanguage,
        i18n: I18N_STORE(OSR_ROOT(), dstLanguage),
        ...productConfig,
        fm: {
          keywords: (productConfig.keywords || "").split(',').map((k) => k.trim())
        }
      },
      ...options,
      onCompileDone: onCompiled,
      onCompile: async (options) => {
        const gallery = await productGallery(grunt, 'media/gallery', product, lang, dstLanguage)
        const galleryRenderings = await productGallery(grunt, 'renderings', product, lang, dstLanguage)
        options.variables.fm.rGallery = gallery
        options.variables.fm.rGalleryRenderings = galleryRenderings
        return options
      }
    } as ICompileTaskOptions
  }
  debug && logger.debug('Create product compile options for ' + product, defaultOptions.options)
  config[`content-${dstLanguage}-${slug}`] = {
    ...defaultOptions,
  }
  grunt.extendConfig({ compile: config })
  grunt.registerTask(`content-${dstLanguage}-${slug}`, `compile:content-${dstLanguage}-${slug}`)
}
export const registerProductTasks = (grunt) => {
  const logLevel = grunt.option('logLevel') || 'warn'
  logger.setSettings({ minLevel: logLevel })
  const product_compile_tasks = []
  const productTasks = (items) => {
    items.forEach((product) => {
      const slug = path.parse(product).base
      compileProductTask(grunt, product, I18N_SOURCE_LANGUAGE, I18N_SOURCE_LANGUAGE, "./content/en/retail")
      product_compile_tasks.push(`compile:content-en-${slug}`)
      LANGUAGES.forEach((lang) => {
        product_compile_tasks.push(`compile:content-${lang}-${slug}`)
        compileProductTask(grunt, product, I18N_SOURCE_LANGUAGE, lang, `./content/${lang}/retail`)
      })
    })
  }
  productTasks(readProducts(grunt.option('branch') || 'test'))
  grunt.registerTask(`content-all`, product_compile_tasks)
}

/////////////////////////////////////////////////////////////////////
//
//  Product Single Test Task products[product] -> src/retail/product

export const productContentOptions = (target, product) => {
  product = '' + product
  const product_rel = product.replace('products/', '')
  const root = resolve(PRODUCT_ROOT())
  const productConfig: any = read(PRODUCT_CONFIG(product), "json")
  if (!productConfig) {
    logger.error('Product config not found !' + product)
  }
  return {
    debug: false,
    watch: false,
    root,
    cwd: root,
    env: OSRL_ENV,
    profile: '${root}/.osrl.json',
    output: `${target}/${product_rel}/_index.md`,
    // format: 'html',
    module: OSRL_MODULE_NAME,
    cache: true,
    variables: {
      product,
      product_rel,
      root,
      product_relative: '' + product_rel,
      ...productConfig
    }
  }
}
export const productHugoTask = (grunt, product, options: any = {}, product_item_tasks) => {
  if (!product) {
    logger.error('Invalid product')
  }
  const config = {}
  const slug = path.parse(product).base
  const target = path.resolve(PRODUCTS_TARGET_SRC)
  const productOptions = productContentOptions(target, product)
  config[`product-${slug}`] = {
    src: [PRODUCT_HUGO_TEMPLATE],
    options: productOptions
  }
  grunt.extendConfig({
    compile: config
  })
  grunt.registerTask(`product-${slug}`, `compile:product-${slug}`)
  product_item_tasks.push(`compile:product-${slug}`)
  grunt.registerTask(`products-hugo`, product_item_tasks)
  writeTaskConfig(`compile_product-${slug}`, config)
}
export const readProducts = (branch: string = 'test') => {
  const conf = read(ENABLED_PRODUCTS, "json") || {}
  if (branch) {
    conf['all'] = [...conf["sheetpress"], ...conf["injectors"], ...conf["extruders"], ...conf["shredders"]]
    return conf[branch] || []
  } else {
    return Object.values(conf).flat()
  }
}
