<?php
/**
 * ExportHandler
 *
 * Handles CSV export of statistics data.
 *
 * @package Relatedly\Admin\Statistics
 * @since   2.0.0
 * @since   2.3.0 Added full workbook export with summary, display-type breakdown,
 *                top clicked, top sources, and daily statistics.
 */

namespace Relatedly\Admin\Statistics;

use Relatedly\Core\Cache;
use Relatedly\Premium\FeatureGate;

defined( 'ABSPATH' ) || exit;

/**
 * Streams statistics CSV exports.
 *
 * @since 2.0.0
 * @since 2.3.0 Streams a richer multi-section CSV workbook.
 */
class ExportHandler {

	/**
	 * Statistics data provider.
	 *
	 * @since 2.0.0
	 * @var DataProvider
	 */
	private DataProvider $data;

	/**
	 * Create the export handler.
	 *
	 * @since 2.0.0
	 * @param Cache $cache Cache service.
	 */
	public function __construct( Cache $cache ) {
		$this->data = new DataProvider( $cache );
	}

	/**
	 * Register export admin-post handler.
	 *
	 * @since 2.0.0
	 */
	public function init_hooks(): void {
		add_action( 'admin_post_relatedly_export_csv', [ $this, 'handle_export' ] );
	}

	/**
	 * Stream a CSV file for the requested date range.
	 *
	 * @since 2.0.0
	 * @since 2.3.0 Export a multi-section workbook instead of a single top-posts sheet.
	 */
	public function handle_export(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied.', 'relatedly' ) );
		}

		if ( ! FeatureGate::can_export_statistics() ) {
			wp_die( esc_html__( 'Statistics export is a premium feature.', 'relatedly' ) );
		}

		if ( ! wp_verify_nonce(
			sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ?? '' ) ),
			'relatedly_export_csv'
		) ) {
			wp_die( esc_html__( 'Security check failed.', 'relatedly' ) );
		}

		$start = sanitize_text_field( wp_unslash( $_GET['start_date'] ?? gmdate( 'Y-m-d', strtotime( '-30 days' ) ) ) );
		$end   = sanitize_text_field( wp_unslash( $_GET['end_date'] ?? gmdate( 'Y-m-d' ) ) );

		$summary     = $this->data->get_summary( $start, $end );
		$top_clicked = $this->data->get_top_clicked( $start, $end, 500 );
		$top_sources = $this->data->get_top_sources( $start, $end, 500 );
		$daily       = $this->data->get_daily_counts( $start, $end );

		$filename = 'relatedly-stats-' . $start . '-to-' . $end . '.csv';

		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
		header( 'Pragma: no-cache' );
		header( 'Expires: 0' );

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
		$out = fopen( 'php://output', 'w' );

		// UTF-8 BOM for Excel compatibility.
		fprintf( $out, "\xEF\xBB\xBF" );

		// Header.
		fputcsv( $out, [ __( 'Relatedly Statistics Export', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Date Range', 'relatedly' ), $start . ' — ' . $end ] );
		fputcsv( $out, [] );

		// Summary section.
		fputcsv( $out, [ __( 'Summary', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Metric', 'relatedly' ), __( 'Value', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Total Clicks', 'relatedly' ), $summary['total_clicks'] ] );
		fputcsv( $out, [ __( 'Total Impressions', 'relatedly' ), $summary['total_impressions'] ] );
		fputcsv( $out, [ __( 'Overall CTR', 'relatedly' ), $summary['ctr'] . '%' ] );
		fputcsv( $out, [] );

		// Display-type breakdown.
		fputcsv( $out, [ __( 'Performance by Display Type', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Display Type', 'relatedly' ), __( 'Clicks', 'relatedly' ), __( 'Impressions', 'relatedly' ), __( 'CTR', 'relatedly' ) ] );
		foreach ( $summary['breakdown'] as $type => $metrics ) {
			fputcsv( $out, [ $type, $metrics['clicks'], $metrics['impressions'], $metrics['ctr'] . '%' ] );
		}
		fputcsv( $out, [] );

		// Top clicked posts.
		fputcsv( $out, [ __( 'Top Clicked Posts', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Post Title', 'relatedly' ), __( 'Post ID', 'relatedly' ), __( 'Clicks', 'relatedly' ), __( 'Impressions', 'relatedly' ), __( 'CTR', 'relatedly' ) ] );
		foreach ( $top_clicked as $row ) {
			fputcsv( $out, [ $row['title'], $row['post_id'], $row['clicks'], $row['impressions'], $row['ctr'] . '%' ] );
		}
		fputcsv( $out, [] );

		// Top source posts.
		fputcsv( $out, [ __( 'Top Source Posts', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Post Title', 'relatedly' ), __( 'Post ID', 'relatedly' ), __( 'Clicks Generated', 'relatedly' ), __( 'Impressions', 'relatedly' ), __( 'CTR', 'relatedly' ) ] );
		foreach ( $top_sources as $row ) {
			fputcsv( $out, [ $row['title'], $row['post_id'], $row['clicks'], $row['impressions'], $row['ctr'] . '%' ] );
		}
		fputcsv( $out, [] );

		// Daily statistics.
		fputcsv( $out, [ __( 'Daily Statistics', 'relatedly' ) ] );
		fputcsv( $out, [ __( 'Date', 'relatedly' ), __( 'Clicks', 'relatedly' ), __( 'Impressions', 'relatedly' ), __( 'CTR', 'relatedly' ) ] );
		foreach ( $daily as $row ) {
			$day_ctr = $row['impressions'] > 0 ? round( ( $row['clicks'] / $row['impressions'] ) * 100, 2 ) : 0.0;
			fputcsv( $out, [ $row['date'], $row['clicks'], $row['impressions'], $day_ctr . '%' ] );
		}

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
		fclose( $out );
		exit;
	}
}
