const fs = require('fs');
const path = require('path');

const ExcelJS = require('exceljs');
const workbook = new ExcelJS.Workbook();

const HEADER_ROW_INDEX = 1;
const SOUND_COL_IDX = 5;
const IMAGE_COL_IDX = 6;
const CAT_NAME_IDX = 7;
const CAT_IMG_IDX = 8;

const TOOLS_HOME = path.resolve(__dirname);
const PROJ_HOME = path.resolve(path.join(TOOLS_HOME, '..', '..'));
const PUBLIC_DATA = path.resolve(path.join(PROJ_HOME, 'public', 'data'));
const LESSON_HOME = path.resolve(path.join(PUBLIC_DATA, 'Lesson'));
const QUIZ_HOME = path.resolve(path.join(PUBLIC_DATA, 'Quiz'));

const OUTPUT_LESSON_JSON_PATH = path.resolve(path.join(LESSON_HOME, 'content.json'));
const OUTPUT_LISTENING_PRACTICE_JSON_PATH = path.resolve(path.join(QUIZ_HOME, 'ListeningPractice', 'content.json'));
const OUTPUT_MATCHING_FRENZY_JSON_PATH = path.resolve(path.join(QUIZ_HOME, 'MatchingFrenzy', 'content.json'));
//
const VOCABULARY_ASSET_HOME = path.resolve(path.join(LESSON_HOME, 'v'));

const OUTPUT_IMAGE_PATH = path.resolve(path.join(VOCABULARY_ASSET_HOME, 'images'));
const OUTPUT_SOUND_PATH = path.resolve(path.join(VOCABULARY_ASSET_HOME, 'sounds'));
let source_json_content = JSON.parse(fs.readFileSync(OUTPUT_LESSON_JSON_PATH));

//

var output = [];
var listening_practice_output = [];
var all_categories = [];
var categories_found = [];

//

function checkFileExist(file_path) {
  let u_file_path = getUnderscoreFilename(file_path);
  if (!fs.existsSync(u_file_path)) {
    throw new Error(`resources file not found: ${u_file_path}`);
  }
  return;
}

function getCellValue(cell) {
  return cell ? cell.result || cell.value : '';
}

function getUnderscoreFilename(file_name) {
  return file_name.replace(/\s/g, '_');
}

function findLastRowIdx(ws) {
  for (let i = 1; i < 130; i++) {
    let test = getCellValue(ws.getRow(i).getCell(1));
    if (!test || test.trim() === '') {
      return i - 1;
    }
  }
  return 3000;
}

(async () => {
  await workbook.xlsx.readFile('lessons.xlsx');
  let worksheets = workbook.worksheets;
  //
  try {
    // check excel table
    for (const ws of worksheets) {
      //
      const first_data_row_idx = HEADER_ROW_INDEX + 1;
      const last_data_row_idx = findLastRowIdx(ws);
      //

      for (let i = first_data_row_idx; i <= last_data_row_idx; i++) {
        let sound_file_name = ws.getRow(i).getCell(SOUND_COL_IDX).value;
        let expected_sound_file_path = path.join('sounds', sound_file_name);
        checkFileExist(expected_sound_file_path);

        let image_file_name = ws.getRow(i).getCell(IMAGE_COL_IDX).value;
        let expected_image_file_path = path.join('images', image_file_name);
        checkFileExist(expected_image_file_path);
      }

      let temp = [];
      for (let i = first_data_row_idx; i <= last_data_row_idx; i++) {
        temp.push(getUnderscoreFilename(getCellValue(ws.getRow(i).getCell(CAT_IMG_IDX))));
      }
      temp = new Set(temp);
      for (const cat_img_file_name of temp) {
        let expected_cat_img_file_path = path.join('images', cat_img_file_name);
        checkFileExist(expected_cat_img_file_path);
      }
    }

    // gen output
    for (const ws of worksheets) {
      const first_data_row_idx = HEADER_ROW_INDEX + 1;
      const last_data_row_idx = findLastRowIdx(ws);
      //

      for (let i = first_data_row_idx; i <= last_data_row_idx; i++) {
        if (ws.getRow(i).getCell(CAT_NAME_IDX).value) {
          if (categories_found.indexOf(ws.getRow(i).getCell(CAT_NAME_IDX).value) === -1) {
            categories_found.push(ws.getRow(i).getCell(CAT_NAME_IDX).value);
          }
        }
      }

      for (const cat_name of categories_found) {
        let words = [];
        let cat_image = '';
        for (let i = first_data_row_idx; i <= last_data_row_idx; i++) {
          if (ws.getRow(i).getCell(CAT_NAME_IDX).value === cat_name) {
            let word = ws.getRow(i).getCell(1).value.trim();
            let word_c = ws.getRow(i).getCell(2).value.trim();
            let sample_e = ws.getRow(i).getCell(3).value.trim();
            let sample_c = ws.getRow(i).getCell(4).value.trim();
            let sound = `/data/Lesson/v/sounds/${getCellValue(ws.getRow(i).getCell(5))}`;
            let image = `/data/Lesson/v/images/${getCellValue(ws.getRow(i).getCell(6))}`;

            cat_image = `/data/Lesson/v/images/${getUnderscoreFilename(
              getCellValue(ws.getRow(i).getCell(CAT_IMG_IDX))
            )}`;

            words.push({
              word,
              word_c,
              sample_e,
              sample_c,
              sound,
              image
              //
            });
          }
        }

        all_categories.push({
          //
          cat_name,
          cat_image,
          content: words,
          init_answer: ['A', 'B', 'C']
        });
      }

      output = {
        name: ws.name,
        path: ws.name,
        content: all_categories
      };

      listening_practice_output = all_categories;
    }

    // fs.writeFileSync('output.json', JSON.stringify(output, null, 2));
    source_json_content[0] = output;

    console.log('copying image and sound files');
    fs.mkdirSync(OUTPUT_IMAGE_PATH, { recursive: true });
    fs.mkdirSync(OUTPUT_SOUND_PATH, { recursive: true });
    let copied = [];
    for (const ws of worksheets) {
      const first_data_row_idx = HEADER_ROW_INDEX + 1;
      const last_data_row_idx = findLastRowIdx(ws);

      for (let i = first_data_row_idx; i <= last_data_row_idx; i++) {
        let sound_file_name = getUnderscoreFilename(getCellValue(ws.getRow(i).getCell(SOUND_COL_IDX)));
        let expected_sound_file_path = path.join('sounds', sound_file_name);
        let target_sound_file_path = path.join(OUTPUT_SOUND_PATH, sound_file_name);
        fs.copyFileSync(expected_sound_file_path, target_sound_file_path);

        let image_file_name = getUnderscoreFilename(getCellValue(ws.getRow(i).getCell(IMAGE_COL_IDX)));
        let expected_image_file_path = path.join('images', image_file_name);
        let target_image_file_path = path.join(OUTPUT_IMAGE_PATH, image_file_name);
        fs.copyFileSync(expected_image_file_path, target_image_file_path);

        let ci_image_file_name = getUnderscoreFilename(getCellValue(ws.getRow(i).getCell(CAT_IMG_IDX)));
        if (copied.indexOf(ci_image_file_name) === -1) {
          let target_ci_image_file_path = path.join(OUTPUT_IMAGE_PATH, ci_image_file_name);
          let expected_ci_image_file_path = path.join('images', ci_image_file_name);
          fs.copyFileSync(expected_ci_image_file_path, target_ci_image_file_path);
          copied.push(ci_image_file_name);
        }
      }
    }

    console.log('writing output json file');
    fs.writeFileSync(OUTPUT_LESSON_JSON_PATH, JSON.stringify(source_json_content, null, 2));
    fs.writeFileSync(OUTPUT_LISTENING_PRACTICE_JSON_PATH, JSON.stringify(listening_practice_output, null, 2));
    fs.writeFileSync(OUTPUT_MATCHING_FRENZY_JSON_PATH, JSON.stringify(listening_practice_output, null, 2));

    console.log('import done');
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
})();
