<?php
/**
 * Staff Activity Report.
 *
 * A shareable, master-admin-only report summarising who did what over a chosen
 * period — built straight from Platform Helm's Activity Log (no second store).
 * The report can be emailed to the site administrator on demand.
 *
 * Access is capability-based (manage_options = the "master admin"); the email
 * is sent to the site's configured admin address — never a hardcoded one.
 *
 * @package Platform\Helm\Modules\Activity_Intelligence
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\Activity_Intelligence;

use Platform\Helm\Core\Authorization;
use Platform\Helm\Core\Ui;

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

final class StaffReportPage {

	public const PAGE_SLUG    = 'platform-helm-staff-report';
	public const PARENT_SLUG  = 'platform-helm';
	public const EMAIL_ACTION = 'platform_helm_staff_report_email';

	private const DEFAULT_DAYS = 30;

	public function register_hooks(): void {
		add_action( 'admin_menu', [ $this, 'register_menu' ], 51 );
		add_action( 'admin_post_' . self::EMAIL_ACTION, [ $this, 'handle_email' ] );
	}

	public function register_menu(): void {
		if ( ! Authorization::is_master_admin() ) {
			return;
		}
		add_submenu_page(
			self::PARENT_SLUG,
			__( 'Staff Report', 'platform-helm' ),
			__( 'Staff Report', 'platform-helm' ),
			Authorization::ADMIN_CAP,
			self::PAGE_SLUG,
			[ $this, 'render' ]
		);
	}

	private function table(): string {
		global $wpdb;
		return $wpdb->prefix . 'platform_helm_activity';
	}

	private function period_days(): int {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$d = isset( $_GET['period'] ) ? (int) $_GET['period'] : self::DEFAULT_DAYS;
		return max( 1, min( 365, $d ) );
	}

	/**
	 * Aggregate the Activity Log by user + action for the last $days.
	 *
	 * @return array<string,mixed>
	 */
	private function gather( int $days ): array {
		global $wpdb;
		$table = $this->table();

		$empty = [ 'total' => 0, 'staff' => 0, 'users' => [], 'actions' => [], 'top_user' => '', 'top_action' => '', 'top_action_count' => 0 ];

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared
		if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) !== $table ) {
			return $empty;
		}

		$cutoff = wp_date( 'Y-m-d H:i:s', time() - $days * DAY_IN_SECONDS );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT user_id, user_name, action, COUNT(*) AS c
				 FROM {$table} WHERE logged_at >= %s
				 GROUP BY user_id, action", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$cutoff
			),
			ARRAY_A
		);
		if ( empty( $rows ) ) {
			return $empty;
		}

		$users   = [];
		$actions = [];
		$total   = 0;
		foreach ( $rows as $r ) {
			$uid  = (int) $r['user_id'];
			$name = '' !== (string) $r['user_name'] ? (string) $r['user_name'] : __( 'System', 'platform-helm' );
			$act  = (string) $r['action'];
			$c    = (int) $r['c'];

			if ( ! isset( $users[ $uid ] ) ) {
				$users[ $uid ] = [ 'name' => $name, 'total' => 0, 'actions' => [] ];
			}
			$users[ $uid ]['total']           += $c;
			$users[ $uid ]['actions'][ $act ]  = ( $users[ $uid ]['actions'][ $act ] ?? 0 ) + $c;
			$actions[ $act ]                   = ( $actions[ $act ] ?? 0 ) + $c;
			$total                            += $c;
		}

		uasort( $users, static fn( $a, $b ) => $b['total'] <=> $a['total'] );
		arsort( $actions );

		$top_user        = '';
		foreach ( $users as $u ) {
			$top_user = (string) $u['name'];
			break;
		}
		$top_action       = (string) ( array_key_first( $actions ) ?? '' );
		$top_action_count = '' !== $top_action ? (int) $actions[ $top_action ] : 0;

		return [
			'total'            => $total,
			'staff'            => count( $users ),
			'users'            => $users,
			'actions'          => $actions,
			'top_user'         => $top_user,
			'top_action'       => $top_action,
			'top_action_count' => $top_action_count,
		];
	}

	/* ===================================================================== *
	 * RENDER
	 * ===================================================================== */

	public function render(): void {
		Authorization::require_admin();
		$days   = $this->period_days();
		$report = $this->gather( $days );

		$email_btn = '<button type="submit" form="ph-staff-email" class="btn btn-secondary"><i class="ti ti-mail" aria-hidden="true"></i> ' . esc_html__( 'Email to admin', 'platform-helm' ) . '</button>';
		Ui::open_page(
			__( 'Staff Activity Report', 'platform-helm' ),
			sprintf( /* translators: %d: days */ __( 'Who did what over the last %d days — from your Activity Log.', 'platform-helm' ), $days ),
			$email_btn
		);

		// Hidden form that the header button submits.
		echo '<form id="ph-staff-email" method="post" action="' . esc_url( admin_url( 'admin-post.php' ) ) . '" style="display:none">';
		wp_nonce_field( self::EMAIL_ACTION );
		echo '<input type="hidden" name="action" value="' . esc_attr( self::EMAIL_ACTION ) . '"><input type="hidden" name="period" value="' . esc_attr( (string) $days ) . '"></form>';

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( isset( $_GET['emailed'] ) ) {
			Ui::notice( esc_html__( 'Report emailed to the site admin.', 'platform-helm' ), 'success' );
		}

		// Stat tiles.
		echo '<div class="stat-grid">';
		Ui::stat_tile( __( 'Total actions', 'platform-helm' ), number_format_i18n( (int) $report['total'] ), 'blue', 'ti-activity', sprintf( /* translators: %d: days */ __( 'last %d days', 'platform-helm' ), $days ), '' );
		Ui::stat_tile( __( 'Active staff', 'platform-helm' ), number_format_i18n( (int) $report['staff'] ), 'green', 'ti-users', __( 'people with activity', 'platform-helm' ), '' );
		Ui::stat_tile( __( 'Top action', 'platform-helm' ), '' !== $report['top_action'] ? $this->action_label( (string) $report['top_action'] ) : '—', 'amber', 'ti-flame', $report['top_action_count'] > 0 ? number_format_i18n( (int) $report['top_action_count'] ) : '', '' );
		Ui::stat_tile( __( 'Most active', 'platform-helm' ), '' !== $report['top_user'] ? (string) $report['top_user'] : '—', 'blue', 'ti-user-star', '', '' );
		echo '</div>';

		// Period filter.
		echo '<form method="get" class="filter-row"><input type="hidden" name="page" value="' . esc_attr( self::PAGE_SLUG ) . '"><select name="period" onchange="this.form.submit()">';
		foreach ( [ 7 => __( 'Last 7 days', 'platform-helm' ), 30 => __( 'Last 30 days', 'platform-helm' ), 90 => __( 'Last 90 days', 'platform-helm' ) ] as $d => $lbl ) {
			echo '<option value="' . esc_attr( (string) $d ) . '" ' . selected( $days, $d, false ) . '>' . esc_html( $lbl ) . '</option>';
		}
		echo '</select></form>';

		// Per-staff table.
		echo '<div class="card">';
		echo '<div class="card-header"><div class="card-title"><i class="ti ti-users" aria-hidden="true"></i> ' . esc_html__( 'By staff member', 'platform-helm' ) . '</div></div>';

		$users = is_array( $report['users'] ) ? $report['users'] : [];
		if ( empty( $users ) ) {
			echo '<div class="card-body"><p class="text-secondary">' . esc_html__( 'No activity recorded for this period. Enable the Activity Log module to start collecting events.', 'platform-helm' ) . '</p></div></div>';
			Ui::close_page();
			return;
		}

		echo '<div class="table-wrap"><table><thead><tr>';
		echo '<th>' . esc_html__( 'Staff member', 'platform-helm' ) . '</th><th class="right">' . esc_html__( 'Total', 'platform-helm' ) . '</th><th>' . esc_html__( 'Breakdown', 'platform-helm' ) . '</th>';
		echo '</tr></thead><tbody>';
		foreach ( $users as $u ) {
			arsort( $u['actions'] );
			echo '<tr><td><p class="url-cell">' . esc_html( (string) $u['name'] ) . '</p></td>';
			echo '<td class="right"><strong>' . esc_html( number_format_i18n( (int) $u['total'] ) ) . '</strong></td>';
			echo '<td>';
			$i = 0;
			foreach ( $u['actions'] as $act => $c ) {
				if ( $i++ >= 6 ) {
					break;
				}
				echo '<span class="badge badge-neutral" style="margin:0 4px 4px 0">' . esc_html( $this->action_label( (string) $act ) . ' · ' . number_format_i18n( (int) $c ) ) . '</span>';
			}
			echo '</td></tr>';
		}
		echo '</tbody></table></div></div>';

		Ui::close_page();
	}

	/* ===================================================================== *
	 * EMAIL
	 * ===================================================================== */

	public function handle_email(): void {
		if ( ! Authorization::is_master_admin() ) {
			wp_die( esc_html__( 'Permission denied.', 'platform-helm' ), '', [ 'response' => 403 ] );
		}
		check_admin_referer( self::EMAIL_ACTION );

		$days   = isset( $_POST['period'] ) ? max( 1, min( 365, (int) $_POST['period'] ) ) : self::DEFAULT_DAYS;
		$report = $this->gather( $days );

		// Goes to the site administrator's configured address — the "master admin".
		$to = (string) get_option( 'admin_email' );
		if ( '' !== $to ) {
			$site    = wp_specialchars_decode( (string) get_bloginfo( 'name' ), ENT_QUOTES );
			$subject = sprintf( /* translators: 1: site, 2: days */ __( '[%1$s] Staff activity report — last %2$d days', 'platform-helm' ), $site, $days );
			wp_mail( $to, $subject, $this->report_text( $report, $days ) );
		}

		wp_safe_redirect( add_query_arg( [ 'page' => self::PAGE_SLUG, 'period' => $days, 'emailed' => '1' ], admin_url( 'admin.php' ) ) );
		exit;
	}

	/** @param array<string,mixed> $report */
	private function report_text( array $report, int $days ): string {
		$lines = [
			sprintf( /* translators: %d: days */ __( 'Staff activity report — last %d days', 'platform-helm' ), $days ),
			sprintf( /* translators: 1: actions, 2: staff */ __( 'Total actions: %1$s across %2$s staff member(s).', 'platform-helm' ), number_format_i18n( (int) $report['total'] ), number_format_i18n( (int) $report['staff'] ) ),
			'',
		];
		foreach ( (array) $report['users'] as $u ) {
			$parts = [];
			$acts  = is_array( $u['actions'] ) ? $u['actions'] : [];
			arsort( $acts );
			foreach ( $acts as $act => $c ) {
				$parts[] = $this->action_label( (string) $act ) . ' ' . number_format_i18n( (int) $c );
			}
			$lines[] = sprintf( '%s — %s (%s)', (string) $u['name'], number_format_i18n( (int) $u['total'] ), implode( ', ', $parts ) );
		}
		$lines[] = '';
		$lines[] = __( 'Full log:', 'platform-helm' ) . ' ' . admin_url( 'admin.php?page=platform-helm-activity-log' );
		return implode( "\n", $lines );
	}

	private function action_label( string $action ): string {
		$map = [
			'login'              => __( 'Logins', 'platform-helm' ),
			'logout'             => __( 'Logouts', 'platform-helm' ),
			'post_published'     => __( 'Published', 'platform-helm' ),
			'post_updated'       => __( 'Updated', 'platform-helm' ),
			'post_trashed'       => __( 'Trashed', 'platform-helm' ),
			'post_deleted'       => __( 'Deleted', 'platform-helm' ),
			'role_changed'       => __( 'Role changes', 'platform-helm' ),
			'user_registered'    => __( 'Registrations', 'platform-helm' ),
			'link_inserted'      => __( 'Links applied', 'platform-helm' ),
			'link_restored'      => __( 'Links restored', 'platform-helm' ),
			'settings_changed'   => __( 'Settings', 'platform-helm' ),
			'plugin_activated'   => __( 'Activations', 'platform-helm' ),
			'plugin_deactivated' => __( 'Deactivations', 'platform-helm' ),
		];
		return $map[ $action ] ?? ucfirst( str_replace( '_', ' ', $action ) );
	}
}
