process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'
import * as path from 'path'
import * as pMap from 'p-map'
import { resolve } from '@plastichub/osr-cli-commons/fs'
import { files } from '@plastichub/osr-cli-commons/glob'

import { sync as exists } from '@plastichub/fs/exists'
import { sync as read } from '@plastichub/fs/read'

import { logger as _logger } from '@plastichub/core/debug'
import * as ExifReader from 'exifreader'

import { translateText } from '@plastichub/osr-i18n/lib/translate'
import { resize, getResizePatterns, format, getFormats, meta } from '@plastichub/osr-media/lib/media/images'

import {
  I18N_STORE,
  
  OSR_ROOT, PRODUCT_CONFIG, PRODUCT_ROOT, 
  RETAIL_MEDIA_CACHE
} from './config'
import { GalleryImage } from './images'

const logger = _logger('ph-site')
const IMAGES_GLOB = '*.+(JPG|jpg|png|PNG|gif)'

export const productGallery = async (grunt, assetPath, product, lang, dstLanguage): Promise<GalleryImage[]> => {
  product = '' + product
  const root = resolve(PRODUCT_ROOT())
  const productConfig: any = read(PRODUCT_CONFIG(product), "json")
  if (!productConfig) {
    logger.error('Product config not found !' + product)
    return
  }
  const mediaPath = `${root}/${product}/${assetPath}/`
  if (!exists(mediaPath)) {
    return []
  }

  const galleryFiles = files(mediaPath, IMAGES_GLOB, {
    cwd: mediaPath,
    absolute: false
  })

  if (!galleryFiles) {
    return
  }
  const removeBufferValues = (obj: any): any => {
    for (const key in obj) {
      const val = obj[key]
      if (Buffer.isBuffer(val)) {
      }
      if (Buffer.isBuffer(val)) {
        delete obj[key];
      } else if (typeof val === 'object') {
        removeBufferValues(val);
      }
    }
    return obj;
  }
  const removeArrayValues = (obj: any): any => {
    for (const key in obj) {
      if (key == 'id') {
        delete obj[key]
      }
      if (Array.isArray(obj[key]) || Buffer.isBuffer(obj[key])) {
        delete obj[key];
      } else if (typeof obj[key] === 'object') {
        removeArrayValues(obj[key]);
      }
    }
    return obj;
  }

  const removeEmptyObjects = (obj: any): any => {
    for (const key in obj) {
      if (typeof obj[key] === 'object' ||
        (key == 'value' && typeof obj[key] === 'number' && obj[key] === 0 ||
          key == 'base64')
      ) {
        obj[key] = removeEmptyObjects(obj[key]);
        if (Object.keys(obj[key]).length === 0) {
          delete obj[key];
        }
      }
    }
    return obj;
  }
  const removeArrays = (obj: any): any => {
    for (const key in obj) {
      if (key == 'description' && typeof obj[key] === 'string' && obj[key].split(',').length > 2) {
        try {
          if (Buffer.isBuffer(Buffer.from(obj[key].split(','))))
            delete obj[key]
        } catch (e) {

        }
      } else if (typeof obj[key] === 'object') {
        removeArrays(obj[key]);
      }
    }
    return obj;
  }
  return await pMap(galleryFiles, async (file: string) => {
    const parts = path.parse(file)
    const filePath = path.join(mediaPath, file)
    let imageMeta: any = await meta(filePath)
    const exifRaw: any = await ExifReader.load(filePath)
    const title = exifRaw?.title?.description || ''
    const keywords = exifRaw?.['LastKeywordXMP']?.description || exifRaw?.iptc?.Keywords?.description || ''
    const exifDescription = exifRaw?.['ImageDescription']?.description || ''
    const width = exifRaw?.['Image Width']?.value
    const height = exifRaw?.['Image Height']?.value
    const lon = exifRaw?.['GPSLongitude']?.description
    const lat = exifRaw?.['GPSLatitude']?.description
    const description = exifDescription || exifRaw?.iptc?.['Caption/Abstract'].description || ''
    imageMeta.exif = exifRaw
    imageMeta = removeBufferValues(imageMeta)
    imageMeta = removeArrayValues(imageMeta)
    imageMeta = removeArrays(imageMeta)
    imageMeta = removeEmptyObjects(imageMeta)
    delete imageMeta.xmp
    delete imageMeta.icc
    delete imageMeta.exif.icc
    delete imageMeta.exif.xmp
    delete imageMeta.exif.iptc
    const keywordsTranslated = await translateText(keywords || '', lang, dstLanguage,{
      store: I18N_STORE(OSR_ROOT(), dstLanguage)
    })
    const assetUrl = (filePath) => `[[OSR_MACHINES_ASSETS_URL]]/[[product_relative]]/${assetPath}/${filePath}`
    const ret: GalleryImage =
    {
      name: path.parse(file).name,
      url: assetUrl(file),
      thumb: assetUrl(`/20/webp/${parts.name}.webp`),
      responsive: assetUrl(`/webp/${parts.name}.webp`),
      meta: imageMeta || "",
      keywords: keywords.split(',').map((k) => k.trim()),
      description,
      alt: `${description} - ${keywordsTranslated || ''}`,
      width,
      height,
      title
    }
    return ret
  })
}
export const compileProductAssets = async (grunt, product_root, srcLang, dstLanguage) => {
  logger.info('Resize Product Media Assets ', product_root);
  
  await resize(getResizePatterns(product_root, 'drawings'))
  await format(getFormats(product_root, 'drawings'), { png: false, cache: RETAIL_MEDIA_CACHE })
  
  await resize(getResizePatterns(product_root, 'renderings'))
  await format(getFormats(product_root, 'renderings'), { png: false, cache: RETAIL_MEDIA_CACHE })
  
  await resize(getResizePatterns(product_root, 'renderings/20'))
  await format(getFormats(product_root, 'renderings/20'), { png: false, cache: RETAIL_MEDIA_CACHE })

  await resize(getResizePatterns(product_root, 'media/gallery'))  
  await format(getFormats(product_root, 'media/gallery'), { png: false, cache: RETAIL_MEDIA_CACHE })
  await resize(getResizePatterns(product_root, 'media/gallery/20'))
  await format(getFormats(product_root, 'media/gallery/20'), { png: false, cache: RETAIL_MEDIA_CACHE })
}
