import * as ExcelJS from "exceljs";
import path from "path";
import { ExcelExport } from "spartaxx.businessmodels/Common/ExcelExport";
import fs from "fs";

export const ExportExcel = async (options: ExcelExport): Promise<any> => {

  let outputString: string | null = null;
  let result: { SharedPath: string; ServerUrl: string } | null = null;
  const { data, columnsList, fileExportConfig, isFileTypeBase64, sheetName = "Sheet1" } = options;

  try {

    const workbook = new ExcelJS.Workbook();

    const worksheet = workbook.addWorksheet(sheetName);

    worksheet.columns = columnsList.map(col => ({
      header: col.DisplayName,
      key: col.ModelPropertyName,
      width: 20,
    }));

    const filteredData = data.map(item => {
      const filteredRow: Record<string, any> = {};
      columnsList.forEach(col => {
        filteredRow[col.ModelPropertyName] = item[col.ModelPropertyName];
      });
      return filteredRow;
    });

    filteredData.forEach(row => {
      worksheet.addRow(row);
    });

    const headerRow = worksheet.getRow(1);
    headerRow.eachCell({ includeEmpty: true }, cell => {
      cell.font = { bold: true };
      cell.fill = {
        type: 'pattern',
        pattern: 'solid',
        fgColor: { argb: 'FFFF00' }
      };
    });

    const lastRowNumber = worksheet.lastRow?.number || 1;
    const lastColumnNumber = worksheet.columns.length;

    for (let rowIndex = 1; rowIndex <= lastRowNumber; rowIndex++) {
      const row = worksheet.getRow(rowIndex);
      for (let colIndex = 1; colIndex <= lastColumnNumber; colIndex++) {
        const cell = row.getCell(colIndex);
        cell.border = {
          top: { style: 'thin', color: { argb: 'FF000000' } },
          left: { style: 'thin', color: { argb: 'FF000000' } },
          bottom: { style: 'thin', color: { argb: 'FF000000' } },
          right: { style: 'thin', color: { argb: 'FF000000' } }
        };
      }
    }

    worksheet.columns.forEach(column => {
      if (column.eachCell) {
        let maxLength = column.header ? column.header.toString().length : 20;
        column.eachCell({ includeEmpty: true }, cell => {
          const cellValue = cell.value ? cell.value.toString() : "";
          maxLength = Math.max(maxLength, cellValue.length);
        });
        column.width = maxLength + 2;
      }
    });

    if (isFileTypeBase64) {
      const buffer = await workbook.xlsx.writeBuffer();
      outputString = Buffer.from(buffer).toString('base64');
    }
    else {
      const fileName = fileExportConfig && fileExportConfig != null ?
        fileExportConfig.FileName?.replace("@@datetimestamp@@", await getFileTimestamp()) : "";
      const exportExcelFilePath = fileExportConfig && fileExportConfig != null ?
        `${fileExportConfig.AppDirName}${fileExportConfig.ExportDirName}${fileName}` : "";
      const downloadExcelUrl = fileExportConfig && fileExportConfig != null ?
        `${fileExportConfig.AppBaseURL}${fileExportConfig.ExportDirName}${fileName}` : "";
      const directoryPath = path.dirname(exportExcelFilePath);
      await fs.promises.mkdir(directoryPath, { recursive: true });
      await workbook.xlsx.writeFile(exportExcelFilePath);
      result = {
        SharedPath: exportExcelFilePath,
        ServerUrl: downloadExcelUrl
      }
    }

  }
  catch (error) {
    console.log("Failed");
    outputString = null;
    result = null;
  }

  return isFileTypeBase64 ? outputString : result;
};

async function getFileTimestamp(): Promise<string> {
  const currentDate: Date = new Date();
  const year = currentDate.getFullYear();
  const month = ('0' + (currentDate.getMonth() + 1)).slice(-2);
  const day = ('0' + currentDate.getDate()).slice(-2);
  const hours = ('0' + currentDate.getHours()).slice(-2);
  const minutes = ('0' + currentDate.getMinutes()).slice(-2);
  const seconds = ('0' + currentDate.getSeconds()).slice(-2);
  return `${year}${month}${day}${hours}${minutes}${seconds}`;
}