<?php
/**
 * HTML Report Generator.
 *
 * @package mwp-al-ext
 */

namespace WSAL\MainWPExtension\Extensions\Reports;

use WSAL\MainWPExtension\Utilities\DateTimeFormatter;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * HTML report generator class.
 */
class HTML_Report_Generator extends Abstract_Report_Generator {

	/**
	 * Report Filters.
	 *
	 * @var array
	 */
	private $filters = array();

	/**
	 * Generate the HTML report file
	 *
	 * @param array $data         - Data.
	 * @param array $filters      - Filters.
	 * @param array $alert_groups - Alert Groups.
	 * @return int|string
	 */
	public function generate( array $data, array $filters, array $alert_groups = array() ) {
		if ( empty( $data ) ) {
			return 0;
		}

		if ( empty( $filters ) ) {
			return 0;
		}

		$this->filters = $filters;

		// Split data by blog so we can display an organized report.
		$temp_data = array();

		foreach ( $data as $entry ) {
			$blog_name = $entry['blog_name'];

			if ( isset( $entry['site_id'] ) && ! $entry['site_id'] ) {
				$user = get_user_by( 'login', $entry['user_name'] );

				if ( ! empty( $user ) ) {
					$entry['user_firstname'] = $user->first_name;
					$entry['user_lastname']  = $user->last_name;
				} else {
					$entry['user_firstname'] = '';
					$entry['user_lastname']  = '';
				}
			} else {
				if ( isset( $entry['user_data'] ) && $entry['user_data'] ) {
					$entry['user_firstname'] = isset( $entry['user_data']['first_name'] ) ? $entry['user_data']['first_name'] : false;
					$entry['user_lastname']  = isset( $entry['user_data']['last_name'] ) ? $entry['user_data']['last_name'] : false;
				} else {
					$entry['user_firstname'] = '';
					$entry['user_lastname']  = '';
				}
			}

			if ( ! isset( $temp_data[ $blog_name ] ) ) {
				$temp_data[ $blog_name ] = array();
			}

			array_push( $temp_data[ $blog_name ], $entry );
		}

		if ( empty( $temp_data ) ) {
			return 0;
		}

		// Check directory once more.
		$uploads_dir_path = MWPAL_REPORTS_UPLOAD_PATH;
		if ( ! is_dir( $uploads_dir_path ) || ! is_readable( $uploads_dir_path ) || ! is_writable( $uploads_dir_path ) ) {
			return 1;
		}

		$filename = 'wsal_report_' . generate_random_string() . '.html';
		$filepath = str_replace( MWPAL_UPLOADS_DIR, '', MWPAL_REPORTS_UPLOAD_PATH ) . $filename;

		$file  = '';
		$file .= '<!DOCTYPE html><html><head>';
		$file .= '<meta charset="utf-8">';
		$file .= '<title>' . __( 'WP Activity Log Reporter', 'mwp-al-ext' ) . '</title>';
		$file .= '<style>@media print { td.message { min-width: 400px; } }</style>';
		$file .= '</head>';
		$file .= '<body style=\'margin: 0 0;padding: 0 0;font-family: "Open Sans", sans-serif;font-size: 14px;color: #404040;\'><div class="wsal_report_wrap" style="margin: 20px 25px;">';
		$file .= $this->write_header( array_keys( $temp_data ), $alert_groups );

		foreach ( $temp_data as $blog_name => $alerts ) {
			$file .= $this->write_alerts_for_blog( $blog_name, $alerts );
		}

		$file .= '</div></body></html>';
		\WSAL\MainWPExtension\write_to_extension_upload( $filepath, $file, true );

		return $filename;
	}

	/**
	 * Generate the HTML head of the Report.
	 *
	 * @param array $blog_names   - Array of site names.
	 * @param array $alert_groups - Group of alerts.
	 */
	private function write_header( array $blog_names, $alert_groups ) {
		$str  = '<div id="section-1" style="margin: 0 0; padding: 0 0;text-align: center;">';
		$str .= '<h1 style="color: rgb(54,95, 145);">' . __( 'Report from', 'mwp-al-ext' ) . ' ' . get_bloginfo( 'name' ) . ' ' . __( 'website', 'mwp-al-ext' ) . '</h1>';
		$str .= '</div>';

		$date = DateTimeFormatter::instance()->getFormattedDateTime( time() );

		$user = wp_get_current_user();
		$str .= '<div id="section-2" style="margin: 0 0; padding: 0 0;">';
		$str .= '<p style="margin: 0 0; padding: 5px 0; font-size: 13px;border-bottom: solid 1px #333;"><strong>' . __( 'Report Details:', 'mwp-al-ext' ) . '</strong></p>';
		$str .= '<p style="margin: 0 0; padding: 5px 0; font-size: 13px;"><strong>' . __( 'Generated on:', 'mwp-al-ext' ) . '</strong> ' . $date . '</p>';
		$str .= '<p style="margin: 0 0; padding: 5px 0; font-size: 13px;"><strong>' . __( 'Generated by:', 'mwp-al-ext' ) . '</strong> ' . $user->user_login . ' — ' . $user->user_email . '</p>';

		$filters = $this->filters;

		$theader  = '<table class="wsal_report_table" style="border: solid 1px #333333;border-spacing:5px;border-collapse: collapse;margin: 0 0;width: 100%;font-size: 14px;">';
		$theader .= '<thead style="background-color: #555555;border: 1px solid #555555;color: #ffffff;padding: 0 0;text-align: left;vertical-align: top;"><tr>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Site(s)', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'User(s)', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Role(s)', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'IP address(es)', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Alert Groups', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Alert Code(s)', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Start date', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'End date', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Post Types', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . __( 'Post Status', 'mwp-al-ext' ) . '</p></td>';
		$theader .= '</tr></thead>';

		$v1 =
		$v2 =
		$v3 =
		$v4 =
		$v5 =
		$v6 = __( 'All', 'mwp-al-ext' );
		$v7 = __( 'From the beginning', 'mwp-al-ext' );
		$v8 = $this->getFormattedDate( current_time( 'timestamp' ) );
		$v9 =
		$v10 = __( 'All', 'mwp-al-ext' );

		if ( ! empty( $filters['sites'] ) ) {
			$v1 = implode( ', ', $blog_names );
		}

		if ( ! empty( $filters['users'] ) ) {
			$tmp = array();

			foreach ( $filters['users'] as $user_id ) {
				$u = get_user_by( 'id', $user_id );

				if ( $u && $u instanceof WP_User ) {
					array_push( $tmp, $u->user_login . ' — ' . $u->user_email );
				}
			}

			$v2 = implode( ',<br>', $tmp );
		}

		if ( ! empty( $filters['roles'] ) ) {
			$v3 = implode( ', ', $filters['roles'] );
		}

		if ( ! empty( $filters['ip-addresses'] ) ) {
			$v4 = implode( ', ', $filters['ip-addresses'] );
		}

		if ( ! empty( $filters['alert_codes']['groups'] ) ) {
			if ( count( $alert_groups ) <> count( $filters['alert_codes']['groups'] ) ) {
				$v5 = implode( ', ', $filters['alert_codes']['groups'] );
			}
		}

		if ( ! empty( $filters['alert_codes']['alerts'] ) ) {
			$v6 = implode( ', ', $filters['alert_codes']['alerts'] );
		}

		if ( ! empty( $filters['date_range']['start'] ) ) {
			$v7 = $filters['date_range']['start'];
		}

		if ( ! empty( $filters['date_range']['end'] ) ) {
			$v8 = $filters['date_range']['end'];
		}

		if ( ! empty( $filters['alert_codes']['post_types'] ) ) {
			$post_types = array_map( 'ucfirst', $filters['alert_codes']['post_types'] );
			$v9         = implode( ', ', $post_types );
		}

		if ( ! empty( $filters['alert_codes']['post_statuses'] ) ) {
			$post_statuses = array_map( 'ucfirst', $filters['alert_codes']['post_statuses'] );
			$v10           = implode( ', ', $post_statuses );
		}

		$str .= '<p><strong>' . __( 'Criteria', 'mwp-al-ext' ) . ':</strong></p>';

		$tbody  = '<tbody><tr>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v1 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v2 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v3 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v4 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v5 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v6 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v7 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v8 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v9 . '</td>';
		$tbody .= '<td style="padding: 16px 7px;">' . $v10 . '</td>';
		$tbody .= '</tr></tbody>';
		$tbody .= '</table>';

		$str .= $theader . $tbody;

		$str .= '</div>';
		return $str;
	}

	/**
	 * Generate the HTML body of the standard Report.
	 *
	 * @param string $blog_name - Blog name.
	 * @param array  $data      - Data.
	 *
	 * @return string
	 */
	private function write_alerts_for_blog( $blog_name, array $data ) {
		$file_str  = '<h3 style="font-size: 20px; margin: 25px 0;">' . $blog_name . '</h3>';
		$file_str .= '<table class="wsal_report_table" style="border: solid 1px #333333;border-spacing:5px;border-collapse: collapse;margin: 0 0;width: 100%;font-size: 14px;">';

		$columns = array(
			__( 'Code', 'mwp-al-ext' ),
			__( 'Type', 'mwp-al-ext' ),
			__( 'Date', 'mwp-al-ext' ),
			__( 'Username', 'mwp-al-ext' ),
			__( 'User', 'mwp-al-ext' ),
			__( 'Role', 'mwp-al-ext' ),
			__( 'Source IP', 'mwp-al-ext' ),
			__( 'Message', 'mwp-al-ext' ),
		);

		$h = '';
		foreach ( $columns as $item ) {
			$h .= '<td style="padding: 16px 7px;"><p style="margin: 0">' . $item . '</p></td>';
		}

		$file_str .= '<thead style="background-color: #555555;border: 1px solid #555555;color: #ffffff;padding: 0 0;text-align: left;vertical-align: top;"><tr>' . $h . '</tr></thead>';
		$file_str .= '<tbody>';

		foreach ( $data as $i => $alert ) {
			$formattedDateTime = DateTimeFormatter::instance()->getFormattedDateTime( $alert['timestamp'] );
			$file_str          .= ( 0 !== $i % 2 ) ? '<tr style="background-color: #f1f1f1;">' : '<tr style="background-color: #ffffff;">';
			$file_str          .= '<td style="padding: 16px 7px; text-align: center; font-weight: 700;">' . $alert['alert_id'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px;">' . $alert['code'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px;">' . $formattedDateTime . '</td>';
			$file_str          .= '<td style="padding: 16px 7px;">' . $alert['user_name'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px; min-width: 100px;">' . $alert['user_firstname'] . ' ' . $alert['user_lastname'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px;">' . $alert['role'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px;">' . $alert['user_ip'] . '</td>';
			$file_str          .= '<td style="padding: 16px 7px; word-break: break-all; line-height: 1.5;" class="message">' . $alert['message'] . '</td>';
			$file_str          .= '</tr>';
		}

		$file_str .= '</tbody></table>';
		return $file_str;
	}
}
