<?php
/**
 * 404 Monitor module.
 *
 * @since      1.0
 * @package    RankMathPro
 * @subpackage RankMathPro\Admin
 * @author     Rank Math <support@rankmath.com>
 */

namespace RankMathPro;

use RankMath\Helper;
use RankMath\Traits\Hooker;
use MyThemeShop\Helpers\Param;

defined( 'ABSPATH' ) || exit;

/**
 * Monitor class.
 *
 * @codeCoverageIgnore
 */
class Monitor_Pro {

	use Hooker;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->filter( 'rank_math/404_monitor/page_title_actions', 'page_title_actions', 20, 1 );
		$this->action( 'rank_math/404_monitor/before_list_table', 'export_panel', 20 );
		$this->action( 'admin_enqueue_scripts', 'enqueue', 20 );
		$this->action( 'init', 'maybe_export', 20 );
	}

	/**
	 * Add page title action for export.
	 *
	 * @param array $actions Original actions.
	 * @return array
	 */
	public function page_title_actions( $actions ) {
		$actions['export'] = [
			'class' => 'page-title-action',
			'href'  => add_query_arg( 'export-404', '1' ),
			'label' => __( 'Export', 'rank-math-pro' ),
		];

		return $actions;
	}

	/**
	 * Output export panel.
	 *
	 * @return void
	 */
	public function export_panel() {
		$today = date( 'Y-m-d' );
		?>
		<div class="rank-math-box rank-math-export-404-panel <?php echo Param::get( 'export-404' ) ? '' : 'hidden'; ?>">
			<h3><?php esc_html_e( 'Export 404 Logs', 'rank-math-pro' ); ?></h3>
			<p class="description">
				<?php esc_html_e( 'Export and download 404 logs from a selected period of time in the form of a CSV file. Leave the from/to fields empty to export all logs.', 'rank-math-pro' ); ?>
			</p>
			<form action="" method="get" autocomplete="off">
				<input type="hidden" name="action" value="rank_math_export_404">
				<?php wp_nonce_field( 'export_404' ); ?>

				<label for="rank_math_export_404_date_from">
					<span>
						<?php esc_html_e( 'From date', 'rank-math-pro' ); ?>
					</span>
					<input type="text" name="date_from" value="" id="rank_math_export_404_date_from" class="rank-math-datepicker" placeholder="<?php echo esc_attr( $today ); ?>">
				</label>
				<label for="rank_math_export_404_date_to">
					<span>
						<?php esc_html_e( 'To date', 'rank-math-pro' ); ?>
					</span>
					<input type="text" name="date_to" value="" id="rank_math_export_404_date_to" class="rank-math-datepicker" placeholder="<?php echo esc_attr( $today ); ?>">
				</label>
				<div class="rank_math_export_404_submit_wrap">
					<input type="submit" value="<?php esc_attr_e( 'Export', 'rank-math-pro' ); ?>" class="button button-primary">
				</div>
			</form>
		</div>
		<?php
	}

	/**
	 * Undocumented function
	 *
	 * @return void
	 */
	public function maybe_export() {
		if ( Param::get( 'action' ) !== 'rank_math_export_404' ) {
			return;
		}

		if ( ! current_user_can( 'export' ) || ! Helper::has_cap( '404_monitor' ) ) {
			// Todo: add error notice instead of wp_die()?
			wp_die( esc_html__( 'Sorry, your user does not seem to have the necessary capabilities to export.', 'rank-math-pro' ) );
		}

		if ( wp_verify_nonce( Param::get( '_nonce' ), 'export_404' ) ) {
			// Todo: add error notice instead of wp_die()?
			wp_die( esc_html__( 'Nonce error. Please try again.', 'rank-math-pro' ) );
		}

		$date_from = $this->sanitize_datetime( Param::get( 'date_from' ) );
		$date_to   = $this->sanitize_datetime( Param::get( 'date_to' ) );

		$this->headers();
		$this->export_items( $date_from, $date_to );
		die();
	}

	/**
	 * Send headers to start export file download.
	 *
	 * @return void
	 */
	private function headers() {
		$sitename = sanitize_key( get_bloginfo( 'name' ) );
		$filename = $sitename . '_404-log-' . date( 'Y-m-d_H-i-s' ) . '.csv';

		header( 'Content-Type: application/csv' );
		header( 'Content-Description: File Transfer' );
		header( "Content-Disposition: attachment; filename={$filename}" );
		header( 'Pragma: no-cache' );
	}

	/**
	 * Do export.
	 *
	 * @param  string $time_from Start date (SQL DateTime format).
	 * @param  string $time_to   End date (SQL DateTime format).
	 * 
	 * @return void
	 */
	private function export_items( $time_from = null, $time_to = null ) {
		global $wpdb;
		$logs_table = $wpdb->prefix . 'rank_math_404_logs';
		$query = "SELECT * FROM {$logs_table} WHERE 1=1";
		$where = '';
		if ( $time_from ) {
			$where .= " AND accessed > '{$time_from} 00:00:01'";
		}
		if ( $time_to ) {
			$where .= " AND accessed < '{$time_to} 23:59:59'";
		}
		$query .= $where;
		$items = $wpdb->get_results( $query, ARRAY_A );

		if ( empty( $items ) ) {
			return;
		}

		$columns = array_keys( $items[0] );
		$this->output_csv( $columns );
		foreach ( $items as $line ) {
			$this->output_csv( array_values( $line ) );
		}
	}

	/**
	 * Output fputcsv instead of saving to a file.
	 *
	 * @param array $data Data array.
	 * @return void
	 */
	public function output_csv( $data ) {
		$out = fopen( 'php://output', 'w' );
		fputcsv( $out, $data );
		fclose( $out );
	}

	/**
	 * Sanitize date field inputs.
	 *
	 * @param string $date Date input.
	 * @return string
	 */
	public function sanitize_datetime( $date ) {
		return preg_replace( '/[^0-9 :-]/', '', $date );
	}

	/**
	 * Enqueue styles and scripts.
	 *
	 * @param  string $hook Page hook prefix.
	 *
	 * @return void
	 */
	public function enqueue( $hook ) {
		if ( ! is_admin() || Param::get( 'page' ) !== 'rank-math-404-monitor' ) {
			return;
		}

		wp_enqueue_script( 'rank-math-pro-404-monitor', RANK_MATH_PRO_URL . 'assets/admin/js/404-monitor.js', [ 'jquery-ui-core', 'jquery-ui-datepicker' ], RANK_MATH_PRO_VERSION, true );
		wp_enqueue_style( 'rank-math-pro-404-monitor', RANK_MATH_PRO_URL . 'assets/admin/css/404-monitor.css', [], RANK_MATH_PRO_VERSION );
	}

}
