<?php
/**
 * Bulk-pay drawer.
 *
 * Renders the drawer shell for paying a hand-picked selection of referrals from the
 * Referrals list. The body is AJAX-loaded and rendered by the SAME grouped-payout
 * renderer as the full Pay Affiliates preview screen ({@see affwp_render_payout_preview_body()}),
 * so the two surfaces stay identical. The Alpine store + open trigger live in
 * assets/js/affwp-bulk-pay-drawer.js; PHP-computed nonce/ajax URL hand through
 * wp_localize_script(). The sticky footer mirrors the preview screen's fixed bottom bar.
 *
 * @package    AffiliateWP
 * @subpackage Admin/Payouts
 * @since      2.33.0
 */

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

/**
 * Render the bulk-pay drawer markup. Emits once per request.
 *
 * @since 2.33.0
 */
function affwp_render_bulk_pay_drawer() {

	static $rendered = false;

	if ( $rendered ) {
		return;
	}

	$rendered = true;

	affwp_drawer(
		array(
			'id'                => 'bulk-pay-drawer',
			'alpine_store'      => 'bulkPayDrawer',
			'width'             => '4xl',
			'header_style'      => 'flat',
			'close_on_backdrop' => true,
			'close_on_escape'   => true,
			// Full-drawer spinner until the preview body lands.
			'loading_x_show'    => '$store.bulkPayDrawer.isLoading && ! $store.bulkPayDrawer.bodyHtml',
			'loading_text'      => __( 'Building payout preview…', 'affiliate-wp' ),
			'content_callback'  => 'affwp_render_bulk_pay_drawer_content',
			'footer_callback'   => 'affwp_render_bulk_pay_drawer_footer',
		)
	);

	// Toast container (self-guarded; safe to call alongside other surfaces).
	affwp_toast();
}

/**
 * Drawer body: the shared payout-preview body, injected via x-html once the AJAX
 * preview resolves, plus an inline error line.
 *
 * @since 2.33.0
 */
function affwp_render_bulk_pay_drawer_content() {
	?>
	<div x-data="{ get d() { return $store.bulkPayDrawer; } }" class="affwp-ui @container">
		<div x-html="d.bodyHtml"></div>

		<?php /* Referral-level "won't be paid" reconciliation for the hand-picked selection — explains every referral that won't be paid (already in a payout, not connected, etc.) with a resolve link, since compute drops some silently. */ ?>
		<template x-if="d.skippedItems && d.skippedItems.length">
			<section class="mt-6 max-w-5xl rounded-lg bg-white ring-1 ring-gray-200 overflow-hidden">
				<header class="border-b border-gray-200 px-6 py-4">
					<h2 class="text-base/6 font-semibold tracking-tight m-0"><?php esc_html_e( "Won't be paid", 'affiliate-wp' ); ?></h2>
				</header>
				<div class="divide-y divide-gray-100 text-sm/6">
					<template x-for="(r, i) in d.skippedItems" :key="i">
						<div class="flex items-start justify-between gap-4 px-6 py-2.5">
							<span class="min-w-0">
								<span class="font-medium text-gray-900" x-text="r.affiliate"></span>
								<span class="text-gray-400"> &mdash; </span>
								<span class="text-gray-500" x-text="r.reason"></span>
								<span class="text-gray-400" x-show="r.count > 1" x-text="' (' + r.count + ')'"></span>
							</span>
							<a x-show="r.action_url" :href="r.action_url"
							:target="r.opens_drawer ? null : '_blank'"
							rel="noopener noreferrer"
							@click="if ( r.opens_drawer ) { $event.preventDefault(); $store.bulkPayDrawer.openPayout( r.payout_id ); }"
							class="shrink-0 font-medium text-gray-700 underline underline-offset-2 hover:no-underline" x-text="r.action_label"></a>
						</div>
					</template>
				</div>
			</section>
		</template>
	</div>
	<?php
}

/**
 * Drawer footer: mirrors the Pay Affiliates fixed bottom bar. Status (total · N
 * affiliates) on the left, the primary Pay action on the right. Bound to the store.
 *
 * @since 2.33.0
 */
function affwp_render_bulk_pay_drawer_footer() {
	?>
	<div x-data="{ get d() { return $store.bulkPayDrawer; } }" class="flex items-center justify-between gap-4">
		<div class="text-sm/5 min-w-0">
			<p class="m-0 tabular-nums font-medium text-gray-900" x-show="d.count" x-html="d.totalLabel"></p>
			<p class="m-0 text-gray-500" x-show="! d.count" x-html="d.totalLabel || ''"></p>
		</div>
		<div class="flex items-center gap-2 shrink-0">
			<button type="button"
				@click="d.close()"
				class="cursor-pointer rounded-md bg-transparent border-0 px-3 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-affwp-brand-500 focus-visible:ring-offset-2 transition-colors">
				<?php esc_html_e( 'Cancel', 'affiliate-wp' ); ?>
			</button>
			<button type="button"
				@click="d.pay()"
				x-show="d.count && ! d.hasBlocking"
				:disabled="d.isProcessing"
				class="cursor-pointer inline-flex items-center gap-2 rounded-md border border-transparent bg-affwp-brand-500 px-4 py-2 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="d.isProcessing" x-cloak class="animate-spin -ml-1 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
					<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="d.confirmLabel"></span>
			</button>
			<span x-show="d.hasBlocking" class="text-sm font-medium text-red-700"><?php esc_html_e( 'Resolve the issue above to continue', 'affiliate-wp' ); ?></span>
		</div>
	</div>
	<?php
}
