• Set up IPC handlers for statistics functionality

    Establishes all IPC channels needed for statistics collection, retrieval, and management between the renderer process and main process.

    Parameters

    • mainWindow: BrowserWindow

      The main application window instance for IPC communication

    Returns void

    export function setupStatisticsIPC(mainWindow: BrowserWindow) {
    // Collection service controls
    // Handler to check if metrics collection is active
    ipcMain.handle("statistics:isCollectionActive", () => {
    return isSkipMetricsCollectionActive();
    });

    // Handler to start metrics collection
    ipcMain.handle(
    "statistics:startCollection",
    async (_event, intervalMinutes = DEFAULT_COLLECTION_INTERVAL) => {
    try {
    await startSkipMetricsCollection(intervalMinutes);
    return { success: true };
    } catch (error: unknown) {
    saveLog(`Error starting metrics collection: ${String(error)}`, "ERROR");
    return { success: false, error: String(error) };
    }
    },
    );

    // Handler to stop metrics collection
    ipcMain.handle("statistics:stopCollection", () => {
    try {
    stopSkipMetricsCollection();
    return { success: true };
    } catch (error: unknown) {
    saveLog(`Error stopping metrics collection: ${String(error)}`, "ERROR");
    return { success: false, error: String(error) };
    }
    });

    // Handler to manually trigger aggregation
    ipcMain.handle("statistics:triggerAggregation", async () => {
    try {
    await triggerManualAggregation();
    return { success: true };
    } catch (error: unknown) {
    saveLog(`Error during manual aggregation: ${String(error)}`, "ERROR");
    return { success: false, error: String(error) };
    }
    });

    // Handler for daily skip metrics
    ipcMain.handle("statistics:getDailySkipMetrics", async () => {
    try {
    const dailyMetricsFilePath = join(
    app.getPath("userData"),
    "data",
    "daily_skip_metrics.json",
    );

    if (!existsSync(dailyMetricsFilePath)) {
    return { success: false, error: "Daily metrics file not found" };
    }

    const dailyMetrics =
    readJsonSync(dailyMetricsFilePath, { throws: false }) || {};
    return { success: true, data: dailyMetrics };
    } catch (error: unknown) {
    saveLog(`Error retrieving daily skip metrics: ${String(error)}`, "ERROR");
    return { success: false, error: String(error) };
    }
    });

    // Handler for weekly skip metrics
    ipcMain.handle("statistics:getWeeklySkipMetrics", async () => {
    try {
    const weeklyMetricsFilePath = join(
    app.getPath("userData"),
    "data",
    "weekly_skip_metrics.json",
    );

    if (!existsSync(weeklyMetricsFilePath)) {
    return { success: false, error: "Weekly metrics file not found" };
    }

    const weeklyMetrics =
    readJsonSync(weeklyMetricsFilePath, { throws: false }) || {};
    return { success: true, data: weeklyMetrics };
    } catch (error: unknown) {
    saveLog(
    `Error retrieving weekly skip metrics: ${String(error)}`,
    "ERROR",
    );
    return { success: false, error: String(error) };
    }
    });

    // Handler for aggregating artist metrics
    ipcMain.handle("statistics:getArtistSkipMetrics", async () => {
    try {
    const artistMetrics = await aggregateArtistSkipMetrics();
    return { success: true, data: artistMetrics };
    } catch (error: unknown) {
    console.error("Error aggregating artist metrics:", error);
    return {
    success: false,
    error: error instanceof Error ? error.message : String(error),
    };
    }
    });

    // Get all statistics data
    ipcMain.handle("statistics:getAll", async () => {
    return await getStatistics();
    });

    // Get unique artist count
    ipcMain.handle("statistics:getUniqueArtistCount", async () => {
    const statistics = await getStatistics();
    return calculateUniqueArtistCount(statistics);
    });

    // Get skipped tracks
    ipcMain.handle("statistics:getSkippedTracks", async () => {
    return await getSkippedTracks();
    });

    // Aggregate daily metrics
    ipcMain.handle("statistics:getDailyMetrics", async () => {
    if (existsSync(DAILY_METRICS_FILE)) {
    return JSON.parse(readFileSync(DAILY_METRICS_FILE, "utf-8"));
    }
    return await aggregateDailySkipMetrics();
    });

    // Aggregate weekly metrics
    ipcMain.handle("statistics:getWeeklyMetrics", async () => {
    if (existsSync(WEEKLY_METRICS_FILE)) {
    return JSON.parse(readFileSync(WEEKLY_METRICS_FILE, "utf-8"));
    }
    return await aggregateWeeklySkipMetrics();
    });

    // Aggregate artist metrics
    ipcMain.handle("statistics:getArtistMetrics", async () => {
    if (existsSync(ARTIST_METRICS_FILE)) {
    return JSON.parse(readFileSync(ARTIST_METRICS_FILE, "utf-8"));
    }
    return await aggregateArtistSkipMetrics();
    });

    // Calculate library statistics
    ipcMain.handle("statistics:getLibraryStats", async () => {
    if (existsSync(LIBRARY_STATS_FILE)) {
    return JSON.parse(readFileSync(LIBRARY_STATS_FILE, "utf-8"));
    }
    return await calculateLibrarySkipStatistics();
    });

    // Analyze time-based patterns
    ipcMain.handle("statistics:getTimePatterns", async () => {
    if (existsSync(TIME_PATTERNS_FILE)) {
    return JSON.parse(readFileSync(TIME_PATTERNS_FILE, "utf-8"));
    }
    return await analyzeTimeBasedPatterns();
    });

    // Detect skip patterns
    ipcMain.handle("statistics:getSkipPatterns", async () => {
    if (existsSync(SKIP_PATTERNS_FILE)) {
    return JSON.parse(readFileSync(SKIP_PATTERNS_FILE, "utf-8"));
    }
    return await detectSkipPatterns();
    });

    // Get artist insights
    ipcMain.handle("statistics:getArtistInsights", async () => {
    if (existsSync(ARTIST_INSIGHTS_FILE)) {
    return JSON.parse(readFileSync(ARTIST_INSIGHTS_FILE, "utf-8"));
    }
    return await calculateArtistInsights();
    });

    // Export skipped tracks to CSV
    ipcMain.handle("statistics:exportSkippedTracksToCSV", async () => {
    return await exportSkippedTracksToCSV(mainWindow);
    });

    // Export artist metrics to CSV
    ipcMain.handle("statistics:exportArtistMetricsToCSV", async () => {
    return await exportArtistMetricsToCSV(mainWindow);
    });

    // Export daily metrics to CSV
    ipcMain.handle("statistics:exportDailyMetricsToCSV", async () => {
    return await exportDailyMetricsToCSV(mainWindow);
    });

    // Export weekly metrics to CSV
    ipcMain.handle("statistics:exportWeeklyMetricsToCSV", async () => {
    return await exportWeeklyMetricsToCSV(mainWindow);
    });

    // Export library statistics to CSV
    ipcMain.handle("statistics:exportLibraryStatisticsToCSV", async () => {
    return await exportLibraryStatisticsToCSV(mainWindow);
    });

    // Export time patterns to CSV
    ipcMain.handle("statistics:exportTimePatternsToCSV", async () => {
    return await exportTimePatternsToCSV(mainWindow);
    });

    // Export detected patterns to CSV
    ipcMain.handle("statistics:exportDetectedPatternsToCSV", async () => {
    return await exportDetectedPatternsToCSV(mainWindow);
    });

    // Export all statistics to JSON
    ipcMain.handle("statistics:exportAllToJSON", async () => {
    return await exportAllStatisticsToJSON(mainWindow);
    });

    // Copy statistics summary to clipboard
    ipcMain.handle("statistics:copyToClipboard", async () => {
    const statistics = await getStatistics();
    return copyStatisticsToClipboard(statistics);
    });
    }