<?php
/**
 * Payout Drawer — Next Steps Card
 *
 * Renders the failure-class-aware recommendation card. Only shown when the
 * drawer's loaded payout is failed AND the classifier produced a known
 * class. Sits between the method-summary card and the referrals section
 * so the "why" is immediately followed by "what now."
 *
 * Card grammar (three regions):
 *
 *   ┌── Header ──────────────────────────┐
 *   │  Diagnosis pair: headline + narration │
 *   ├── Body ────────────────────────────┤
 *   │  State-aware action (button OR     │
 *   │  status + Resend link)             │
 *   ├── Footer (expandable) ─────────────┤
 *   │  Switch payout method     [chevron]│
 *   │  (radio list appears when open)    │
 *   └─────────────────────────────────────┘
 *
 * Card contents come from `affwp_build_payout_next_steps()` and reach the
 * Alpine store as `drawer.payout.next_steps`. The switch-method footer
 * reads from `drawer.switchableMethods` (server-built map of slug → label
 * + description).
 *
 * @package     AffiliateWP
 * @subpackage  Admin/Payouts
 * @since       2.33.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
?>

<!--
	Fires on either failed payouts (failure_class set by the per-method
	classifier) OR processing payouts with stuck per-item states (PayPal
	UNCLAIMED). The next_steps payload itself is the gate: the builder
	returns a non-null value only for actionable cases. Same operational
	shape regardless of payment-system status — affiliate needs to act,
	system has already emailed them, retry will fire automatically.
-->
<template x-if="drawer.payout && drawer.payout.next_steps && ! drawer.isSuperseded">
	<div class="affwp-card rounded-lg border border-gray-200 bg-white overflow-hidden"
		x-data="{
			switchExpanded: false,
			selectedSwitchMethod: '',
			switchConfirming: false,
			resendConfirming: false,
			get selectedSwitchMethodLabel() {
				if ( ! this.selectedSwitchMethod ) return '';
				const opt = ( this.$store.payoutDrawer.switchableMethods || [] )
					.find( o => o.slug === this.selectedSwitchMethod );
				return opt ? opt.label : '';
			}
		}">

		<!--
			No eyebrow strip. It previously carried the failure-class label
			("DATA ERROR" — internal jargon) and then the method ("PAYPAL" —
			redundant with the header sub-line and Details, which already name
			the method). The bold provider-reason headline below is a strong
			enough entry point on its own; a third method label was noise.
		-->

		<!--
			Header + Body region. Uses flex/gap (not space-y-*) because
			the narration <p> carries m-0 to suppress WP admin's default
			margin, and that overrides Tailwind's space-y rule. Gap is
			layout-level and can't be undone by a child's margin reset.

			Card padding is `p-4` (16px) to match the rest of the
			AffiliateWP admin's rhythm.
		-->
		<div class="flex flex-col gap-4 p-4">

			<!--
				Diagnosis pair: headline + action. Lead with the provider's verbatim
				reason ("Payment to self is not allowed.") when we have it — it's the
				most specific, actionable line — and fall back to the class headline
				for failures with no provider message (auth, transient, timeout). The
				eyebrow above carries the provider name, so no inline "PayPal:" prefix.
			-->
			<div class="flex flex-col gap-2">
				<h3 class="text-sm font-semibold text-gray-900 m-0 break-words"
					style="overflow-wrap: anywhere; word-break: break-word;"
					x-text="drawer.payout.next_steps.provider_message || drawer.payout.next_steps.headline"></h3>
				<p class="text-sm text-gray-600 m-0" x-text="drawer.payout.next_steps.description"></p>
			</div>

			<!--
				State-aware body action.

				  A. cooldown inactive (or non-email kinds) → primary button
				  B. cooldown active → status line + Resend (inline two-step
					 confirm) with the recipient address inline so admins
					 can verify which inbox the system used
			-->

			<!-- State A: primary button. -->
			<template x-if="drawer.payout.next_steps.primary_action.kind !== 'email_affiliate' || ! drawer.payout.failure_email_cooldown_active">
				<div>
					<button type="button"
						@click="drawer.runNextStepsAction()"
						:disabled="drawer.isNextStepsRunning"
						class="cursor-pointer inline-flex items-center rounded-md border border-transparent bg-affwp-brand-500 px-3 py-1.5 text-sm font-medium text-white shadow-sm hover:bg-affwp-brand-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
						<svg x-show="drawer.isNextStepsRunning" x-cloak class="animate-spin -ml-1 mr-2 h-3.5 w-3.5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" aria-hidden="true">
							<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
							<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
						</svg>
						<span x-text="drawer.payout.next_steps.primary_action.label"></span>
					</button>
				</div>
			</template>

			<!--
				State B (cooldown active): status line with recipient
				address + inline two-step Resend confirm.

				The "AffiliateWP emailed them a reminder… to <email>" line
				attributes the nudge to AffiliateWP — not PayPal — so the
				admin understands this is our outreach (sent automatically
				on first unclaimed detection, re-sendable here), distinct
				from PayPal's own claim email. It also carries the recipient
				context so admins can verify which inbox the system used
				(closes a quiet gap when an admin is about to call the
				affiliate or escalate to support).

				Resend is a two-step inline confirm rather than a native
				window.confirm() — matches the rest of the drawer's
				visual language and avoids the Web-1.0 modal. Default
				state shows "Resend reminder" link; clicking toggles to
				"Send another?  [Send]  Cancel" inline; Send fires the
				AJAX, Cancel reverts.
			-->
			<template x-if="drawer.payout.next_steps.primary_action.kind === 'email_affiliate' && drawer.payout.failure_email_cooldown_active">
				<div class="flex flex-col gap-1.5 text-sm">
					<div class="flex items-start gap-2 text-gray-600">
						<?php \AffiliateWP\Utils\Icons::render( 'check', '', [ 'class' => 'h-4 w-4 text-green-600 shrink-0 mt-0.5', 'style' => 'fill' ] ); ?>
						<span>
							<?php esc_html_e( 'AffiliateWP emailed them a reminder to claim it —', 'affiliate-wp' ); ?>
							<span x-text="drawer.payout.last_failure_email_sent_human"></span><template x-if="drawer.payout.affiliate_email"><span>, <?php esc_html_e( 'to', 'affiliate-wp' ); ?> <span class="text-gray-900" x-text="drawer.payout.affiliate_email"></span></span></template>.
						</span>
					</div>

					<!--
						@click.stop is essential on every button in this
						two-step block. The trigger button (and the Send /
						Cancel buttons inside the confirm step) get removed
						from the DOM by their own x-if when clicked. Without
						.stop, the click event keeps bubbling up to the
						drawer's outside-click handler in trait-drawers.php,
						which calls
						`event.target.closest('[data-affwp-drawer-panel]')`
						— but the original target is now detached from the
						DOM, closest() returns null, and the drawer closes
						with the user wondering why. .stop keeps the event
						inside the card.
					-->

					<!-- Default: quiet Resend link, indented to align with text. -->
					<template x-if="! resendConfirming">
						<button type="button"
							@click.stop="resendConfirming = true"
							:disabled="drawer.isNextStepsRunning"
							class="cursor-pointer bg-transparent border-0 p-0 pl-6 text-left text-sm font-medium text-affwp-link hover:text-affwp-link-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 rounded disabled:opacity-50 disabled:cursor-not-allowed w-fit">
							<?php esc_html_e( 'Resend reminder', 'affiliate-wp' ); ?>
						</button>
					</template>

					<!--
						Confirm step: "Send another?" + Send / Cancel.
						Send fires the AJAX (sendFailureEmail), then
						closes the confirm step. Cancel reverts to the
						default Resend link.
					-->
					<template x-if="resendConfirming">
						<div class="pl-6 flex items-center gap-3 flex-wrap">
							<span class="text-gray-700"><?php esc_html_e( 'Send another?', 'affiliate-wp' ); ?></span>
							<button type="button"
								@click.stop="drawer.sendFailureEmail(); resendConfirming = false"
								:disabled="drawer.isNextStepsRunning"
								class="cursor-pointer inline-flex items-center rounded-md border border-gray-300 bg-white px-2.5 py-1 text-xs font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
								<?php esc_html_e( 'Send', 'affiliate-wp' ); ?>
							</button>
							<button type="button"
								@click.stop="resendConfirming = false"
								class="cursor-pointer bg-transparent border-0 p-0 text-xs text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:underline rounded">
								<?php esc_html_e( 'Cancel', 'affiliate-wp' ); ?>
							</button>
						</div>
					</template>

				</div>
			</template>

		</div>

		<!--
			Footer region: expandable switch-method.

			Why a footer (not inline link inside the body group):

			1. Grammar — header / body / footer is a familiar three-region
			   card pattern. Header diagnoses, body responds, footer offers
			   the alternative path. Each region has one job.
			2. Position predictability — admins learn "the override always
			   lives at the bottom" instead of scanning the body for a
			   ghost link.
			3. The divider above does the hierarchy work that the word "or"
			   was carrying. Drop the prefix; position telegraphs role.
			4. Right-aligned chevron matches iOS-settings + accordion
			   convention. The whole row becomes a hit target.
			5. Expansion fills the dedicated region cleanly rather than
			   awkwardly pushing inline-block content.

			Local Alpine state (`switchExpanded`, `selectedSwitchMethod`)
			lives on the card root so the trigger and panel share it.
		-->
		<template x-if="drawer.canSwitchMethod">
			<div class="border-t border-gray-200">

				<!--
					Trigger label "Pay with another method" rather than
					"Switch payout method": the verb makes it explicit that
					clicking through executes a payment now, not just opens
					a settings panel. Switching is destructive (re-routes
					referrals, creates a new payout, supersedes this row,
					calls the new provider immediately) and the action
					language has to communicate that.
				-->
				<button type="button"
					@click="switchExpanded = ! switchExpanded; if ( ! switchExpanded ) { selectedSwitchMethod = ''; switchConfirming = false }"
					:aria-expanded="switchExpanded.toString()"
					class="flex items-center justify-between w-full cursor-pointer bg-transparent border-0 px-4 py-3 text-sm font-medium text-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-affwp-brand-500">
					<span><?php esc_html_e( 'Pay with another method', 'affiliate-wp' ); ?></span>
					<span class="text-gray-400 transition-transform duration-200"
						:class="switchExpanded ? '-rotate-90' : ''"
						aria-hidden="true">
						<?php \AffiliateWP\Utils\Icons::render( 'chevron-right', '', [ 'class' => 'h-4 w-4' ] ); ?>
					</span>
				</button>

				<!--
					Two-stage panel: pick a method first, then confirm. The
					confirm step is non-optional because the action runs the
					provider immediately (Stripe transfer, PayPal payout,
					store-credit issuance), creates a new payout row, and
					marks this one as superseded. One destructive cascade
					earns one explicit "yes."
				-->
				<div x-show="switchExpanded" x-collapse>
					<div class="border-t border-gray-100 bg-gray-50/50 px-4 py-3">

						<!-- Stage 1: pick. -->
						<template x-if="! switchConfirming">
							<div>
								<div class="flex flex-col gap-2 mb-3">
									<template x-for="opt in drawer.switchableMethods" :key="opt.slug">
										<label class="flex items-start gap-2.5 cursor-pointer py-1">
											<input type="radio"
												name="affwp-switch-method-radio"
												:value="opt.slug"
												x-model="selectedSwitchMethod"
												class="mt-0.5 h-4 w-4 text-affwp-brand-500 border-gray-300 focus:ring-affwp-brand-500 cursor-pointer">
											<span class="flex flex-col gap-0.5 min-w-0 flex-1">
												<span class="text-sm font-medium text-gray-900" x-text="opt.label"></span>
												<span class="text-xs text-gray-500" x-text="opt.description" x-show="opt.description"></span>
											</span>
										</label>
									</template>
								</div>

								<!--
									@click.stop on every action button here.
									These transition the Stage 1 / Stage 2
									template x-ifs, which remove the clicked
									button from the DOM at the same moment
									the click event tries to bubble. Without
									.stop, the click reaches the drawer
									trait's outside-click handler, which
									calls closest() on the detached element
									(returns null) and closes the drawer.
								-->
								<div class="flex items-center gap-3">
									<button type="button"
										@click.stop="switchConfirming = true"
										:disabled="! selectedSwitchMethod"
										class="cursor-pointer inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
										<?php esc_html_e( 'Continue', 'affiliate-wp' ); ?>
									</button>
									<button type="button"
										@click.stop="switchExpanded = false; selectedSwitchMethod = ''"
										class="cursor-pointer bg-transparent border-0 p-0 text-sm text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:underline rounded">
										<?php esc_html_e( 'Cancel', 'affiliate-wp' ); ?>
									</button>
								</div>
							</div>
						</template>

						<!--
							Stage 2: confirm. Names the consequence in plain
							language (amount + method + supersession) before
							the action fires. The primary button label is
							verbose on purpose so the click reads as
							explicit consent to do that exact thing now.
						-->
						<template x-if="switchConfirming">
							<div class="flex flex-col gap-3">
								<p class="text-sm text-gray-700 m-0">
									<?php
									printf(
										/* translators: 1: amount with currency, 2: selected method label, 3: superseded payout id */
										esc_html__( 'This will pay %1$s now via %2$s. The new payout supersedes #%3$s, which stays as a historical record.', 'affiliate-wp' ),
										'<span class="font-semibold text-gray-900" x-text="drawer.payout.amount_formatted"></span>',
										'<span class="font-semibold text-gray-900" x-text="selectedSwitchMethodLabel"></span>',
										'<span x-text="drawer.payout.payout_id"></span>'
									);
									?>
								</p>

								<div class="flex items-center gap-3">
									<button type="button"
										@click.stop="drawer.switchMethod( selectedSwitchMethod, null ); switchExpanded = false; selectedSwitchMethod = ''; switchConfirming = false"
										:disabled="drawer.isSwitching"
										class="cursor-pointer inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border border-transparent bg-affwp-brand-500 px-3 py-1.5 text-sm font-medium text-white shadow-sm hover:bg-affwp-brand-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors">
										<svg x-show="drawer.isSwitching" x-cloak class="animate-spin -ml-0.5 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" aria-hidden="true">
											<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
											<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
										</svg>
										<span x-text="drawer.isSwitching
											? '<?php echo esc_js( __( 'Paying…', 'affiliate-wp' ) ); ?>'
											: '<?php echo esc_js( __( 'Pay', 'affiliate-wp' ) ); ?>' + ' ' + drawer.payout.amount_formatted + ' ' + '<?php echo esc_js( __( 'now', 'affiliate-wp' ) ); ?>'"></span>
									</button>
									<button type="button"
										@click.stop="switchConfirming = false"
										class="cursor-pointer bg-transparent border-0 p-0 text-sm text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:underline rounded">
										<?php esc_html_e( 'Back', 'affiliate-wp' ); ?>
									</button>
								</div>
							</div>
						</template>

					</div>

				</div>

			</div>
		</template>

	</div>
</template>
