<?php
/**
 * Cart detail modal for ACR admin.
 *
 * @package EDD\Pro\CartRecovery\Admin\Carts
 * @copyright Copyright (c) 2026, Sandhills Development, LLC
 * @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since 3.6.5
 */

namespace EDD\Pro\CartRecovery\Admin\Carts;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

use EDD\Pro\CartRecovery\Emails\Repository;
use EDD\EventManagement\SubscriberInterface;
use EDD\Pro\CartRecovery\Carts\Cart;
use EDD\Pro\CartRecovery\Traits\Status;
use EDD\Pro\CartRecovery\Traits\Debug;

/**
 * Renders and handles the cart detail modal/overlay.
 *
 * @since 3.6.5
 */
final class Modal implements SubscriberInterface {
	use Status;
	use Debug;

	/**
	 * Returns the subscribed events.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	public static function get_subscribed_events(): array {
		return array(
			'admin_footer'                      => 'render_modal_container',
			'wp_ajax_edd_acr_load_cart_details' => 'ajax_load_cart_details',
		);
	}

	/**
	 * AJAX: Load cart details for modal.
	 */
	public function ajax_load_cart_details(): void {
		if ( ! current_user_can( 'manage_shop_settings' ) ) {
			wp_send_json_error(
				array( 'message' => __( 'Permission denied.', 'easy-digital-downloads' ) ),
				403
			);
		}

		check_ajax_referer( 'edd_acr_nonce', 'nonce' );

		$cart_id = absint( $_POST['cart_id'] ?? 0 );
		if ( ! $cart_id ) {
			wp_send_json_error( array( 'message' => __( 'Cart ID is required.', 'easy-digital-downloads' ) ), 400 );
		}

		$query = new \EDD\Pro\CartRecovery\Database\Queries\RecoveryCart();
		$cart  = $query->get_item( $cart_id );
		if ( ! $cart ) {
			$this->log( sprintf( 'Admin cart not found: %d', $cart_id ), true );
			wp_send_json_error( array( 'message' => __( 'Cart not found.', 'easy-digital-downloads' ) ), 404 );
		}

		// Validate decoded payload before formatting details to avoid runtime notices.
		if ( ! $this->has_valid_cart_payload( $cart ) ) {
			$this->log( sprintf( 'Cart payload invalid for modal rendering: %d', $cart_id ), true );
			wp_send_json_error( array( 'message' => __( 'Cart data is corrupted.', 'easy-digital-downloads' ) ), 500 );
		}

		ob_start();
		$this->render_modal_body( $cart );
		wp_send_json_success(
			array(
				'html' => ob_get_clean(),
			)
		);
	}

	/**
	 * Renders the modal HTML structure using a native dialog element.
	 *
	 * Renders directly instead of using Modal::render() since we're already
	 * in the admin_footer hook and need the modal element available immediately.
	 *
	 * @since 3.6.5
	 */
	public function render_modal_container(): void {
		$screen = get_current_screen();
		if ( ! $screen || 'download_page_edd-cart-recovery' !== $screen->id ) {
			return;
		}
		?>
		<dialog id="edd-acr-cart-modal" class="edd-modal edd-modal--cart-recovery" aria-labelledby="edd-modal__title">
			<div class="edd-modal__header">
				<h2 id="edd-modal__title"><?php esc_html_e( 'Cart Details', 'easy-digital-downloads' ); ?></h2>
				<button type="button" class="edd-modal__close" aria-label="<?php esc_attr_e( 'Close', 'easy-digital-downloads' ); ?>">
					<span class="dashicons dashicons-no-alt"></span>
					<span class="screen-reader-text"><?php esc_html_e( 'Close', 'easy-digital-downloads' ); ?></span>
				</button>
			</div>
			<div class="edd-modal__content"></div>
			<div class="edd-modal__loading edd-hidden">
				<?php $this->render_skeleton_loading(); ?>
			</div>
		</dialog>
		<?php
	}

	/**
	 * Renders the inner modal body with cart data.
	 *
	 * @since 3.6.5
	 * @param Cart $cart The cart object.
	 * @return void
	 */
	private function render_modal_body( Cart $cart ): void {
		$customer = $this->format_customer_info( $cart );
		$items    = $cart->get_items();
		$totals   = $this->format_totals( $cart );
		$emails   = $this->get_email_history( $cart->id );
		$metadata = $this->format_metadata( $cart );
		?>
		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Customer', 'easy-digital-downloads' ); ?></h3>
			<div class="edd-acr-info-grid">
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Name', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( wp_check_invalid_utf8( $customer['name'] ) ); ?></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Email', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( wp_check_invalid_utf8( $customer['email'] ) ); ?></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Customer ID', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo $customer['id'] ? (int) $customer['id'] : '&mdash;'; ?></span>
				</div>
			</div>
		</section>

		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Cart Items', 'easy-digital-downloads' ); ?></h3>
			<?php if ( $items ) : ?>
				<div class="edd-acr-items-list">
					<?php
					foreach ( $items as $key => $item ) {
						?>
						<div class="edd-acr-cart-item" data-download-id="<?php echo esc_attr( $item['id'] ); ?>">
							<?php $this->render_cart_item( $item, $key, $cart ); ?>
						</div>
						<?php
					}
					?>
				</div>
			<?php else : ?>
				<p class="edd-acr-empty-message"><em><?php esc_html_e( 'No items.', 'easy-digital-downloads' ); ?></em></p>
			<?php endif; ?>
		</section>

		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Totals', 'easy-digital-downloads' ); ?></h3>
			<div class="edd-acr-info-grid">
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Cart Total', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( $totals['cart_total'] ); ?></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Currency', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( $totals['currency'] ); ?></span>
				</div>
			</div>
		</section>

		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Customer Journey', 'easy-digital-downloads' ); ?></h3>
			<?php
			$timeline = new Timeline( $cart );
			$timeline->render( $cart->id );
			?>
		</section>

		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Email History', 'easy-digital-downloads' ); ?></h3>
			<?php if ( $emails ) : ?>
				<div class="edd-acr-email-list">
					<?php foreach ( $emails as $email ) : ?>
						<div class="edd-acr-email-item">
							<?php $this->render_email_item( $email ); ?>
						</div>
					<?php endforeach; ?>
					<?php
					$view_logs = edd_get_admin_url(
						array(
							'page'    => 'edd-cart-recovery',
							'tab'     => 'activity',
							'cart_id' => $cart->id,
						)
					);
					?>
					<a href="<?php echo esc_url( $view_logs ); ?>">
						<?php esc_html_e( 'View Activity', 'easy-digital-downloads' ); ?>
					</a>
				</div>
			<?php else : ?>
				<p class="edd-acr-empty-message"><em><?php esc_html_e( 'No emails sent.', 'easy-digital-downloads' ); ?></em></p>
			<?php endif; ?>
		</section>

		<section class="edd-acr-cart-section">
			<h3><?php esc_html_e( 'Metadata', 'easy-digital-downloads' ); ?></h3>
			<div class="edd-acr-info-grid">
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Session ID', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><code><?php echo esc_html( $metadata['session_id'] ); ?></code></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Status', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( $this->get_status_label( $metadata['status'] ) ); ?></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Created', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( $metadata['date_created'] ); ?></span>
				</div>
				<div class="edd-acr-info-row">
					<span class="edd-acr-info-label"><?php esc_html_e( 'Updated', 'easy-digital-downloads' ); ?></span>
					<span class="edd-acr-info-value"><?php echo esc_html( $metadata['date_modified'] ); ?></span>
				</div>
				<?php if ( $metadata['date_recovered'] ) : ?>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Recovered Date', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><?php echo esc_html( $metadata['date_recovered'] ); ?></span>
					</div>
				<?php endif; ?>
			</div>
		</section>
		<?php
	}

	/**
	 * Determines whether the cart payload is safe to render.
	 *
	 * @since 3.6.5
	 * @param object $cart The cart object.
	 * @return bool Whether the cart payload is safe to render.
	 */
	private function has_valid_cart_payload( $cart ): bool {
		if ( ! $cart instanceof Cart ) {
			return false;
		}

		// Use Cart's decode method which handles validation.
		// Empty carts and invalid JSON will return empty array.
		$items = $cart->get_items();

		// Both empty carts and carts with items are valid.
		return is_array( $items );
	}

	/**
	 * Renders a cart item.
	 *
	 * @since 3.6.5
	 * @param array $item The cart item.
	 * @param int   $key  The cart item key/position.
	 * @param Cart  $cart The cart object.
	 * @return void
	 */
	private function render_cart_item( $item, $key, $cart ): void {
		// Normalize the item options.
		if ( ! isset( $item['options'] ) && isset( $item['item_number']['options'] ) ) {
			$item['options'] = $item['item_number']['options'];
		}
		$currency = $cart->currency ?? edd_get_currency();
		?>
		<div class="edd-acr-cart-item__content">
			<?php if ( has_post_thumbnail( $item['id'] ) ) : ?>
				<div class="edd-acr-cart-item__image">
					<?php echo get_the_post_thumbnail( $item['id'], array( 50, 50 ) ); ?>
				</div>
			<?php endif; ?>
			<div class="edd-acr-cart-item__details">
				<div class="edd-acr-cart-item__title">
					<?php echo esc_html( edd_get_cart_item_name( $item ) ); ?>
				</div>
				<div class="edd-acr-cart-item__options">
					<?php
					/**
					 * Fires after the cart item title in the admin cart recovery modal.
					 * Allows extensions to add additional information (e.g., subscription terms, renewal info).
					 *
					 * @since 3.6.5
					 *
					 * @param array $item Cart item data.
					 * @param int   $key  Cart item key/position.
					 */
					do_action( 'edd_checkout_cart_item_title_after', $item, $key );
					?>
				</div>
				<div class="edd-acr-cart-item__meta">
					<?php if ( edd_item_quantities_enabled() ) : ?>
						<span class="edd-acr-cart-item__quantity">
							<?php
							printf(
								/* translators: %d: quantity */
								esc_html__( 'Quantity: %d', 'easy-digital-downloads' ),
								(int) $item['quantity'] ?? 1
							);
							?>
						</span>
					<?php endif; ?>
					<?php
					if ( ! empty( $item['discount'] ) ) {
						?>
						<span class="edd-acr-cart-item__discount">
							<?php
							printf(
								/* translators: %s: discount */
								esc_html__( 'Discount: %s', 'easy-digital-downloads' ),
								edd_currency_filter( edd_format_amount( $item['discount'] ), $currency )
							);
							if ( ! empty( $cart->discount_applied ) ) {
								echo ' | ';
								echo esc_html( $cart->discount_applied );
							}
							?>
						</span>
						<?php
					}
					?>
				</div>
			</div>
			<div class="edd-acr-cart-item__price">
				<?php echo esc_html( edd_currency_filter( edd_format_amount( $item['price'] ?? 0 ), $currency ) ); ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Renders an email item.
	 *
	 * @since 3.6.5
	 * @param array $email The email.
	 * @return void
	 */
	private function render_email_item( array $email ): void {
		?>
		<div class="edd-acr-email-header">
			<strong><?php echo esc_html( $email['subject'] ); ?></strong>
			<?php
			$status = $email['status'];
			if ( 'sent' === $status ) {
				$status = 'success';
			} elseif ( 'failed' === $status ) {
				$status = 'error';
			} elseif ( 'pending' === $status ) {
				$status = 'warning';
			}
			$args = array(
				'status' => $status,
				'label'  => $this->get_status_label( $email['status'], 'email' ),
			);

			$status_badge = new \EDD\Utils\StatusBadge( $args );
			$status_badge->render();
			?>
		</div>
		<div class="edd-acr-email-meta">
			<?php echo esc_html( $this->format_date( $email['sent'] ) ); ?>
		</div>
		<?php
	}

	/**
	 * Formats customer information.
	 *
	 * @since 3.6.5
	 * @param object $cart The cart object.
	 * @return array Customer info.
	 */
	private function format_customer_info( $cart ): array {
		return array(
			'name'  => $cart->get_customer_name()['full_name'],
			'email' => ! empty( $cart->email ) ? $cart->email : '',
			'id'    => ! empty( $cart->customer_id ) ? (int) $cart->customer_id : 0,
		);
	}

	/**
	 * Retrieves email history for a cart.
	 *
	 * @since 3.6.5
	 * @param int $cart_id The ID of the cart.
	 * @return array Email history.
	 * @throws \Exception If the email history cannot be retrieved.
	 */
	private function get_email_history( int $cart_id ): array {
		$repo   = new Repository();
		$emails = $repo->get_emails_by_cart_id( $cart_id );
		$list   = array();
		foreach ( $emails as $email ) {
			$list[] = array(
				'sent'    => ! empty( $email->date_sent ) ? date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $email->date_sent ) ) : '',
				'subject' => ! empty( $email->email_subject ) ? $email->email_subject : '',
				'status'  => ! empty( $email->delivery_status ) ? $email->delivery_status : '',
			);
		}
		return $list;
	}

	/**
	 * Formats totals info.
	 *
	 * @since 3.6.5
	 * @param object $cart The cart object.
	 * @return array Totals info.
	 */
	private function format_totals( $cart ): array {
		$currency = $cart->currency ?? edd_get_currency();

		return array(
			'cart_total' => ! empty( $cart->cart_total ) ? edd_currency_filter( edd_format_amount( $cart->cart_total ), $currency ) : '0.00',
			'currency'   => $currency,
		);
	}

	/**
	 * Formats metadata.
	 *
	 * @since 3.6.5
	 * @param object $cart The cart object.
	 * @return array Metadata.
	 */
	private function format_metadata( $cart ): array {
		$metadata = array(
			'session_id'     => ! empty( $cart->session_id ) ? $cart->session_id : '',
			'status'         => ! empty( $cart->status ) ? $cart->status : '',
			'date_created'   => ! empty( $cart->date_created ) ? $this->format_date( $cart->date_created ) : '',
			'date_modified'  => ! empty( $cart->date_modified ) ? $this->format_date( $cart->date_modified ) : '',
			'date_recovered' => '',
		);

		if ( ! empty( $cart->date_recovered ) ) {
			$metadata['date_recovered'] = $this->format_date( $cart->date_recovered );
		}

		return $metadata;
	}

	/**
	 * Formats a date.
	 *
	 * @since 3.6.5
	 * @param string $date The date to format.
	 * @return string The formatted date.
	 */
	private function format_date( $date ): string {
		return edd_date_i18n( strtotime( $date ), get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
	}

	/**
	 * Renders skeleton loading placeholders for the modal.
	 *
	 * @since 3.6.5
	 * @return void
	 */
	private function render_skeleton_loading(): void {
		?>
		<div class="edd-acr-cart-details edd-acr-cart-details--loading">
			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Customer', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-info-grid">
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Name', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Email', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Customer ID', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
				</div>
			</section>

			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Cart Items', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-items-list">
					<div class="edd-acr-cart-item">
						<div class="edd-acr-cart-item__content">
							<div class="edd-acr-cart-item__details">
								<div class="edd-acr-cart-item__title">
									<span class="edd-modal__skeleton"></span>
								</div>
								<div class="edd-acr-cart-item__meta">
									<span class="edd-modal__skeleton edd-modal__skeleton--short"></span>
								</div>
							</div>
							<div class="edd-acr-cart-item__price">
								<span class="edd-modal__skeleton edd-modal__skeleton--short"></span>
							</div>
						</div>
					</div>
				</div>
			</section>

			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Totals', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-info-grid">
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Cart Total', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Currency', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
				</div>
			</section>

			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Customer Journey', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-info-grid">
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label">
							<span class="dashicons dashicons-clock"></span>
							<?php esc_html_e( 'Cart Abandoned', 'easy-digital-downloads' ); ?>
						</span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label">
							<span class="dashicons dashicons-cart"></span>
							<?php esc_html_e( 'Cart Created', 'easy-digital-downloads' ); ?>
						</span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
				</div>
			</section>

			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Email History', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-email-list">
					<div class="edd-acr-email-item">
						<div class="edd-acr-email-header">
							<span class="edd-modal__skeleton"></span>
						</div>
						<div class="edd-acr-email-meta">
							<span class="edd-modal__skeleton edd-modal__skeleton--short"></span>
						</div>
					</div>
				</div>
			</section>

			<section class="edd-acr-cart-section">
				<h3><?php esc_html_e( 'Metadata', 'easy-digital-downloads' ); ?></h3>
				<div class="edd-acr-info-grid">
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Session ID', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Status', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton edd-modal__skeleton--short"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Created', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton"></span></span>
					</div>
					<div class="edd-acr-info-row">
						<span class="edd-acr-info-label"><?php esc_html_e( 'Updated', 'easy-digital-downloads' ); ?></span>
						<span class="edd-acr-info-value"><span class="edd-modal__skeleton"></span></span>
					</div>
				</div>
			</section>
		</div>
		<?php
	}
}
