/**
 * Export utilities for DataTable component
 */

export type ExportFormat = 'csv' | 'json' | 'xlsx';

export interface ExportOptions {
  filename?: string;
  format: ExportFormat;
  columns?: string[];
  includeHeaders?: boolean;
}

/**
 * Convert data to CSV format
 */
export function dataToCSV<T extends Record<string, any>>(
  data: T[],
  columns?: string[],
  includeHeaders = true
): string {
  if (data.length === 0) return '';

  // Get columns from first item if not provided
  const cols = columns || Object.keys(data[0]);

  // Build CSV content
  const rows: string[] = [];

  // Add headers
  if (includeHeaders) {
    const headers = cols.map(col => {
      // Handle column names with special characters
      const value = String(col);
      return value.includes(',') || value.includes('"') || value.includes('\n')
        ? `"${value.replace(/"/g, '""')}"`
        : value;
    });
    rows.push(headers.join(','));
  }

  // Add data rows
  data.forEach(item => {
    const row = cols.map(col => {
      const value = item[col];
      
      // Handle different value types
      if (value === null || value === undefined) return '';
      if (value instanceof Date) return value.toISOString();
      if (typeof value === 'object') return JSON.stringify(value);
      
      const stringValue = String(value);
      return stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')
        ? `"${stringValue.replace(/"/g, '""')}"`
        : stringValue;
    });
    rows.push(row.join(','));
  });

  return rows.join('\n');
}

/**
 * Convert data to JSON format
 */
export function dataToJSON<T>(data: T[], columns?: string[]): string {
  if (!columns || columns.length === 0) {
    return JSON.stringify(data, null, 2);
  }

  // Filter data to include only specified columns
  const filteredData = data.map(item => {
    const filtered: Record<string, any> = {};
    columns.forEach(col => {
      if (col in (item as any)) {
        filtered[col] = (item as any)[col];
      }
    });
    return filtered;
  });

  return JSON.stringify(filteredData, null, 2);
}

/**
 * Download data as a file
 */
export function downloadFile(content: string, filename: string, mimeType: string): void {
  const blob = new Blob([content], { type: mimeType });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  
  // Cleanup
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

/**
 * Export data to the specified format
 */
export async function exportData<T extends Record<string, any>>(
  data: T[],
  options: ExportOptions
): Promise<void> {
  const { format, filename = 'data-export', columns, includeHeaders = true } = options;
  
  let content: string;
  let mimeType: string;
  let extension: string;

  switch (format) {
    case 'csv':
      content = dataToCSV(data, columns, includeHeaders);
      mimeType = 'text/csv;charset=utf-8;';
      extension = 'csv';
      break;
      
    case 'json':
      content = dataToJSON(data, columns);
      mimeType = 'application/json;charset=utf-8;';
      extension = 'json';
      break;
      
    case 'xlsx':
      // For XLSX, we'll need to use a library like xlsx or exceljs
      // For now, we'll throw an error indicating it's not implemented
      throw new Error('XLSX export requires additional dependencies. Use CSV format instead.');
      
    default:
      throw new Error(`Unsupported export format: ${format}`);
  }

  const finalFilename = `${filename}-${new Date().toISOString().split('T')[0]}.${extension}`;
  downloadFile(content, finalFilename, mimeType);
}

/**
 * Get visible columns from column definitions
 */
export function getVisibleColumns<T>(
  columns: Array<{ id?: string; accessorKey?: string; header?: any }>,
  columnVisibility: Record<string, boolean>
): string[] {
  return columns
    .filter(col => {
      const key = col.id || col.accessorKey;
      return key && columnVisibility[key] !== false;
    })
    .map(col => col.id || col.accessorKey!)
    .filter(Boolean);
}