/**
 * Global Table Import/Export Utility
 * Handles CSV/JSON export and import for any table-based page
 * 
 * Usage:
 * ```typescript
 * import { useTableImportExport } from '../../utils/table-import-export';
 * 
 * const { handleExport, handleImport } = useTableImportExport({
 *   endpoint: '/v1/planner/keywords/export/',
 *   filename: 'keywords',
 *   columns: columns, // Column config from TablePageTemplate
 *   filters: filterValues, // Current filter values
 * });
 * ```
 */

import { API_BASE_URL } from '../services/api';

export interface ExportConfig {
  endpoint: string;
  filename: string;
  format?: 'csv' | 'json';
  columns?: Array<{ key: string; label: string }>;
  filters?: Record<string, any>;
}

export interface ImportConfig {
  endpoint: string;
  acceptedFormats?: string[];
  maxFileSize?: number;
  queryParams?: Record<string, any>; // Additional query params (e.g., site_id, sector_id)
  onSuccess?: (result: any) => void;
  onError?: (error: Error) => void;
}

/**
 * Build export URL with filters as query parameters
 */
export const buildExportUrl = (config: ExportConfig): string => {
  const params = new URLSearchParams();
  
  // Add filters as query params
  if (config.filters) {
    Object.entries(config.filters).forEach(([key, value]) => {
      if (value !== '' && value !== null && value !== undefined) {
        params.append(key, String(value));
      }
    });
  }

  const queryString = params.toString();
  const endpoint = config.endpoint.endsWith('/') 
    ? config.endpoint 
    : `${config.endpoint}/`;
  
  const fullUrl = `${API_BASE_URL}${endpoint}${queryString ? `?${queryString}` : ''}`;
  
  
  return fullUrl;
};

/**
 * Export table data to CSV or JSON
 */
export const exportTableData = async (
  config: ExportConfig,
  onProgress?: (progress: string) => void,
  onError?: (error: Error) => void
): Promise<void> => {
  const format = config.format || 'csv';
  const url = buildExportUrl(config);


  onProgress?.(`Exporting ${format.toUpperCase()}...`);

  try {
    const response = await fetch(url, {
      method: 'GET',
      credentials: 'include',
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Export failed: ${response.statusText} - ${errorText}`);
    }

    const blob = await response.blob();
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = `${config.filename}.${format}`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);

    onProgress?.(`Export successful: ${config.filename}.${format}`);
  } catch (error) {
    const err = error instanceof Error ? error : new Error('Export failed');
    onError?.(err);
    throw err;
  }
};

/**
 * Import table data from file
 */
export const importTableData = async (
  file: File,
  config: ImportConfig,
  onProgress?: (progress: string) => void,
  onError?: (error: Error) => void
): Promise<any> => {
  // Validate file format
  const acceptedFormats = config.acceptedFormats || ['.csv'];
  const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
  
  if (!acceptedFormats.includes(fileExtension)) {
    const error = new Error(
      `Invalid file format. Accepted formats: ${acceptedFormats.join(', ')}`
    );
    onError?.(error);
    throw error;
  }

  // Validate file size
  const maxSize = config.maxFileSize || 5 * 1024 * 1024; // 5MB default
  if (file.size > maxSize) {
    const error = new Error(`File size exceeds ${maxSize / 1024 / 1024}MB limit`);
    onError?.(error);
    throw error;
  }

  onProgress?.(`Importing ${file.name}...`);

  const formData = new FormData();
  formData.append('file', file);

  try {
    const endpoint = config.endpoint.endsWith('/') 
      ? config.endpoint 
      : `${config.endpoint}/`;
    
    // Build query string from queryParams
    const params = new URLSearchParams();
    if (config.queryParams) {
      Object.entries(config.queryParams).forEach(([key, value]) => {
        if (value !== '' && value !== null && value !== undefined) {
          params.append(key, String(value));
        }
      });
    }
    
    const queryString = params.toString();
    const url = `${API_BASE_URL}${endpoint}${queryString ? `?${queryString}` : ''}`;
    
    const response = await fetch(url, {
      method: 'POST',
      body: formData,
      credentials: 'include',
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Import failed: ${response.statusText} - ${errorText}`);
    }

    const result = await response.json();
    onProgress?.(`Import successful: ${result.imported || 0} rows imported`);
    config.onSuccess?.(result);
    return result;
  } catch (error) {
    const err = error instanceof Error ? error : new Error('Import failed');
    onError?.(err);
    throw err;
  }
};

/**
 * React hook for table import/export functionality
 */
export const useTableImportExport = (exportConfig: ExportConfig) => {
  const handleExport = async (
    format: 'csv' | 'json' = 'csv',
    onProgress?: (progress: string) => void,
    onError?: (error: Error) => void
  ) => {
    await exportTableData(
      { ...exportConfig, format },
      onProgress,
      onError
    );
  };

  const handleImport = async (
    file: File,
    importConfig: ImportConfig,
    onProgress?: (progress: string) => void,
    onError?: (error: Error) => void
  ) => {
    return await importTableData(file, importConfig, onProgress, onError);
  };

  return {
    handleExport,
    handleImport,
  };
};

/**
 * Generate CSV from table data (client-side fallback)
 * Used when backend doesn't provide export endpoint
 */
export const generateCSVFromTable = (
  data: any[],
  columns: Array<{ key: string; label: string }>,
  filename: string = 'export'
): void => {
  // Create header row
  const headers = columns.map((col) => col.label).join(',');
  
  // Create data rows
  const rows = data.map((row) =>
    columns
      .map((col) => {
        const value = row[col.key];
        // Escape commas and quotes in CSV
        const stringValue = value?.toString() || '';
        if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
          return `"${stringValue.replace(/"/g, '""')}"`;
        }
        return stringValue;
      })
      .join(',')
  );

  const csvContent = [headers, ...rows].join('\n');
  
  // Create download
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const downloadUrl = window.URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = downloadUrl;
  link.download = `${filename}.csv`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  window.URL.revokeObjectURL(downloadUrl);
};

