<?php
/**
 * PeachPay Log Download Handler.
 *
 * Serves PeachPay log entries filtered by date/time range as downloadable file.
 *
 * @package PeachPay
 */

if ( ! defined( 'PEACHPAY_ABSPATH' ) ) {
	exit;
}

/**
 * Handles download of PeachPay logs by date/time range.
 */
class PeachPay_Log_Download {

	/**
	 * Log handle (source) for PeachPay.
	 */
	const LOG_HANDLE = 'peachpay';

	/**
	 * Initialize the download handler.
	 */
	public static function init() {
		add_action( 'admin_post_peachpay_download_logs', array( __CLASS__, 'handle_download' ) );
	}

	/**
	 * Handle the log download request.
	 */
	public static function handle_download() {
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			wp_die( esc_html__( 'You do not have permission to download logs.', 'peachpay-for-woocommerce' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
		if ( ! wp_verify_nonce( $nonce, 'peachpay_download_logs' ) ) {
			wp_die( esc_html__( 'Security check failed.', 'peachpay-for-woocommerce' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$from_date = isset( $_GET['from_date'] ) ? sanitize_text_field( wp_unslash( $_GET['from_date'] ) ) : gmdate( 'Y-m-d' );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$from_time = isset( $_GET['from_time'] ) ? sanitize_text_field( wp_unslash( $_GET['from_time'] ) ) : '00:00';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$to_date = isset( $_GET['to_date'] ) ? sanitize_text_field( wp_unslash( $_GET['to_date'] ) ) : gmdate( 'Y-m-d' );
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$to_time = isset( $_GET['to_time'] ) ? sanitize_text_field( wp_unslash( $_GET['to_time'] ) ) : gmdate( 'H:i' );

		$from_ts = strtotime( $from_date . ' ' . $from_time );
		$to_ts   = strtotime( $to_date . ' ' . $to_time );

		if ( false === $from_ts || false === $to_ts || $from_ts > $to_ts ) {
			wp_die( esc_html__( 'Invalid date range.', 'peachpay-for-woocommerce' ) );
		}

		$content = self::get_logs_in_range( $from_ts, $to_ts );
		$filename = sprintf(
			'peachpay-%s-%s-to-%s-%s.log',
			gmdate( 'Y-m-d', $from_ts ),
			str_replace( ':', '', $from_time ),
			gmdate( 'Y-m-d', $to_ts ),
			str_replace( ':', '', $to_time )
		);

		header( 'Content-Type: text/plain; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
		header( 'Cache-Control: no-cache, no-store, must-revalidate' );
		header( 'Pragma: no-cache' );
		header( 'Expires: 0' );
		header( 'Content-Length: ' . strlen( $content ) );

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $content;
		exit;
	}

	/**
	 * Get PeachPay log entries within the given timestamp range.
	 *
	 * @param int $from_ts Start timestamp.
	 * @param int $to_ts   End timestamp.
	 * @return string Log content.
	 */
	private static function get_logs_in_range( $from_ts, $to_ts ) {
		if ( ! defined( 'WC_LOG_DIR' ) ) {
			return __( 'WooCommerce log directory not available.', 'peachpay-for-woocommerce' ) . "\n";
		}

		$log_dir = trailingslashit( WC_LOG_DIR );
		$files   = is_dir( $log_dir ) ? scandir( $log_dir ) : array();
		$lines   = array();

		if ( ! empty( $files ) ) {
			foreach ( $files as $file ) {
				if ( '.' === $file || '..' === $file || strpos( $file, self::LOG_HANDLE . '-' ) !== 0 || substr( $file, -4 ) !== '.log' ) {
					continue;
				}
				$path = $log_dir . $file;
				if ( ! is_readable( $path ) ) {
					continue;
				}
				$content = file_get_contents( $path );
				if ( false === $content ) {
					continue;
				}
				$file_lines = explode( "\n", $content );
				foreach ( $file_lines as $line ) {
					$line = trim( $line );
					if ( '' === $line ) {
						continue;
					}
					$ts = self::parse_log_line_timestamp( $line );
					if ( null !== $ts && $ts >= $from_ts && $ts <= $to_ts ) {
						$lines[] = array( 'ts' => $ts, 'line' => $line );
					}
				}
			}
		}

		usort( $lines, function ( $a, $b ) {
			return $a['ts'] - $b['ts'];
		} );

		$output = '';
		foreach ( $lines as $item ) {
			$output .= $item['line'] . "\n";
		}

		if ( '' === $output ) {
			$output = sprintf(
				/* translators: 1: from date/time, 2: to date/time */
				__( 'No PeachPay logs found between %1$s and %2$s.', 'peachpay-for-woocommerce' ),
				gmdate( 'Y-m-d H:i', $from_ts ),
				gmdate( 'Y-m-d H:i', $to_ts )
			) . "\n";
		}

		return $output;
	}

	/**
	 * Parse timestamp from a WooCommerce log line.
	 * Format: "2026-02-06T14:30:00+00:00 INFO message"
	 *
	 * @param string $line Log line.
	 * @return int|null Unix timestamp or null if unparseable.
	 */
	private static function parse_log_line_timestamp( $line ) {
		// WooCommerce uses date('c') = ISO 8601, e.g. 2026-02-06T14:30:00+00:00
		if ( preg_match( '/^(\d{4}-\d{2}-\d{2}T[\d:.+-]+)\s+/', $line, $m ) ) {
			$ts = strtotime( $m[1] );
			return false !== $ts ? $ts : null;
		}
		// Legacy format: 02-06-2026 @ 14:30:00
		if ( preg_match( '/^(\d{2}-\d{2}-\d{4}\s+@\s+[\d:]+)\s+/', $line, $m ) ) {
			$ts = strtotime( str_replace( ' @ ', ' ', $m[1] ) );
			return false !== $ts ? $ts : null;
		}
		return null;
	}
}
