<?php

namespace Simple_History\Loggers;

use Simple_History\Event_Details\Event_Details_Group;
use Simple_History\Event_Details\Event_Details_Group_Table_Formatter;
use Simple_History\Event_Details\Event_Details_Item;
use Simple_History\Log_Initiators;

/**
 * Logs Site Health status changes (issues detected, resolved, or changed severity).
 *
 * @package SimpleHistory
 */
class Site_Health_Logger extends Logger {
	/** @var string Logger slug */
	public $slug = 'SiteHealthLogger';

	/**
	 * Return logger info.
	 *
	 * @return array
	 */
	public function get_info() {
		return array(
			'name'        => _x( 'Site Health Logger', 'SiteHealthLogger', 'simple-history' ),
			'type'        => 'core',
			'description' => __( 'Logs changes in Site Health test results', 'simple-history' ),
			'capability'  => 'manage_options',
			'messages'    => array(
				'site_health_issue_detected' => __( 'Detected Site Health issue: {site_health_label}', 'simple-history' ),
				'site_health_issue_resolved' => __( 'Resolved Site Health issue: {site_health_label}', 'simple-history' ),
				'site_health_issue_changed'  => __( 'Changed Site Health issue severity: {site_health_label}', 'simple-history' ),
			),
			'labels'      => array(
				'search' => array(
					'label'     => _x( 'Site Health', 'Site Health logger: search', 'simple-history' ),
					'label_all' => _x( 'All Site Health changes', 'Site Health logger: search', 'simple-history' ),
					'options'   => array(
						_x( 'Issues detected', 'Site Health logger: search', 'simple-history' ) => array(
							'site_health_issue_detected',
						),
						_x( 'Issues resolved', 'Site Health logger: search', 'simple-history' ) => array(
							'site_health_issue_resolved',
						),
						_x( 'Issues changed severity', 'Site Health logger: search', 'simple-history' ) => array(
							'site_health_issue_changed',
						),
					),
				),
			),
		);
	}

	/**
	 * Called when logger is loaded.
	 */
	public function loaded() {
		add_filter( 'site_status_test_result', array( $this, 'on_site_status_test_result' ) );
	}

	/**
	 * Called for each Site Health test result.
	 * Compares the new status against the previously stored status and logs changes.
	 *
	 * @param array $result Test result array from WP_Site_Health::perform_test().
	 * @return array Unmodified result (this is a filter).
	 */
	public function on_site_status_test_result( $result ) {
		if ( ! is_array( $result ) || empty( $result['test'] ) || empty( $result['status'] ) ) {
			return $result;
		}

		$test_id    = $result['test'];
		$new_status = $result['status'];

		$option_key     = "simplehistory_{$this->get_slug()}_test_results";
		$stored_results = get_option( $option_key );

		if ( ! is_array( $stored_results ) ) {
			$stored_results = array();
		}

		$previous_status = $stored_results[ $test_id ] ?? null;

		// No change — skip DB write and logging.
		if ( $previous_status === $new_status ) {
			return $result;
		}

		// Update stored status only when something changed or on first run.
		$stored_results[ $test_id ] = $new_status;

		// Autoload disabled since this option is only accessed during Site Health checks.
		update_option( $option_key, $stored_results, false );

		// First run for this test — store as baseline, don't log.
		// Pre-existing issues shouldn't appear as new events.
		if ( $previous_status === null ) {
			return $result;
		}

		// Status changed — determine which message to use.
		if ( $new_status === 'good' ) {
			$this->log_status_change( 'site_health_issue_resolved', $result, $new_status, $previous_status );
		} elseif ( $previous_status === 'good' ) {
			$this->log_status_change( 'site_health_issue_detected', $result, $new_status, $previous_status );
		} else {
			$this->log_status_change( 'site_health_issue_changed', $result, $new_status, $previous_status );
		}

		return $result;
	}

	/**
	 * Log a Site Health status change.
	 *
	 * @param string $message_key Message key to log.
	 * @param array  $result      Test result array.
	 * @param string $new_status  New status (good, recommended, critical).
	 * @param string $old_status  Previous status.
	 */
	private function log_status_change( $message_key, $result, $new_status, $old_status ) {
		$context = array(
			'site_health_test'            => $result['test'],
			'site_health_label'           => $result['label'] ?? $result['test'],
			'site_health_status'          => $new_status,
			'site_health_previous_status' => $old_status,
			'site_health_badge_label'     => strtolower( $result['badge']['label'] ?? '' ),
			'_initiator'                  => Log_Initiators::WORDPRESS,
		);

		if ( $new_status === 'critical' ) {
			$this->warning_message( $message_key, $context );
		} elseif ( $new_status === 'good' ) {
			$this->info_message( $message_key, $context );
		} else {
			$this->notice_message( $message_key, $context );
		}
	}

	/**
	 * Append status details to the log row output.
	 *
	 * @param object $row Log row.
	 * @return Event_Details_Group
	 */
	public function get_log_row_details_output( $row ) {

		$group = new Event_Details_Group();
		$group->set_formatter( new Event_Details_Group_Table_Formatter() );

		$group->add_item(
			new Event_Details_Item( 'site_health_status', __( 'Current status', 'simple-history' ) )
		);

		$group->add_item(
			new Event_Details_Item( 'site_health_previous_status', __( 'Previous status', 'simple-history' ) )
		);

		$group->add_item(
			new Event_Details_Item( 'site_health_badge_label', __( 'Category', 'simple-history' ) )
		);

		return $group;
	}

	/**
	 * Get action links for a Site Health event.
	 *
	 * @param object $row Log row object.
	 * @return array Array of action link arrays.
	 */
	public function get_action_links( $row ) {
		if ( ! current_user_can( 'view_site_health_checks' ) ) {
			return [];
		}

		return [
			[
				'url'    => admin_url( 'site-health.php' ),
				'label'  => __( 'Site Health', 'simple-history' ),
				'action' => 'view',
			],
		];
	}
}
