• Exports skipped tracks data to CSV

    Creates a comprehensive CSV export of all skipped tracks in the user's listening history, including track metadata and skip statistics. This function formats the skip data into a tabular structure optimized for analysis in spreadsheet applications or data visualization tools.

    The export includes:

    • Track identification (ID, name, artist, album)
    • Skip frequency metrics (total, manual, automatic)
    • Temporal information (first skip, most recent skip)

    The function handles the entire export process including:

    • Retrieving and validating skip data
    • Transforming complex data structures into CSV-compatible format
    • Prompting for save location (if not provided)
    • Writing data with proper error handling

    Parameters

    • mainWindow: BrowserWindow

      The Electron BrowserWindow to attach dialogs to

    • OptionaltargetPath: string

      Optional pre-defined export path (bypasses user prompt)

    Returns Promise<{ success: boolean; message?: string; filePath?: string }>

    Promise resolving to object containing success status, message, and path

    // Export with user prompt for location
    const result = await exportSkippedTracksToCSV(mainWindow);
    if (result.success) {
    showSuccessMessage(`Exported to ${result.filePath}`);
    } else {
    showErrorMessage(result.message);
    }
    // Export to specific path without prompt
    const path = join(app.getPath('downloads'), 'skipped-tracks.csv');
    const result = await exportSkippedTracksToCSV(mainWindow, path);
    export async function exportSkippedTracksToCSV(
    mainWindow: BrowserWindow,
    targetPath?: string,
    ): Promise<{ success: boolean; message?: string; filePath?: string }> {
    try {
    // Get skipped tracks data
    const skippedTracks = await getSkippedTracks();

    if (!skippedTracks || skippedTracks.length === 0) {
    return {
    success: false,
    message: "No skipped tracks data available to export",
    };
    }

    // Define headers for CSV
    const headers = {
    id: "Track ID",
    name: "Track Name",
    artist: "Artist",
    albumName: "Album",
    skipCount: "Skip Count",
    lastSkipped: "Last Skipped At",
    firstSkipped: "First Skipped At",
    manualSkipCount: "Manual Skips",
    autoSkipCount: "Auto Skips",
    };

    // Prepare data for CSV
    const csvData = skippedTracks.map((track) => ({
    id: track.id,
    name: track.name,
    artist: track.artist,
    albumName: track.albumName || "",
    skipCount: track.skipCount || 0,
    lastSkipped: track.lastSkipped || "",
    firstSkipped:
    track.skipEvents && track.skipEvents.length > 0
    ? track.skipEvents[0].timestamp
    : "",
    manualSkipCount: track.manualSkipCount || 0,
    autoSkipCount: track.autoSkipCount || 0,
    }));

    // Convert to CSV
    const csv = objectToCSV(csvData, headers);

    // Determine file path
    let filePath = targetPath;
    if (!filePath) {
    const timestamp = new Date()
    .toISOString()
    .replace(/:/g, "-")
    .split(".")[0];
    const defaultFileName = `skipped_tracks_${timestamp}.csv`;

    filePath = await promptForExportLocation(
    mainWindow,
    join(ensureExportDir(), defaultFileName),
    [{ name: "CSV Files", extensions: ["csv"] }],
    );

    if (!filePath) {
    return { success: false, message: "Export was canceled" };
    }
    }

    // Write the CSV file
    writeFileSync(filePath, csv);

    return {
    success: true,
    message: "Skipped tracks data exported successfully",
    filePath,
    };
    } catch (error) {
    console.error("Error exporting skipped tracks to CSV:", error);
    return {
    success: false,
    message: `Error exporting data: ${error instanceof Error ? error.message : "Unknown error"}`,
    };
    }
    }