<?php
/**
 * Alert pipeline: critical events email immediately; the rest roll into a daily digest.
 *
 * @package Upgrade_Pilot
 */

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

/**
 * Class UPilot_Alerts
 */
class UPilot_Alerts {

	/**
	 * Constructor: hook the event pipeline and the digest cron.
	 */
	public function __construct() {
		add_action( 'upilot_event_recorded', array( $this, 'route_event' ), 10, 4 );
		add_action( 'upilot_daily_digest', array( $this, 'send_digest' ) );
	}

	/**
	 * Route a newly recorded event.
	 *
	 * @param string $slug       Plugin slug.
	 * @param string $event_type Event type.
	 * @param string $severity   info|warning|critical.
	 * @param array  $details    Details.
	 */
	public function route_event( $slug, $event_type, $severity, $details ) {
		$settings = UPilot_Store::get_option( 'upilot_settings', array() );

		if ( 'critical' === $severity && ! empty( $settings['email_critical'] ) ) {
			$this->send_critical( $slug, $event_type, $details );
			return;
		}

		if ( 'info' === $severity ) {
			return; // Info events are visible in the UI; no email noise.
		}

		if ( ! empty( $settings['email_digest'] ) ) {
			$queue   = UPilot_Store::get_option( 'upilot_digest_queue', array() );
			$queue[] = array(
				'slug'       => $slug,
				'event_type' => $event_type,
				'severity'   => $severity,
				'details'    => $details,
				'time'       => time(),
			);
			// Cap the queue defensively.
			if ( count( $queue ) > 200 ) {
				$queue = array_slice( $queue, -200 );
			}
			UPilot_Store::update_option( 'upilot_digest_queue', $queue, false );
		}
	}

	/**
	 * Immediate email for critical events.
	 *
	 * @param string $slug       Plugin slug.
	 * @param string $event_type Event type.
	 * @param array  $details    Details.
	 */
	private function send_critical( $slug, $event_type, $details ) {
		$settings = UPilot_Store::get_option( 'upilot_settings', array() );
		$to       = ! empty( $settings['alert_email'] ) ? $settings['alert_email'] : get_option( 'admin_email' );
		$name     = isset( $details['name'] ) ? $details['name'] : $slug;

		$labels = array(
			'closed'     => __( 'was CLOSED on WordPress.org', 'upgrade-pilot' ),
			'compromise' => __( 'appears on a known-compromise advisory list', 'upgrade-pilot' ),
		);
		$what   = isset( $labels[ $event_type ] ) ? $labels[ $event_type ] : $event_type;

		$subject = sprintf(
			/* translators: 1: site name, 2: plugin name. */
			__( '[%1$s] Plugin alert: %2$s needs attention', 'upgrade-pilot' ),
			wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
			$name
		);

		$lines   = array();
		$lines[] = sprintf(
			/* translators: 1: plugin name, 2: what happened. */
			__( 'Upgrade Pilot detected that the plugin "%1$s" %2$s.', 'upgrade-pilot' ),
			$name,
			$what
		);
		if ( ! empty( $details['reason'] ) ) {
			/* translators: %s: reason. */
			$lines[] = sprintf( __( 'Reason: %s', 'upgrade-pilot' ), $details['reason'] );
		}
		if ( ! empty( $details['detail'] ) ) {
			$lines[] = (string) $details['detail'];
		}
		$lines[] = '';
		$lines[] = __( 'Review it here:', 'upgrade-pilot' ) . ' ' . UPilot_Store::admin_url( 'admin.php?page=upgrade-pilot-trust' );
		$lines[] = '';
		$lines[] = __( 'Closed plugins receive no further updates through the directory. If the closure reason is a security issue, consider deactivating the plugin until a fix ships.', 'upgrade-pilot' );

		wp_mail( $to, $subject, implode( "\n", $lines ) );
	}

	/**
	 * Send the daily digest, if anything is queued.
	 */
	public function send_digest() {
		$queue = UPilot_Store::get_option( 'upilot_digest_queue', array() );
		if ( empty( $queue ) || ! is_array( $queue ) ) {
			return;
		}

		$settings = UPilot_Store::get_option( 'upilot_settings', array() );
		$to       = ! empty( $settings['alert_email'] ) ? $settings['alert_email'] : get_option( 'admin_email' );

		$subject = sprintf(
			/* translators: 1: site name, 2: number of events. */
			__( '[%1$s] Upgrade Pilot digest: %2$d plugin change(s)', 'upgrade-pilot' ),
			wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ),
			count( $queue )
		);

		$type_labels = array(
			'author_change'       => __( 'author changed', 'upgrade-pilot' ),
			'contributor_added'   => __( 'new contributor(s) added', 'upgrade-pilot' ),
			'contributor_removed' => __( 'contributor(s) removed', 'upgrade-pilot' ),
			'reopened'            => __( 'was reopened on WordPress.org', 'upgrade-pilot' ),
		);

		$lines   = array();
		$lines[] = __( 'Changes Upgrade Pilot noticed in the plugins installed on your site:', 'upgrade-pilot' );
		$lines[] = '';
		foreach ( $queue as $item ) {
			$name    = isset( $item['details']['name'] ) ? $item['details']['name'] : $item['slug'];
			$label   = isset( $type_labels[ $item['event_type'] ] ) ? $type_labels[ $item['event_type'] ] : $item['event_type'];
			$extra   = '';
			if ( 'author_change' === $item['event_type'] && isset( $item['details']['from'], $item['details']['to'] ) ) {
				$extra = sprintf( ' (%s → %s)', $item['details']['from'], $item['details']['to'] );
			}
			if ( 'contributor_added' === $item['event_type'] && ! empty( $item['details']['added'] ) ) {
				$extra = ' (' . implode( ', ', (array) $item['details']['added'] ) . ')';
			}
			$lines[] = sprintf( '- %s: %s%s', $name, $label, $extra );
		}
		$lines[] = '';
		$lines[] = __( 'Details and actions:', 'upgrade-pilot' ) . ' ' . UPilot_Store::admin_url( 'admin.php?page=upgrade-pilot-trust' );
		$lines[] = '';
		$lines[] = __( 'A change of author or contributors is usually a legitimate sale or team change — but plugins that change hands deserve a closer look before their next update runs. You can freeze updates per plugin from the Update Trust screen.', 'upgrade-pilot' );

		if ( wp_mail( $to, $subject, implode( "\n", $lines ) ) ) {
			UPilot_Store::delete_option( 'upilot_digest_queue' );
		}
	}
}
