import path from 'path'
import chalk from 'chalk'
import axios from 'axios';
import qs from 'qs'
import { Console } from 'console';

const ora = require('ora');
const fsEx = require('fs-extra')

interface TranslatehHandler {
  translate: string
  locale: string
  config:string
  localPath?: string
  outPutPath?: string // 输出目录
}

interface TranslatehData {
  translateApiUrl: string
  text: string
  from: string
  to: string
}

type Types = keyof TranslatehHandler
// 翻译语言
let TranslateData: Array<string> = [];
// 读取的翻译源文件
let i18ndata:any= {};
// 文件输出目录
const outPutPath:any = {
  url: '',
  locale:[],  // 语言包
  excludeConfig:{},  // 排除的语言包
  outPutPath:'', // 输出目录
  name: ''
};


let spinner: any


// 读取文档
function readFile(localPath: string) {
  const packagePath = path.resolve(process.cwd(), localPath);
  outPutPath.url = localPath.substring(0, localPath.lastIndexOf('/')) + '/';
  // 
  outPutPath.name = packagePath.split('.')[1];
  if (!fsEx.pathExistsSync(packagePath)) {
    throw new Error(chalk.red(`error: 当前路径不存在${localPath}`));
  }
  const json = fsEx.readFileSync(packagePath).toString();
  return json;
}


async function translate(options: TranslatehHandler) {
  // 翻译
  if (options['localPath']) {
    i18ndata = readFile(options['localPath'] as string)
  }
  if (options['config']) {
    outPutPath.excludeConfig = JSON.parse(readFile(options['config'] as string));
  }
    // outputPath  输出目录
  if (options['outPutPath']) {
    outPutPath.outPutPath = options['outPutPath']
  }
  // 获取转义语言
  const locale = eval(options['locale'].split('to:')[1]);
  outPutPath.locale = locale;
  await tempTargetList(i18ndata, locale[0]);
}

// 截取并转义字符串
export const getText = (data: any, eq: number,arr:Array<any>) => {
  let index = eq || 0;
  for (const i in data) {
    if (typeof data[i] === 'object') {
      getText(data[i],arr.length,arr);
      index = arr.length;
    } else {
      index++;
      // const key = index + (i.substring(0, 1).toLocaleUpperCase()) ;
      const key = index ;

      data[i] = `${data[i].replace(/&/ig, '%%%')}`
      arr.push(`${key}A:${data[i]}`);

    }
  }
  return arr;
}

//Rewriting 重新写入翻译文件
export const RewritConfig = (data:any, ranslateData: Array<string>, to: string, index: number,arr:any) => {
  for (const i in data) {
    if (typeof data[i] === 'object') {
      RewritConfig(data[i], ranslateData, to, arr.length,arr);
      index = arr.length;
    } else {
      index++;
      const qystring = ranslateData[0];
      if (qystring) {
        // 去除不需要的字符
        const value:string = qystring.replace(/^\d+[a-zA-Z]:/,'').replace(/。$/, '').replace(/\./, '').replace(/%%%/ig, '&').trim();

        data[i] = value;
        ranslateData.splice(0,1);
      }
      arr.push(i);
    }
  }
  if(ranslateData.length<1){
    if(outPutPath.outPutPath){
      outPutPath.url = path.resolve(process.cwd(), outPutPath.outPutPath)+'\\';
    }
    const url =  outPutPath.url+to+'.'+outPutPath.name;
    // 已经存在该文件
    if (fsEx.pathExistsSync(url)) {
      let beforeData =  JSON.parse(readFile(url as string));
        if(beforeData){
          data = Object.assign(beforeData,data);
        }

    }
    

    if(outPutPath.excludeConfig && outPutPath.excludeConfig[to]){
      // 排除
      data = Object.assign(data,outPutPath.excludeConfig[to].data);
    }

    outPutPath.locale.splice(0,1);
     fsEx.writeJsonSync(url, data, { spaces: 2 });
     spinner.succeed(chalk.green(`语言包${to}：文件写入${url}`))
    if(outPutPath.locale.length>0){
      //
      TranslateData = [];
       tempTargetList(i18ndata, outPutPath.locale[0]);
    }
  }

  return arr;
}



export const getSourceList = (i18ndata: any) => {
  // 获取翻译转数组字符串
  const textArr = getText(JSON.parse(i18ndata), 0,[]);
  const chunkSplitLimitList = getSourceListText(textArr.join('。**'), 2000);
  return chunkSplitLimitList;
}



// 翻译
const tempTargetList = async (i18ndata: any, type: string) => {
  const sourceList = getSourceList(i18ndata);
  spinner.start(`${type}语言包翻译中……`)

  await initResult({
    text: sourceList[0],
    type: type
  }, sourceList);

}
/**
 * @param {*} { 翻译结果调用}
 * @returns
 */
const initResult = async function (item: any, sourceList: any) {

  await transform({
    translateApiUrl: 'https://t.song.work/api',
    text: item.text,
    from: 'zh-CN',
    to: item.type
  }, sourceList);
}

/**
 * @param {*} { translateApiUrl: 翻译APi地址， text: 需要翻译的文本， from: 源语言， to: 目标语言, separator: 词组分割符}
 * @returns
 */

function transform({
  translateApiUrl,
  text,
  from,
  to,
}: TranslatehData, sourceList: any) {
  return axios({
    url: translateApiUrl,
    method: 'get',
    params: {
      text:text,
      from:from,
      to
    },
    paramsSerializer: function (params) {
      return qs.stringify(params, { arrayFormat: 'indices' });
    },
  })
    .then(async (res: any) => {
      TranslateData.push(res.data.result);
      sourceList.splice(0, 1);
      if (sourceList.length > 0) {
        await initResult({
          text: sourceList[0],
          type: to
        }, sourceList)
      } else {
        spinner.succeed(chalk.green(`${to}语言包翻译成功`))
         RewritConfig(JSON.parse(i18ndata), TranslateData.join('').split('**'), to, 0,[])

      }
      return res.data.result;
    })
    .catch((err: any) => {
      console.log(`Translation error, Check that the API is available: ${err}`);
    });
}
export const getSourceListText = (sourceStr: string, limit: number) => {
  // 切割整理的多维数组文件
  let len = sourceStr.length;
  let index = 0;
  // eslint-disable-next-line no-empty
  if (limit) { }
  const chunkSplitLimitList = [];

  while (len > 0) {
    const end = index + limit;
    const str = sourceStr.slice(index, end);
    chunkSplitLimitList.push(str);
    index = end;
    len = len - limit;
  }
  return chunkSplitLimitList;
}











// 翻译的核心命令
async function execTranslate(options: TranslatehHandler) {
  spinner = ora('Loading unicorns').start()
  translate(options as TranslatehHandler)
}

export default execTranslate
