import * as cheerio from 'cheerio';
import { ParsedDocument, SupportedFileExtension } from '../utils/types';
import { getValidExtensions } from '../firebase/cloudstore/uploadFile';
import csv from 'csvtojson';

const UTF8BytesPerCharacter = 3;

export function parseGoogleSheet(data: string) {
  const $ = cheerio.load(data)

  // Get the first table
  const table = $('table').first()
  const tableBody = table.find('tbody')
  const rows = tableBody.find('tr')

  // print all rows one by one
  rows.each((i: number, row: any) => {
    const cells = $(row).find('td')
    cells.each((j: number, cell: any) => {
      console.log($(cell).text())
    })
  })
}


export function parseUploadedFile(file: File, onProgress?: (p: number) => void) {

  const [extension, name] = file.name.split('.').reverse();

  const convert: { [e in SupportedFileExtension]: ((raw: string) => object) } = {
    [SupportedFileExtension.CSV]: convertCSVToObject,
    [SupportedFileExtension.JSON]: convertJSONToObject,
  }

  if (getValidExtensions().includes(extension.toLowerCase()) && name && name != "") {

    return new Promise<any>((resolve, reject) => {
      const fileReader = new FileReader();

      fileReader.onerror = function (error: any) {
        reject(error)
      }

      fileReader.onprogress = function (event) {
        if(onProgress && event.lengthComputable) {
          onProgress(Math.round(event.loaded / event.total))
        }
      }

      fileReader.onload = function () {
        if (fileReader.result == null) {
          reject("Unable to read file")
        } else {
          if (typeof fileReader.result == 'string') {
            try {
              resolve(
                checkFormat(
                  convert[extension as SupportedFileExtension](fileReader.result)
                )
              )
            } catch (error) {
              reject("Invalid format error: " + error)
            }

          } else {
            reject("Invalid reading method")
          }

        }
      };

      fileReader.readAsText(file);
    })

  } else {
    return new Promise<any>((_, reject) => reject('Unsupported file type (extension is ' + extension + ')'))
  }

}

async function convertCSVToObject(raw: string) {
  const jsonObj = await csv({output: 'json'}).fromString(raw)
  return jsonObj
}

function convertJSONToObject(raw: string) {
  return JSON.parse(raw)
}

function checkFormat(parsed: any): any {
  // throw new Error('Function not implemented.');
  return parsed
}

export function computeParsedData(result: object[]): ParsedDocument {
  const rows = result.length;
  const columns = Math.max(...result.map(row => Object.keys(row).length))
  return {
    data: result,
    columns,
    rows,
    size: JSON.stringify(result).length * UTF8BytesPerCharacter
  }
}
