import { Injectable, Logger } from '@nestjs/common';
import * as ExcelJS from 'exceljs';
import * as path from 'path';
import * as fs from 'fs';
import { ConfigService } from '@nestjs/config';

export interface ExcelColumn {
  header: string;
  key: string;
  width?: number;
}

export interface ExcelExportOptions {
  sheetName?: string;
  columns: ExcelColumn[];
  data: any[];
  title?: string;
  subtitle?: string;
}

@Injectable()
export class ExcelExportService {
  private readonly logger = new Logger(ExcelExportService.name);
  private readonly storagePath: string;

  constructor(private readonly configService: ConfigService) {
    this.storagePath = this.configService.get<string>(
      'FILE_STORAGE_PATH',
      './storage/reports',
    );
  }

  async export(
    fileName: string,
    options: ExcelExportOptions,
  ): Promise<{ filePath: string; fileSize: number }> {
    const workbook = new ExcelJS.Workbook();
    workbook.creator = 'Reporting Service';
    workbook.created = new Date();

    const worksheet = workbook.addWorksheet(options.sheetName || 'Report');

    // Add title if provided
    if (options.title) {
      worksheet.addRow([options.title]);
      worksheet.mergeCells(1, 1, 1, options.columns.length);
      const titleRow = worksheet.getRow(1);
      titleRow.font = { bold: true, size: 16 };
      titleRow.alignment = { horizontal: 'center' };
    }

    // Add subtitle if provided
    if (options.subtitle) {
      const subtitleRowNum = options.title ? 2 : 1;
      worksheet.addRow([options.subtitle]);
      worksheet.mergeCells(subtitleRowNum, 1, subtitleRowNum, options.columns.length);
      const subtitleRow = worksheet.getRow(subtitleRowNum);
      subtitleRow.font = { size: 12 };
      subtitleRow.alignment = { horizontal: 'center' };
    }

    // Add empty row before headers
    if (options.title || options.subtitle) {
      worksheet.addRow([]);
    }

    // Setup columns
    worksheet.columns = options.columns.map((col) => ({
      header: col.header,
      key: col.key,
      width: col.width || 15,
    }));

    // Style header row
    const headerRowNum = (options.title ? 1 : 0) + (options.subtitle ? 1 : 0) + (options.title || options.subtitle ? 1 : 0) + 1;
    const headerRow = worksheet.getRow(headerRowNum);
    headerRow.font = { bold: true };
    headerRow.fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFE0E0E0' },
    };

    // Add data rows
    options.data.forEach((row) => {
      worksheet.addRow(row);
    });

    // Ensure storage directory exists
    const fullPath = path.join(this.storagePath, fileName);
    const dir = path.dirname(fullPath);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }

    // Write file
    await workbook.xlsx.writeFile(fullPath);

    const stats = fs.statSync(fullPath);

    this.logger.log(`Excel file exported: ${fullPath} (${stats.size} bytes)`);

    return {
      filePath: fullPath,
      fileSize: stats.size,
    };
  }
}
