• Exports time patterns to CSV

    Creates a specialized CSV export focused on temporal listening patterns, providing insights into how listening behavior varies by time of day, day of week, and across different time periods. This export is particularly valuable for identifying rhythms and patterns in user engagement.

    The export includes multiple interconnected sections:

    • Hourly distribution of skips and plays throughout the day
    • Daily distribution across the week with pattern identification
    • Session metrics showing how listening is clustered in time
    • Skip rate variations by time period

    The CSV format uses section headers and multi-part organization to present related data in a coherent structure, making it suitable for both visual inspection and programmatic analysis in spreadsheet applications.

    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 time patterns for visualization
    const result = await exportTimePatternsToCSV(mainWindow);
    if (result.success) {
    openVisualizationTool(result.filePath);
    } else {
    showExportError(result.message);
    }
    export async function exportTimePatternsToCSV(
    mainWindow: BrowserWindow,
    targetPath?: string,
    ): Promise<{ success: boolean; message?: string; filePath?: string }> {
    try {
    // Get time patterns
    const timePatterns = await analyzeTimeBasedPatterns();

    if (!timePatterns) {
    return {
    success: false,
    message: "No time patterns data available to export",
    };
    }

    // For time patterns, we'll create multiple sections

    // Hourly distribution
    const hourlyHeaders = {
    hour: "Hour of Day",
    skips: "Skips",
    plays: "Plays",
    skipRate: "Skip Rate",
    };

    const hourlyData = [];
    if (timePatterns.hourlyDistribution) {
    for (let i = 0; i < 24; i++) {
    const skipsData = Array.isArray(timePatterns.hourlyDistribution)
    ? timePatterns.hourlyDistribution[i] || 0
    : 0;

    hourlyData.push({
    hour: `${i}:00-${i + 1}:00`,
    skips: skipsData,
    plays: 0, // This data isn't in the current hourlyDistribution model
    skipRate: 0, // Needs to be calculated differently
    });
    }
    }

    // Daily distribution
    const dailyHeaders = {
    day: "Day of Week",
    skips: "Skips",
    plays: "Plays",
    skipRate: "Skip Rate",
    };

    const dayNames = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    ];
    const dailyData = [];

    if (timePatterns.dayOfWeekDistribution) {
    for (let i = 0; i < 7; i++) {
    const skipsData = Array.isArray(timePatterns.dayOfWeekDistribution)
    ? timePatterns.dayOfWeekDistribution[i] || 0
    : 0;

    dailyData.push({
    day: dayNames[i],
    skips: skipsData,
    plays: 0, // This data isn't in the current model
    skipRate: 0, // Needs to be calculated differently
    });
    }
    }

    // Create the CSV by combining sections
    let csvContent = "TIME-BASED PATTERNS\n\n";

    // Add hourly distribution
    csvContent += "HOURLY DISTRIBUTION\n";
    csvContent += objectToCSV(hourlyData, hourlyHeaders);

    // Add daily distribution
    csvContent += "\n\nDAILY DISTRIBUTION\n";
    csvContent += objectToCSV(dailyData, dailyHeaders);

    // Add session metrics if available - session metrics aren't part of the TimePatterns type yet
    const sessionMetrics = {
    avgDuration: 0,
    avgTracks: 0,
    avgSkips: 0,
    avgTimeBetween: 0,
    };

    if (sessionMetrics) {
    csvContent += "\n\nSESSION METRICS\n";
    csvContent += `Average session duration: ${sessionMetrics.avgDuration || 0} ms\n`;
    csvContent += `Average tracks per session: ${sessionMetrics.avgTracks || 0}\n`;
    csvContent += `Average skips per session: ${sessionMetrics.avgSkips || 0}\n`;
    csvContent += `Average time between sessions: ${sessionMetrics.avgTimeBetween || 0} ms\n`;
    }

    // Determine file path
    let filePath = targetPath;
    if (!filePath) {
    const timestamp = new Date()
    .toISOString()
    .replace(/:/g, "-")
    .split(".")[0];
    const defaultFileName = `time_patterns_${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, csvContent);

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