// Copy utilities for log management

import { StructuredLog } from '@/components/JobDevTools';

/**
 * Format a single log entry for copying as plain text
 * Format: [TIMESTAMP] [LEVEL] [CATEGORY] MESSAGE
 * Includes metrics/network data if present
 */
export function formatLogForCopy(log: StructuredLog): string {
  const timestamp = formatTimestamp(log.timestamp);
  let line = `[${timestamp}] [${log.level}] [${log.category}] ${log.message}`;

  // Include metrics if present
  if (log.metrics && Object.keys(log.metrics).length > 0) {
    line += `\n    metrics: ${JSON.stringify(log.metrics)}`;
  }

  // Include network data if present
  if (log.network && Object.keys(log.network).length > 0) {
    line += `\n    network: ${JSON.stringify(log.network)}`;
  }

  return line;
}

/**
 * Format multiple logs for copying as plain text
 * Joins logs with newlines and includes a header with count
 */
export function formatLogsForCopy(logs: StructuredLog[]): string {
  if (logs.length === 0) {
    return 'No logs to copy.';
  }

  const header = `=== ${logs.length} Log${logs.length !== 1 ? 's' : ''} ===`;
  const separator = '='.repeat(header.length);
  const formattedLogs = logs.map(formatLogForCopy).join('\n');

  return `${header}\n${separator}\n${formattedLogs}\n${separator}`;
}

/**
 * Copy text to clipboard with fallback for older browsers
 * Returns true if copy was successful, false otherwise
 */
export async function copyToClipboard(text: string): Promise<boolean> {
  // Try modern Clipboard API first
  if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch (err) {
      console.warn('Clipboard API failed, trying fallback:', err);
    }
  }

  // Fallback to execCommand for older browsers
  try {
    const textArea = document.createElement('textarea');
    textArea.value = text;

    // Make the textarea invisible
    textArea.style.position = 'fixed';
    textArea.style.left = '-9999px';
    textArea.style.top = '-9999px';
    textArea.style.opacity = '0';

    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();

    const success = document.execCommand('copy');
    document.body.removeChild(textArea);

    return success;
  } catch (err) {
    console.error('Fallback copy failed:', err);
    return false;
  }
}

/**
 * Format logs as pretty-printed JSON for export
 */
export function formatLogsAsJson(logs: StructuredLog[]): string {
  const exportData = {
    exportedAt: new Date().toISOString(),
    count: logs.length,
    logs: logs.map((log) => ({
      timestamp: log.timestamp,
      timestamp_ms: log.timestamp_ms,
      level: log.level,
      category: log.category,
      message: log.message,
      ...(log.metrics && { metrics: log.metrics }),
      ...(log.network && { network: log.network }),
    })),
  };

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

/**
 * Format logs as CSV for export
 * Includes headers and properly escapes values
 */
export function formatLogsAsCsv(logs: StructuredLog[]): string {
  if (logs.length === 0) {
    return 'timestamp,timestamp_ms,level,category,message,metrics,network';
  }

  const headers = ['timestamp', 'timestamp_ms', 'level', 'category', 'message', 'metrics', 'network'];
  const headerRow = headers.join(',');

  const rows = logs.map((log) => {
    const values = [
      escapeCsvValue(log.timestamp),
      log.timestamp_ms.toString(),
      log.level,
      log.category,
      escapeCsvValue(log.message),
      escapeCsvValue(log.metrics ? JSON.stringify(log.metrics) : ''),
      escapeCsvValue(log.network ? JSON.stringify(log.network) : ''),
    ];
    return values.join(',');
  });

  return [headerRow, ...rows].join('\n');
}

/**
 * Download content as a file
 */
export function downloadAsFile(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;
  link.style.display = 'none';

  document.body.appendChild(link);
  link.click();

  // Clean up
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

/**
 * Get file extension and MIME type for a format
 */
export function getExportFileInfo(format: ExportFormat): { extension: string; mimeType: string } {
  switch (format) {
    case 'json':
      return { extension: 'json', mimeType: 'application/json' };
    case 'csv':
      return { extension: 'csv', mimeType: 'text/csv' };
    case 'text':
    default:
      return { extension: 'txt', mimeType: 'text/plain' };
  }
}

/**
 * Format logs based on export format
 */
export function formatLogsForExport(logs: StructuredLog[], format: ExportFormat): string {
  switch (format) {
    case 'json':
      return formatLogsAsJson(logs);
    case 'csv':
      return formatLogsAsCsv(logs);
    case 'text':
    default:
      return formatLogsForCopy(logs);
  }
}

// Helper functions

/**
 * Format timestamp for display
 */
function formatTimestamp(timestamp: string): string {
  try {
    const date = new Date(timestamp);
    return date.toLocaleTimeString('en-US', {
      hour12: false,
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      fractionalSecondDigits: 3,
    });
  } catch {
    return timestamp;
  }
}

/**
 * Escape a value for CSV (handles quotes and commas)
 */
function escapeCsvValue(value: string): string {
  if (!value) return '';

  // If value contains comma, newline, or quote, wrap in quotes and escape internal quotes
  if (value.includes(',') || value.includes('\n') || value.includes('"')) {
    return `"${value.replace(/"/g, '""')}"`;
  }

  return value;
}

// Types
export type ExportFormat = 'text' | 'json' | 'csv';
