import { Injectable } from '@nestjs/common';
import { Response } from 'express';
import * as ExcelJS from 'exceljs';
import { ExportFormat, ExportOptions } from './export.types';

@Injectable()
export class ExportService {
  async export(options: ExportOptions, res: Response): Promise<void> {
    const { filename, sheetName = 'Sheet1', columns, data, format } = options;

    const workbook = new ExcelJS.Workbook();
    const sheet = workbook.addWorksheet(sheetName);

    sheet.columns = columns.map((col) => ({
      header: col.header,
      key: col.key,
      width: col.width ?? 20,
    }));

    // Style header row
    const headerRow = sheet.getRow(1);
    headerRow.eachCell((cell) => {
      if (cell.value !== null && cell.value !== undefined && cell.value !== '') {
        cell.font = { bold: true, color: { argb: 'FF000000' } };
        cell.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: 'FFD4A843' },
        };
        cell.alignment = { vertical: 'middle', horizontal: 'center' };
      }
    });
    headerRow.height = 20;

    // Add data rows — replace any null/undefined/empty with '-'
    data.forEach((rowData) => {
      const sanitized = Object.fromEntries(
        Object.entries(rowData).map(([k, v]) => [
          k,
          v === null || v === undefined || v === '' ? '-' : v,
        ]),
      );
      sheet.addRow(sanitized);
    });

    // Apply percent format to columns marked as percent
    columns.forEach((col, colIndex) => {
      if (col.isPercent) {
        sheet.getColumn(colIndex + 1).numFmt = '0.00%';
      }
    });

    // Border all cells including empty ones
    const totalRows = sheet.rowCount;
    const totalCols = columns.length;

    for (let r = 1; r <= totalRows; r++) {
      for (let c = 1; c <= totalCols; c++) {
        const cell = sheet.getRow(r).getCell(c);
        cell.border = {
          top: { style: 'thin' },
          left: { style: 'thin' },
          bottom: { style: 'thin' },
          right: { style: 'thin' },
        };
      }
    }

    if (format === ExportFormat.XLSX) {
      res.setHeader(
        'Content-Type',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      );
      res.setHeader('Content-Disposition', `attachment; filename="${filename}.xlsx"`);
      await workbook.xlsx.write(res);
    } else {
      res.setHeader('Content-Type', 'text/csv; charset=utf-8');
      res.setHeader('Content-Disposition', `attachment; filename="${filename}.csv"`);
      await workbook.csv.write(res);
    }

    res.end();
  }
}