import { Injectable } from '@angular/core';
import * as FileSaver from "file-saver";
import * as ExcelJS from "exceljs/dist/exceljs.min.js";
const EXCEL_TYPE =
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";
const EXCEL_EXTENSION = ".xlsx";
@Injectable({
  providedIn: 'root'
})
export class ExcelService {

  constructor() { }

  public async exportAsExcelFile(workbookData: any[], excelFileName: string) {
    const workbook = new ExcelJS.Workbook();

    workbookData.forEach(({ workSheet, rows, properties }) => {
      const sheet = workbook.addWorksheet(workSheet, { state: properties == undefined ? "visible" : properties.state });
      const uniqueHeaders = [
        ...new Set(
          rows.reduce((prev, next) => [...prev, ...Object.keys(next)], [])
        )
      ];
      sheet.columns = uniqueHeaders.map(x => ({ header: x, key: x, width: 30, alignment: { wrapText: true }, filterButton: true }));
      rows.forEach((jsonRow, i) => {
        let cellValues = { ...jsonRow };

        uniqueHeaders.forEach((header: any, j) => {
          if (Array.isArray(jsonRow[header])) {
            cellValues[header] = "";
          }
        });
        sheet.addRow(cellValues);
        uniqueHeaders.forEach((header: any, j) => {

          if (header == "expiry_date" && Array.isArray(jsonRow[header])) {
            var jsonDropdown = jsonRow[header];
            sheet.getCell(
              this.getSpreadSheetCellNumber(i + 1, j)
            ).dataValidation = {
              type: "date",
              operator: 'greaterThan',
              formulae: [new Date(2000, 0, 1)],
              allowBlank: true,
              showErrorMessage: true,
              errorStyle: "error",
              errorTitle: "Error",
              error: "Please Enter valid Date"
            };
          }
          else {
            if (Array.isArray(jsonRow[header])) {
              var jsonDropdown = jsonRow[header];
              sheet.getCell(
                this.getSpreadSheetCellNumber(i + 1, j)
              ).dataValidation = {
                type: "list",
                formulae: [jsonRow[header]],
                allowBlank: true,
                showErrorMessage: true,
                errorStyle: "error",
                errorTitle: "Error",
                error: "Value must be in the list"
              };
            }
          }
        });
      });
    });

    const buffer = await workbook.xlsx.writeBuffer();
    this.saveAsExcelFile(buffer, excelFileName);
  }

  private getSpreadSheetCellNumber(row, column) {
    let result = "";
    let n = column;
    while (n >= 0) {
      result = String.fromCharCode((n % 26) + 65) + result;
      n = Math.floor(n / 26) - 1;
    }
    result += `${row + 1}`;

    return result;
  }

  private saveAsExcelFile(buffer: any, fileName: string): void {
    const data: Blob = new Blob([buffer], {
      type: EXCEL_TYPE
    });
    FileSaver.saveAs(
      data,
      fileName + new Date().getTime() + EXCEL_EXTENSION
    );
  }
}
