<?php

defined( 'ABSPATH' ) || exit;

class ZACLS_Export {

	public static function export_login_attempts( $args = array() ) {
		global $wpdb;

		$where  = array( '1=1' );
		$params = array();

		if ( ! empty( $args['status'] ) ) {
			$where[]  = 'status = %s';
			$params[] = sanitize_text_field( $args['status'] );
		}
		if ( ! empty( $args['ip'] ) ) {
			$where[]  = 'ip = %s';
			$params[] = sanitize_text_field( $args['ip'] );
		}
		if ( ! empty( $args['days'] ) ) {
			$where[]  = 'attempt_time >= %s - INTERVAL %d DAY';
			$params[] = current_time( 'mysql' );
			$params[] = absint( $args['days'] );
		}

		$sql = "SELECT * FROM {$wpdb->prefix}zacls_login_attempts";
		if ( count( $where ) > 1 ) {
			$sql .= ' WHERE ' . implode( ' AND ', $where );
		}
		$sql    .= ' ORDER BY attempt_time DESC'; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$results = $wpdb->get_results( $wpdb->prepare( $sql, $params ), ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery,PluginCheck.Security.DirectDB.UnescapedDBParameter

		if ( empty( $results ) ) {
			wp_die( esc_html__( 'No data to export.', 'za-creative-login-shield' ) );
		}

		$format = isset( $args['format'] ) ? $args['format'] : 'csv';
		if ( ! in_array( $format, array( 'csv', 'json', 'pdf' ), true ) ) {
			$format = 'csv';
		}

		if ( 'json' === $format ) {
			self::send_json( $results, 'zacls-login-attempts.json' );
		} elseif ( 'pdf' === $format ) {
			self::send_pdf_report( $args );
		} else {
			$headers = array(
				__( 'ID', 'za-creative-login-shield' ),
				__( 'IP Address', 'za-creative-login-shield' ),
				__( 'Username', 'za-creative-login-shield' ),
				__( 'User ID', 'za-creative-login-shield' ),
				__( 'Status', 'za-creative-login-shield' ),
				__( 'User Agent', 'za-creative-login-shield' ),
				__( 'Country Code', 'za-creative-login-shield' ),
				__( 'Device ID', 'za-creative-login-shield' ),
				__( 'Date/Time', 'za-creative-login-shield' ),
			);
			self::send_csv( 'zacls-login-attempts.csv', $headers, $results );
		}
	}

	public static function export_blocked_ips( $format = 'csv' ) {
		global $wpdb;

		if ( ! in_array( $format, array( 'csv', 'json' ), true ) ) {
			$format = 'csv';
		}

		$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}zacls_blocked_ips ORDER BY blocked_at DESC", ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery
		if ( empty( $results ) ) {
			wp_die( esc_html__( 'No data to export.', 'za-creative-login-shield' ) );
		}

		if ( 'json' === $format ) {
			self::send_json( $results, 'zacls-blocked-ips.json' );
		} else {
			$headers = array(
				__( 'ID', 'za-creative-login-shield' ),
				__( 'IP Address', 'za-creative-login-shield' ),
				__( 'Type', 'za-creative-login-shield' ),
				__( 'Reason', 'za-creative-login-shield' ),
				__( 'Blocked At', 'za-creative-login-shield' ),
				__( 'Expires At', 'za-creative-login-shield' ),
			);
			self::send_csv( 'zacls-blocked-ips.csv', $headers, $results );
		}
	}

	public static function export_report( $days = 30, $format = 'pdf' ) {
		if ( ! in_array( $format, array( 'csv', 'json', 'pdf' ), true ) ) {
			$format = 'pdf';
		}
		$days = min( max( (int) $days, 1 ), 365 );

		if ( 'pdf' === $format ) {
			$html = ZACLS_PDF::generate_login_report( $days );
			ZACLS_PDF::generate( $html, 'zacls-security-report.pdf' );
		} elseif ( 'json' === $format ) {
			$data = array(
				'stats'        => ZACLS_Analytics::get_summary_stats( $days ),
				'activity'     => ZACLS_Analytics::get_login_activity( min( $days, 30 ) ),
				'attackers'    => ZACLS_Analytics::get_top_attackers( 10, $days ),
				'health'       => ZACLS_Health::calculate_score(),
				'generated_at' => current_time( 'mysql' ),
			);
			self::send_json( $data, 'zacls-security-report.json' );
		} else {
			$stats = ZACLS_Analytics::get_summary_stats( $days );
			$headers = array(
				__( 'Metric', 'za-creative-login-shield' ),
				__( 'Value', 'za-creative-login-shield' ),
			);
			$data = array(
				array( __( 'Total Attempts', 'za-creative-login-shield' ), $stats['total'] ),
				array( __( 'Failed', 'za-creative-login-shield' ), $stats['failed'] ),
				array( __( 'Successful', 'za-creative-login-shield' ), $stats['success'] ),
				array( __( 'Blocked IPs', 'za-creative-login-shield' ), $stats['blocked'] ),
				array( __( 'Unique IPs', 'za-creative-login-shield' ), $stats['unique_ips'] ),
				array( __( 'Attack Rate', 'za-creative-login-shield' ), $stats['attack_rate'] . '%' ),
			);
			self::send_csv( 'zacls-security-report.csv', $headers, $data, false );
		}
	}

	private static function send_csv( $filename, $headers, $data, $use_keys = true ) {
		if ( ob_get_level() ) {
			ob_end_clean();
		}

		nocache_headers();
		header( 'Content-Type: text/csv; charset=UTF-8' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
		header( 'Expires: 0' );

		$lines = array();
		$header_cells = array();
		foreach ( $headers as $h ) {
			$header_cells[] = '"' . str_replace( '"', '""', $h ) . '"';
		}
		$lines[] = implode( ',', $header_cells );

		foreach ( $data as $row ) {
			$cells = array();
			if ( $use_keys ) {
				foreach ( $headers as $h ) {
					$key   = self::get_header_key( $h );
					$value = isset( $row[ $key ] ) ? $row[ $key ] : '';
					$value = self::neutralize_csv_cell( $value );
					$cells[] = '"' . str_replace( '"', '""', $value ) . '"';
				}
			} else {
				foreach ( $row as $cell ) {
					$cell = self::neutralize_csv_cell( $cell );
					$cells[] = '"' . str_replace( '"', '""', $cell ) . '"';
				}
			}
			$lines[] = implode( ',', $cells );
		}

		echo implode( "\r\n", $lines ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV file download, not HTML
		wp_die( '', '', array( 'response' => 200 ) );
	}

	/**
	 * Prevent CSV formula injection by prefixing dangerous leading characters.
	 *
	 * @param mixed $value Cell value.
	 * @return string Neutralized value.
	 */
	private static function neutralize_csv_cell( $value ) {
		$value = (string) $value;
		if ( '' === $value ) {
			return $value;
		}
		$first = $value[0];
		if ( in_array( $first, array( '=', '+', '-', '@', "\t", "\r" ), true ) ) {
			$value = "'" . $value;
		}
		return $value;
	}

	private static function send_json( $data, $filename ) {
		if ( ob_get_level() ) {
			ob_end_clean();
		}

		nocache_headers();
		header( 'Content-Type: application/json; charset=UTF-8' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '"' );

		echo wp_json_encode( $data, JSON_PRETTY_PRINT );
		wp_die( '', '', array( 'response' => 200 ) );
	}

	private static function send_pdf_report( $args ) {
		$days = isset( $args['days'] ) ? absint( $args['days'] ) : 30;
		$html = ZACLS_PDF::generate_login_report( $days );
		ZACLS_PDF::generate( $html, 'zacls-login-attempts.pdf' );
	}

	private static function get_header_key( $header ) {
		$map = array(
			__( 'ID', 'za-creative-login-shield' )        => 'id',
			__( 'IP Address', 'za-creative-login-shield' ) => 'ip',
			__( 'Username', 'za-creative-login-shield' )  => 'username',
			__( 'User ID', 'za-creative-login-shield' )   => 'user_id',
			__( 'Status', 'za-creative-login-shield' )    => 'status',
			__( 'User Agent', 'za-creative-login-shield' ) => 'user_agent',
			__( 'Country Code', 'za-creative-login-shield' ) => 'country_code',
			__( 'Device ID', 'za-creative-login-shield' ) => 'device_id',
			__( 'Date/Time', 'za-creative-login-shield' ) => 'attempt_time',
			__( 'Type', 'za-creative-login-shield' )      => 'type',
			__( 'Reason', 'za-creative-login-shield' )    => 'reason',
			__( 'Blocked At', 'za-creative-login-shield' ) => 'blocked_at',
			__( 'Expires At', 'za-creative-login-shield' ) => 'expires_at',
		);
		return isset( $map[ $header ] ) ? $map[ $header ] : sanitize_key( $header );
	}
}
