<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase, WordPress.Files.FileName.InvalidClassFileName
/**
 * Filter callbacks for the Snooze feature.
 *
 * Hooks into the existing scheduled-order action filter chain to swap
 * Pause for Snooze (alongside or instead, per merchant config) and to
 * replace standard Resume/Pause with Resume Early / Change Snooze on
 * orders that are currently snoozed.
 *
 * @package Autoship\Services\Snooze\Implementations
 * @since   2.13.0
 */

namespace Autoship\Services\Snooze\Implementations;

use Autoship\Domain\Snooze\SnoozeStatus;
use Autoship\Services\Labels\LabelServiceInterface;
use Autoship\Services\Snooze\Interfaces\SnoozeSettingsInterface;

/**
 * Filter callbacks for snooze-aware action transformations and status
 * display formatting.
 */
class SnoozeActionFilters {

	/**
	 * Snooze settings reader.
	 *
	 * @var SnoozeSettingsInterface
	 */
	private SnoozeSettingsInterface $settings;

	/**
	 * White-label terminology service.
	 *
	 * @var LabelServiceInterface
	 */
	private LabelServiceInterface $labels;

	/**
	 * Constructor.
	 *
	 * @param SnoozeSettingsInterface $settings Snooze settings reader.
	 * @param LabelServiceInterface   $labels   White-label terminology service.
	 */
	public function __construct( SnoozeSettingsInterface $settings, LabelServiceInterface $labels ) {
		$this->settings = $settings;
		$this->labels   = $labels;
	}

	/**
	 * Replace the Pause action with (or sit alongside) Snooze in an actions array.
	 *
	 * @param array  $actions The current actions array.
	 * @param string $status  The current order's status.
	 * @param string $context Context in which the actions are being displayed.
	 *
	 * @return array
	 */
	public function swap_pause_action( $actions, $status, $context ) {
		if ( ! $this->settings->is_enabled() ) {
			return $actions;
		}

		if ( ! isset( $actions['Paused'] ) ) {
			return $actions;
		}

		$snooze_label   = $this->settings->get_action_label();
		$schedule_label = $this->labels->get_label( 'Scheduled Order' );
		$behavior       = $this->settings->get_pause_behavior();

		$snooze_entry = array(
			'url'   => '#',
			// translators: %1$s is the snooze label, %2$s is the Scheduled Order label.
			'title' => sprintf( __( '%1$s %2$s', 'autoship' ), $snooze_label, $schedule_label ),
			'name'  => $snooze_label,
		);

		if ( 'instead' === $behavior ) {
			unset( $actions['Paused'] );
			$actions = array( 'Snooze' => $snooze_entry ) + $actions;
		} else {
			$new_actions = array();
			foreach ( $actions as $key => $action ) {
				$new_actions[ $key ] = $action;
				if ( 'Paused' === $key ) {
					$new_actions['Snooze'] = $snooze_entry;
				}
			}
			$actions = $new_actions;
		}

		return $actions;
	}

	/**
	 * Replace the standard Resume / Pause / Snooze actions with Resume
	 * Early + Change Snooze when the order is snoozed.
	 *
	 * @param array        $actions        The current actions array.
	 * @param object|array $autoship_order The scheduled order.
	 * @param int          $customer_id    The WC customer ID.
	 * @param array        $settings       The site settings.
	 *
	 * @return array
	 */
	public function filter_snoozed_actions( $actions, $autoship_order, $customer_id, $settings = array() ) {
		if ( ! $this->settings->is_enabled() || ! SnoozeStatus::is_snoozed( $autoship_order ) ) {
			return $actions;
		}

		$schedule_label = $this->labels->get_label( 'Scheduled Order' );
		$snooze_label   = $this->settings->get_action_label();

		// Remove Pause, Resume, and (the regular) Snooze entries — snoozed
		// orders use their own action set.
		unset( $actions['Paused'] );
		unset( $actions['Active'] );
		unset( $actions['Snooze'] );

		$snoozed_actions = array(
			'ResumeSnooze' => array(
				'url'   => '#',
				// translators: %s is the Scheduled Order label.
				'title' => sprintf( __( 'Resume %s Early', 'autoship' ), $schedule_label ),
				'name'  => __( 'Resume Early', 'autoship' ),
			),
			'Snooze'       => array(
				'url'   => '#',
				// translators: %s is the snooze action label.
				'title' => sprintf( __( 'Change %1$s Duration', 'autoship' ), $snooze_label ),
				// translators: %s is the snooze action label.
				'name'  => sprintf( __( 'Change %s', 'autoship' ), $snooze_label ),
			),
		);

		return $snoozed_actions + $actions;
	}

	/**
	 * Filter the displayed status text for snoozed orders.
	 *
	 * Returns just "Snoozed" — the "Snoozed until [date]" pill is rendered
	 * separately by the templates as a sibling element.
	 *
	 * @param string       $display_text    The current translated status name.
	 * @param object|array $autoship_order  The scheduled order.
	 * @param string       $status_nicename The nicename (e.g. "Paused").
	 *
	 * @return string
	 */
	public function status_display( $display_text, $autoship_order, $status_nicename ) {
		if ( ! SnoozeStatus::is_snoozed( $autoship_order ) ) {
			return $display_text;
		}

		return __( 'Snoozed', 'autoship' );
	}

	/**
	 * Returns the formatted "Snoozed until [date]" text for a snoozed order.
	 *
	 * Used by templates to render the snooze pill next to the status.
	 *
	 * @param object|array $autoship_order The scheduled order.
	 *
	 * @return string The formatted text, or empty string if not snoozed.
	 */
	public function get_snooze_until_text( $autoship_order ): string {
		$formatted_date = $this->get_snooze_resume_date_formatted( $autoship_order );

		if ( '' === $formatted_date ) {
			return '';
		}

		// translators: %s is the formatted resume date.
		return sprintf( __( 'Snoozed until %s', 'autoship' ), $formatted_date );
	}

	/**
	 * Returns the localized resume date for a snoozed order, without any
	 * surrounding text.
	 *
	 * Lets templates compose their own sentence around the date (e.g.
	 * "Auto-resumes on …", "Will resume …") while keeping the date format
	 * — `get_option( 'date_format' )` via `date_i18n()` — in one place.
	 *
	 * @param object|array $autoship_order The scheduled order.
	 *
	 * @return string Localized date, or empty string when the order is not
	 *                snoozed or the resume date is unparseable.
	 */
	public function get_snooze_resume_date_formatted( $autoship_order ): string {
		if ( ! SnoozeStatus::is_snoozed( $autoship_order ) ) {
			return '';
		}

		$is_array         = is_array( $autoship_order );
		$snooze_until_utc = $is_array ? ( $autoship_order['snoozeUntilUtc'] ?? '' ) : ( $autoship_order->snoozeUntilUtc ?? '' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

		$timestamp = strtotime( (string) $snooze_until_utc );
		if ( false === $timestamp ) {
			return '';
		}

		return date_i18n( get_option( 'date_format' ), $timestamp );
	}
}
