<?php
/**
 * Notification drawer component view.
 *
 * @package Awesomemotive\Rewardswp\Views\Admin\Components
 * @since 1.0.0
 */

namespace Awesomemotive\Rewardswp\Views\Admin\Components;

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

use Awesomemotive\Rewardswp\Abstracts\AbstractView;
use Awesomemotive\Rewardswp\Interfaces\ViewInterface;
use Awesomemotive\Rewardswp\Helpers\IconHelper;
use function Awesomemotive\Rewardswp\Helpers\svg_kses;

/**
 * Notification drawer component that displays as an overlay.
 *
 * @since 1.0.0
 */
class NotificationDrawerComponentView extends AbstractView implements ViewInterface {

	/**
	 * Icon helper instance.
	 *
	 * @since 1.0.0
	 *
	 * @var IconHelper
	 */
	private IconHelper $icon_helper;

	/**
	 * Notification item component view instance.
	 *
	 * @since 1.0.0
	 *
	 * @var NotificationItemComponentView
	 */
	private NotificationItemComponentView $notification_component;

	/**
	 * Construct.
	 *
	 * @since 1.0.0
	 *
	 * @param IconHelper                    $icon_helper
	 * @param NotificationItemComponentView $notification_component
	 */
	public function __construct( IconHelper $icon_helper, NotificationItemComponentView $notification_component ) {
		$this->icon_helper            = $icon_helper;
		$this->notification_component = $notification_component;
	}

	/**
	 * Render the notification drawer.
	 *
	 * @since 1.0.0
	 *
	 * @param array $args {
	 *     @type array $notifications_state Notifications configuration and data.
	 * }
	 *
	 * @return void
	 */
	public function render( array $args = [] ): void {
		$args = wp_parse_args(
			$args,
			[
				'notifications_state' => [],
			]
		);

		// Convert notification dates to relative format
		if ( ! empty( $args['notifications_state']['notifications'] ) ) {
			foreach ( $args['notifications_state']['notifications'] as &$notification ) {
				if ( ! empty( $notification['date'] ) ) {
					$notification['relative_date'] = $this->get_relative_time( $notification['date'] );
				}
			}
		}

		$notifications_config_json = wp_json_encode( $args['notifications_state'] );

		// Generate nonce and AJAX URL for notifications.
		$ajax_nonce = wp_create_nonce( 'rewardswp_notifications_nonce' );
		$ajax_url   = admin_url( 'admin-ajax.php' );
		?>
		<div
			class="rewardswp-container"
			x-data="{ notifications: $store.notificationsDrawer }"
			data-notifications-config="<?php echo esc_attr( $notifications_config_json ?: '' ); ?>"
			data-ajax-nonce="<?php echo esc_attr( $ajax_nonce ); ?>"
			data-ajax-url="<?php echo esc_url( $ajax_url ); ?>"
			x-init="
				const config = $el.dataset.notificationsConfig;
				const ajaxNonce = $el.dataset.ajaxNonce;
				const ajaxUrl = $el.dataset.ajaxUrl;
				
				if (!config) {
					console.warn('RewardsWP notifications: no config found');
					return;
				}
				
				// Store AJAX data in the Alpine store for use in AJAX calls
				$store.notificationsDrawer.ajaxNonce = ajaxNonce;
				$store.notificationsDrawer.ajaxUrl = ajaxUrl;
				
				try {
					$store.notificationsDrawer.load(JSON.parse(config));
				} catch (error) {
					console.error('RewardsWP notifications: failed to load config', error);
				}
			"
		>
			<div x-cloak x-show="notifications.drawerOpen" class="fixed inset-x-0 z-40 bg-slate-900/40" x-transition.opacity x-on:click="notifications.close()" style="top: var(--wp-admin--admin-bar--height, 32px); height: calc(100vh - var(--wp-admin--admin-bar--height, 32px));"></div>
			<div
				x-cloak
				x-show="notifications.drawerOpen"
				class="fixed right-0 z-50 flex max-w-full pl-10 sm:pl-16"
				x-transition:enter="transform transition ease-out duration-300"
				x-transition:enter-start="translate-x-full"
				x-transition:enter-end="translate-x-0"
				x-transition:leave="transform transition ease-in duration-200"
				x-transition:leave-start="translate-x-0"
				x-transition:leave-end="translate-x-full"
				role="dialog"
				aria-modal="true"
				aria-labelledby="rewardswp-notifications-drawer-title"
				x-on:click.self="notifications.close()"
				x-on:keydown.escape.window="notifications.close()"
				style="top: var(--wp-admin--admin-bar--height, 32px); height: calc(100vh - var(--wp-admin--admin-bar--height, 32px));"
			>
				<div class="h-full w-screen max-w-2xl">
					<div class="flex h-full flex-col overflow-hidden bg-white shadow-xl">
						<div class="bg-blue-700 px-6 py-6 text-white">
							<div class="flex items-center justify-between">
								<div>
									<h2 id="rewardswp-notifications-drawer-title" class="text-base font-semibold" x-text="notifications.titleText()"></h2>
								</div>
								<button type="button" class="rounded-md p-1 text-indigo-200 transition hover:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white" x-on:click="notifications.close()">
									<span class="sr-only"><?php esc_html_e( 'Close panel', 'rewardswp' ); ?></span>
									<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
										<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
									</svg>
								</button>
							</div>
						</div>
						<div class="flex-1 overflow-y-auto px-6 py-6">
							<template x-if="notifications.hasNotifications">
								<div>
									<template x-for="(notification, index) in notifications.paginatedNotifications" x-bind:key="'drawer-' + notification.id">
										<div
											x-show="!notification.dismissed"
											x-collapse.duration.400ms
											x-bind:style="notification.dismissOrder >= 0 ? `transition-delay: ${notification.dismissOrder * 50}ms` : ''"
										>
											<div
												class="transition-opacity duration-200 ease-out"
												x-bind:class="{
													'opacity-0': notification.dismissed,
													'border-t border-slate-200 py-8': true,
													'border-t-0': !notifications.paginatedNotifications.slice(0, index).some(n => !n.dismissed)
												}"
											>
												<?php
												$this->notification_component->render(
													[
														'mode' => 'full',
														'show_divider' => false,
														'alpine_var' => 'notification',
														'alpine_action' => 'notifications.dismissNotification',
													]
												);
												?>
											</div>
										</div>
									</template>
								</div>
							</template>
							<template x-if="!notifications.hasNotifications">
								<div class="flex h-full items-center justify-center">
									<div class="text-center">
										<div class="mx-auto flex items-center justify-center">
											<?php echo wp_kses( $this->icon_helper->get_icon( 'message-check', 'size-12 text-gray-400' ), svg_kses() ); ?>
										</div>
										<h3 class="mt-4 text-base font-medium text-gray-900"><?php esc_html_e( 'No new notifications', 'rewardswp' ); ?></h3>
										<p class="mt-1 text-sm text-gray-500"><?php esc_html_e( 'You\'re all caught up! Important updates will appear here.', 'rewardswp' ); ?></p>
									</div>
								</div>
							</template>
						</div>
						<div class="border-t border-slate-200 px-6 py-4" x-show="notifications.hasNotifications">
							<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
								<button type="button" class="text-sm font-semibold text-blue-600 transition hover:text-blue-700" x-on:click.prevent="notifications.dismissAll()">
									<?php esc_html_e( 'Dismiss All', 'rewardswp' ); ?>
								</button>
								<nav class="flex items-center gap-2">
									<template x-for="pageNumber in notifications.paginationNumbers" x-bind:key="'page-btn-' + pageNumber">
										<button type="button" class="min-w-[2.25rem] rounded-md px-3 py-1 text-sm font-medium" x-bind:class="notifications.page === pageNumber ? 'bg-blue-600 text-white shadow-sm' : 'text-slate-600 hover:bg-slate-100'" x-on:click="notifications.goTo(pageNumber)" x-text="pageNumber"></button>
									</template>
								</nav>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<?php
	}

	/**
	 * Convert a date string to relative time format.
	 *
	 * @since 1.0.0
	 *
	 * @param string $date_string The date string to convert.
	 * @return string The relative time string (e.g., "27 days ago", "2 months ago").
	 */
	private function get_relative_time( string $date_string ): string {
		if ( empty( $date_string ) ) {
			return '';
		}

		try {
			$date     = new \DateTime( $date_string );
			$now      = new \DateTime();
			$interval = $now->diff( $date );

			// Years
			if ( $interval->y >= 1 ) {
				return sprintf(
					/* translators: %d: Number of years. */
					_n( '%d year ago', '%d years ago', $interval->y, 'rewardswp' ),
					$interval->y
				);
			}

			// Months
			if ( $interval->m >= 1 ) {
				return sprintf(
					/* translators: %d: Number of months. */
					_n( '%d month ago', '%d months ago', $interval->m, 'rewardswp' ),
					$interval->m
				);
			}

			// Days
			if ( $interval->d >= 1 ) {
				return sprintf(
					/* translators: %d: Number of days. */
					_n( '%d day ago', '%d days ago', $interval->d, 'rewardswp' ),
					$interval->d
				);
			}

			// Hours
			if ( $interval->h >= 1 ) {
				return sprintf(
					/* translators: %d: Number of hours. */
					_n( '%d hour ago', '%d hours ago', $interval->h, 'rewardswp' ),
					$interval->h
				);
			}

			// Minutes
			if ( $interval->i >= 1 ) {
				return sprintf(
					/* translators: %d: Number of minutes. */
					_n( '%d minute ago', '%d minutes ago', $interval->i, 'rewardswp' ),
					$interval->i
				);
			}

			// Just now
			return __( 'Just now', 'rewardswp' );
		} catch ( \Exception $e ) {
			return $date_string; // Return original if parsing fails
		}
	}
}
