@php
/** @var \App\Models\Job $job */
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Schema;

/* ---------- helpers ---------- */
$toCents = function ($v): int {
    if (is_null($v)) return 0;
    if (is_int($v)) return $v;
    if (is_numeric($v) && str_contains((string) $v, '.')) return (int) round(((float) $v) * 100);
    return (int) $v;
};

$currency = $job->currency ?? optional($job->flow)->currency ?? 'NZD';
$formatMoney = function (int $cents, string $cur = 'NZD'): string {
    $amount = number_format($cents / 100, 2);
    $symbol = match (strtoupper($cur)) {
        'NZD' => 'NZ$', 'AUD' => 'A$', 'USD' => '$', 'GBP' => '£', 'EUR' => '€',
        default => ''
    };
    return $symbol ? $symbol.$amount : ($amount.' '.strtoupper($cur));
};

/* ---------- totals ---------- */
$totalCents = $job->charge_cents
    ?? $job->total_cents
    ?? $toCents($job->charge_amount ?? $job->total_amount ?? 0);

$paidCents = (int) ($job->paid_cents ?? 0);
if ($paidCents === 0 && method_exists($job, 'payments')) {
    try {
        $col = Schema::hasColumn('payments', 'amount_cents') ? 'amount_cents'
             : (Schema::hasColumn('payments', 'amount') ? 'amount' : null);
        if ($col) {
            $paidCents = (int) $job->payments()
                ->whereIn('status', ['succeeded','captured','paid','completed'])
                ->where(function ($q) {
                    $q->whereNull('purpose')->orWhereNotIn('purpose', ['hold','bond_hold']);
                })
                ->sum($col);
        }
    } catch (\Throwable $e) { /* ignore */ }
}
$remainingCents = max(0, (int)$totalCents - (int)$paidCents);

/* ---------- hold (job → flow fallbacks) ---------- */
$holdCents = (function () use ($job, $toCents) {
    $candidates = [
        $job->hold_amount_cents ?? null,
        $job->hold_cents ?? null,
        optional($job->flow)->hold_cents ?? null,
        $toCents($job->hold_amount ?? null),
        $toCents(optional($job->flow)->hold_amount ?? null),
        $job->bond_cents ?? null,
        optional($job->flow)->bond_cents ?? null,
        optional($job->flow)->deposit_cents ?? null,
        optional($job->flow)->hold_amount_cents ?? null,
    ];
    foreach ($candidates as $v) if (is_numeric($v) && (int)$v > 0) return (int)$v;
    return 0;
})();

/* ---------- mode (adds hold-only handling like the React version) ---------- */
$serverMode = $mode ?? null; // allow controller override
$computedMode = ($remainingCents > 0 && $holdCents > 0) ? 'charge+hold'
    : (($remainingCents > 0) ? 'charge'
        : (($holdCents > 0) ? 'hold' : 'none'));
$mode = $serverMode ?: $computedMode;

/* ---------- dates ---------- */
$tz = $job->timezone ?? config('app.timezone', 'UTC');
$startAt = $job->start_at ? Carbon::parse($job->start_at)->timezone($tz) : null;
$endAt   = $job->end_at   ? Carbon::parse($job->end_at)->timezone($tz)   : null;
$fmt = fn (Carbon $c) => $c->isoFormat('ddd D MMM, HH:mm');
$durationLabel = null;
if ($startAt && $endAt && $endAt->greaterThan($startAt)) {
    $mins = $endAt->diffInMinutes($startAt);
    $d = intdiv($mins, 1440); $h = intdiv($mins % 1440, 60); $m = $mins % 60;
    $parts = []; if ($d) $parts[] = $d.'d'; if ($h) $parts[] = $h.'h'; if (!$d && !$h && $m) $parts[] = $m.'m';
    $durationLabel = implode(' ', $parts);
}
$tzShort = $startAt?->format('T') ?? $endAt?->format('T') ?? strtoupper($tz);

/* ---------- urls / keys ---------- */
$stripeKey     = config('services.stripe.key');
$bundleUrl     = route('portal.pay.bundle.job',   ['job' => $job->getKey()]);
$successUrl    = route('portal.pay.job.complete', ['job' => $job->getKey()]);
$recordPaidUrl = route('portal.pay.recordPaid',   ['job' => $job->getKey()]);
$customerEmail = optional($job->customer)->email ?? ($job->customer_email ?? '');

/* ---------- CTA text (prebuilt) ---------- */
$ctaPayText  = $remainingCents > 0
    ? 'Pay ' . $formatMoney((int)$remainingCents, $currency)
    : ($mode === 'hold' ? 'Authorise ' . $formatMoney((int)$holdCents, $currency) . ' hold' : 'Confirm');
$ctaHoldText = ($mode === 'charge+hold' && $holdCents > 0)
    ? ' + authorise ' . $formatMoney((int)$holdCents, $currency) . ' hold'
    : '';

/* ---------- booking ref ---------- */
$jobRef = $job->external_reference
      ?? $job->reference
      ?? $job->job_reference
      ?? $job->ref
      ?? ('#'.$job->id);

/* ---------- GA4 ---------- */
$gaItem = [
    'item_id'   => (string)($jobRef ?? $job->id),
    'item_name' => (string)($job->title ?? 'Booking'),
    'price'     => (float) number_format(($remainingCents ?? 0)/100, 2, '.', ''),
    'quantity'  => 1,
];

/* ---------- controller may pass $clientSecret for hold-only ---------- */
$clientSecret = $clientSecret ?? null;
@endphp

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Secure Payment • {{ config('app.name') }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://js.stripe.com/v3/"></script>

<!-- GA4 base tag -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NWSW5940NR"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }
  function gaTrack(eventName, params){ try { gtag('event', eventName, params || {}); } catch(_) {} }

  gtag('js', new Date());
  gtag('config', 'G-NWSW5940NR', {
    send_page_view: true,
    debug_mode: true,
    transport_type: 'beacon',
    allow_google_signals: true,
    anonymize_ip: true,
    page_title: document.title,
    page_location: location.href
  });

  gtag('event', 'begin_checkout', {
    currency: @json(strtoupper($currency)),
    value: {{ number_format(($remainingCents ?? 0)/100, 2, '.', '') }},
    items: [@json($gaItem)],
    coupon: undefined
  });

  gtag('event', 'view_cart', {
    currency: @json(strtoupper($currency)),
    value: {{ number_format(($remainingCents ?? 0)/100, 2, '.', '') }},
    items: [@json($gaItem)],
    dd_total_cents: {{ (int)$totalCents }},
    dd_paid_cents: {{ (int)$paidCents }},
    dd_hold_cents: {{ (int)$holdCents }}
  });
</script>

<style>
  .card-shadow { box-shadow: 0 10px 24px rgba(2,6,23,.08), 0 6px 12px rgba(2,6,23,.06); }
  .badge { border-radius:9999px; padding:2px 10px; font-size:12px; font-weight:600; }
  .badge-green { background:#DCFCE7; color:#166534; }
  .badge-amber { background:#FEF3C7; color:#92400E; }
  .badge-slate { background:#E2E8F0; color:#0F172A; }
  .mono { font-variant-numeric: tabular-nums; }
  .sr-input { padding:10px; border-radius:10px; border:1px solid #e5e7eb; background:white; }
  #payment-element { border:1px solid #e5e7eb; border-radius:10px; background:#fff; }
  .SubmitButton, .p-SubmitButton, button[type="submit"].SubmitButton { display:none !important; }
</style>
</head>
<body class="bg-slate-50 text-slate-900 antialiased">
<div class="min-h-screen">
  <header class="border-b border-slate-200 bg-white/70 backdrop-blur supports-[backdrop-filter]:bg-white/60">
    <div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between">
      <div class="flex items-center gap-3">
        <div class="h-9 w-9 rounded-2xl bg-slate-900 text-white grid place-items-center">🔒</div>
        <div>
          <div class="text-sm text-slate-500">Secured by</div>
          <div class="font-semibold tracking-tight">{{ config('app.name') }} (via Stripe)</div>
        </div>
      </div>
      <div class="hidden sm:flex items-center gap-2 text-sm">
        <span class="badge badge-slate">PCI DSS</span>
        <span class="badge badge-green">TLS 1.2+</span>
        <span class="badge badge-slate">3D Secure</span>
      </div>
    </div>
  </header>

  <main class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 py-8">
    <div class="mb-2">
      @php
        $header = $mode === 'hold' ? 'Authorise your refundable security hold'
          : ($mode === 'charge+hold' ? 'Complete your payment & authorise hold'
          : ($mode === 'charge' ? 'Complete your payment' : 'Nothing to pay'));
      @endphp
      <h1 class="text-2xl sm:text-3xl font-semibold tracking-tight">{{ $header }}</h1>
      <p class="mt-1 text-slate-600">Reservation {{ $jobRef }} • {{ $job->title ?? 'Booking' }}</p>

      @if($startAt || $endAt)
        <div class="mt-2 text-sm text-slate-700 flex flex-wrap items-center gap-x-3 gap-y-1">
          <span class="font-medium">Rental:</span>
          <span class="mono">
            @if($startAt) {{ $fmt($startAt) }} @else <em>TBC</em> @endif
            <span class="opacity-60">→</span>
            @if($endAt) {{ $fmt($endAt) }} @else <em>TBC</em> @endif
          </span>
          <span class="text-slate-500">@if($durationLabel) ({{ $durationLabel }}) @endif • {{ $tzShort }}</span>
        </div>
      @endif
    </div>

    {{-- Only show a red banner when there is TRULY nothing to do --}}
    @if($mode === 'none')
      <div class="rounded-xl border border-rose-200 bg-rose-50 text-rose-700 p-3 text-sm mb-4">
        <span class="font-semibold">Heads up:</span>
        <span>Nothing to chargeeee.</span>
      </div>
    @endif
    <div id="pay-alert" class="hidden rounded-xl border border-rose-200 bg-rose-50 text-rose-700 p-3 text-sm mb-4">
      <span class="font-semibold">Heads up:</span>
      <span data-slot="message">Something went wrong.</span>
    </div>

    <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 items-start mt-4">
      <!-- LEFT -->
      <section class="lg:col-span-2">
        <div class="bg-white rounded-2xl card-shadow p-6">
          <div class="space-y-4">
            <div class="rounded-xl border border-slate-200 p-4 bg-slate-50/60">
              <h2 class="font-semibold mb-2">What you’ll authorise now</h2>
              <ul class="text-sm text-slate-700 list-disc pl-5 space-y-1">
                @if($remainingCents > 0)
                  <li><strong>Amount due now:</strong> {{ $formatMoney((int)$remainingCents, $currency) }}</li>
                @endif
                @if($holdCents > 0)
                  <li><strong>Refundable security hold:</strong> {{ $formatMoney((int)$holdCents, $currency) }} will be authorised (manual capture).</li>
                @endif
                <li><strong>Save card for off-session:</strong> we may save your card for permitted adjustments.</li>
              </ul>
            </div>

            <div class="grid sm:grid-cols-2 gap-4">
              <div>
                <label class="block text-sm font-medium mb-1" for="payer-name">Name on card</label>
                <input id="payer-name" class="sr-input w-full" placeholder="Jane Appleseed" autocomplete="cc-name">
              </div>
              <div>
                <label class="block text-sm font-medium mb-1" for="payer-email">Receipt email</label>
                <input id="payer-email" class="sr-input w-full" placeholder="you@example.com" type="email" autocomplete="email" value="{{ old('email', $customerEmail) }}">
              </div>
            </div>

            <div>
              <label class="block text-sm font-medium mb-1">Card payment</label>
              <div id="payment-element"></div>
            </div>

            <button id="pay-btn"
              class="w-full inline-flex items-center justify-center gap-2 rounded-xl bg-indigo-600 text-white font-medium py-3 hover:bg-indigo-700 focus:ring-2 focus:ring-indigo-500 disabled:opacity-60 disabled:cursor-not-allowed">
              <svg id="pay-spinner" class="hidden animate-spin h-5 w-5" viewBox="0 0 24 24" fill="none" aria-hidden="true">
                <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-opacity="0.2" stroke-width="4"></circle>
                <path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" stroke-width="4"></path>
              </svg>
              Processing…
            </button>

            <div id="action-message" class="text-sm"></div>
          </div>
        </div>
      </section>

      <!-- RIGHT -->
      <aside class="lg:col-span-1">
        <div class="bg-white rounded-2xl card-shadow p-6 sticky top-6">
          <div class="flex items-center justify-between">
            <h2 class="font-semibold">Payment summary</h2>
            @if($remainingCents === 0)
              <span class="badge badge-green">Paid</span>
            @else
              <span class="badge badge-amber">Unpaid</span>
            @endif
          </div>
          <dl class="mt-4 space-y-3">
            <div class="flex items-center justify-between text-sm">
              <dt class="text-slate-600">Total</dt>
              <dd class="font-medium">{{ $formatMoney((int)$totalCents, $currency) }}</dd>
            </div>
            <div class="flex items-center justify-between text-sm">
              <dt class="text-slate-600">Paid so far</dt>
              <dd class="font-medium">{{ $formatMoney((int)$paidCents, $currency) }}</dd>
            </div>
            <div class="h-px bg-slate-200 my-2"></div>
            <div class="flex items-center justify-between">
              <dt class="text-slate-700 font-medium">Amount due now</dt>
              <dd class="text-lg font-semibold">{{ $formatMoney((int)$remainingCents, $currency) }}</dd>
            </div>
            @if($holdCents > 0)
              <div class="h-px bg-slate-200 my-2"></div>
              <div class="text-xs text-slate-600">
                A refundable security hold of <strong>{{ $formatMoney((int)$holdCents, $currency) }}</strong> will be authorised after payment (manual capture).
              </div>
            @endif
          </dl>
        </div>
      </aside>
    </div>
  </main>
</div>

<meta name="csrf-token" content="{{ csrf_token() }}">
<script>
document.addEventListener('DOMContentLoaded', async () => {
  const stripeKey   = @json($stripeKey);
  const bundleUrl   = @json($bundleUrl);
  const recordUrl   = @json($recordPaidUrl);
  const successUrl  = @json($successUrl);
  const remaining   = Number(@json((int) $remainingCents));
  const holdCents   = Number(@json((int) $holdCents));
  const mode        = @json($mode);
  const clientSecretFromServer = @json($clientSecret); // present for hold-only if controller passed it
  const csrf        = document.querySelector('meta[name="csrf-token"]').content;

  const btn      = document.getElementById('pay-btn');
  const spinner  = document.getElementById('pay-spinner');
  const alertBox = document.getElementById('pay-alert');
  const alertMsg = alertBox?.querySelector('[data-slot="message"]');

  const showError = (m) => {
    try {
      if (alertBox && alertMsg) { alertMsg.textContent = m; alertBox.classList.remove('hidden'); }
      else alert(m);
    } catch (_) {}
  };
  const setLoading = (on) => { btn.disabled = !!on; spinner?.classList.toggle('hidden', !on); };

  let stripe, elements, clientSecret, chosenType; // 'payment' | 'hold'

  function submitLabel() {
    if (mode === 'hold') return `Authorise {{ $formatMoney((int)$holdCents, $currency) }} hold`;
    if (mode === 'charge+hold') return 'Pay & Authorise Hold';
    if (mode === 'charge') return 'Pay Now';
    return 'Continue';
  }

  // Prepare client secret
  try {
    setLoading(true);
    stripe = Stripe(stripeKey);

    // 1) If HOLD-ONLY and controller provided a client_secret, use it immediately
    if (mode === 'hold' && clientSecretFromServer) {
      clientSecret = clientSecretFromServer;
      chosenType = 'hold';
    } else {
      // 2) Otherwise use the bundle endpoint to get charge and/or hold intents
      const resp = await fetch(bundleUrl, {
        method: 'POST',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-CSRF-TOKEN': csrf
        },
        body: JSON.stringify({
          requested_charge_cents: remaining > 0 ? remaining : 0,
          requested_hold_cents: holdCents > 0 ? holdCents : 0
        })
      });

      if (!resp.ok) {
        let msg = 'Server error preparing payment';
        try { const j = await resp.json(); msg = j.message || j.error || msg; } catch (_) {}
        throw new Error(msg);
      }

      const data = await resp.json();
      const balanceSecret = data?.payment?.client_secret || null;
      const bondSecret    = data?.hold?.client_secret || null;

      if (remaining > 0 && balanceSecret) {
        clientSecret = balanceSecret;
        chosenType   = 'payment';
      } else if (bondSecret) {
        clientSecret = bondSecret;
        chosenType   = 'hold';
      } else if (mode === 'none') {
        btn.textContent = 'Nothing to pay';
        btn.disabled = true;
        return;
      } else {
        throw new Error('Could not initialize payment session.');
      }
    }

    // Mount Payment Element
    elements = stripe.elements({ clientSecret, appearance: { theme: 'stripe' }});
    const paymentElement = elements.create('payment');
    paymentElement.mount('#payment-element');

    // Set CTA label
    btn.textContent = submitLabel();
    btn.disabled = false;
  } catch (e) {
    console.error(e);
    btn.textContent = 'Try again';
    showError(e?.message || 'Could not prepare payment.');
    return;
  } finally {
    setLoading(false);
  }

  // Confirm PI & record
  btn.addEventListener('click', async () => {
    try {
      setLoading(true);
      await elements.submit();

      const payerName = document.getElementById('payer-name')?.value || undefined;
      const payerMail = document.getElementById('payer-email')?.value || undefined;

      const {paymentIntent, error} = await stripe.confirmPayment({
        elements,
        clientSecret,
        redirect: 'if_required',
        confirmParams: {
          payment_method_data: { billing_details: { name: payerName, email: payerMail } },
        },
      });

      if (error) throw error;
      if (!paymentIntent) throw new Error('No payment intent returned');

      const ok = new Set(['succeeded','processing','requires_capture']);
      if (!ok.has(paymentIntent.status)) {
        throw new Error(`Unexpected status: ${paymentIntent.status}`);
      }

      // IMPORTANT: send the correct field depending on what we confirmed
      const payload = {
        receipt_email: payerMail,
        requested_hold_cents: holdCents > 0 ? holdCents : 0
      };

      if (chosenType === 'hold') {
        payload.hold_intent = paymentIntent.id;            // manual-capture hold
      } else {
        payload.payment_intent = paymentIntent.id;         // charge
      }

      const rec = await fetch(recordUrl, {
        method: 'POST',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-CSRF-TOKEN': csrf
        },
        body: JSON.stringify(payload)
      });

      if (!rec.ok) {
        let msg = 'Could not save receipt';
        try { const j = await rec.json(); msg = j.message || j.error || msg; } catch (_) {}
        console.warn('record-paid failed', rec.status, msg);
      }

      const qs = new URLSearchParams({ payment_intent: paymentIntent.id });
      window.location.assign(successUrl + '?' + qs.toString());
    } catch (e) {
      console.error(e);
      showError(e?.message || 'Please check your details and try again.');
    } finally {
      setLoading(false);
    }
  });
});
</script>
</body>
</html>
