'use client';

import { useCallback, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { AxiosError } from 'axios';
import { bookingApi } from '@/lib/api';
import { formatDate } from '@/lib/intl-date';
import { useBookingDraft } from '@/lib/store/booking-draft';
import { Stepper } from '@/components/checkout/Stepper';
import { HoldCountdown } from '@/components/checkout/HoldCountdown';
import { HoldExpiredModal } from '@/components/checkout/HoldExpiredModal';
import { useToast } from '@/components/ui/Toaster';
import type { Booking } from '@/types/api';

/**
 * Feature 054 (US3, T041) — Terminal pre-pay review.
 *
 * Replaces the heavy CREATE form when a draft already exists. Shows event
 * basics + selected address + a summary of wallet/promo/loyalty selections
 * persisted to the booking-draft store at the /summary step. The "Confirm
 * & pay" button calls `bookingApi.submit` (moved here from /summary) and
 * routes to `/checkout/pay/{publicId}`.
 *
 * Editing event basics or address is intentionally out of scope — the backend
 * has no PATCH /customer/bookings/{id} route. Users who need a different
 * date or address have to start over from /cart.
 */
export function CheckoutEventReview({ booking, locale }: { booking: Booking; locale: string }) {
  const t = useTranslations('checkout.event');
  const tSummary = useTranslations('checkout.summary');
  const router = useRouter();
  const toast = useToast();

  const promoCode = useBookingDraft((s) => s.promoCode);
  const appliedWalletMinor = useBookingDraft((s) => s.appliedWalletMinor);
  const appliedLoyaltyByVendor = useBookingDraft((s) => s.appliedLoyaltyByVendor);
  const ensurePaymentIdempotencyKey = useBookingDraft((s) => s.ensurePaymentIdempotencyKey);
  const setSubmittedDueMinor = useBookingDraft((s) => s.setSubmittedDueMinor);

  const [submitting, setSubmitting] = useState(false);
  const [holdExpired, setHoldExpired] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);

  const handleHoldExpired = useCallback(() => setHoldExpired(true), []);

  const handleConfirm = useCallback(async () => {
    if (submitting || holdExpired) return;
    setSubmitting(true);
    setSubmitError(null);
    const idempotencyKey = ensurePaymentIdempotencyKey();

    try {
      const totalLoyalty = Object.values(appliedLoyaltyByVendor).reduce((s, v) => s + v, 0);
      const submitted = await bookingApi.submit(locale, booking.public_id, idempotencyKey, {
        promoCode: promoCode ?? undefined,
        walletAmountMinor: appliedWalletMinor > 0 ? appliedWalletMinor : undefined,
        loyaltyAmountsByVendor: Object.values(appliedLoyaltyByVendor).some((v) => v > 0)
          ? appliedLoyaltyByVendor
          : undefined,
      });
      const localDue = Math.max(
        0,
        (submitted.due_minor ?? submitted.total_minor ?? 0) - appliedWalletMinor - totalLoyalty,
      );
      setSubmittedDueMinor(submitted.due_minor ?? localDue);

      if (submitted.lifecycle_status === 'confirmed') {
        router.push(`/${locale}/checkout/pay/${submitted.public_id}`);
      } else {
        router.push(`/${locale}/me/bookings/${submitted.public_id}`);
      }
    } catch (err) {
      const axErr = err as AxiosError<{ errors?: unknown; data?: Booking }>;
      const status = axErr.response?.status;

      if (status === 409) {
        const replayedBooking = axErr.response?.data?.data;
        const targetId = replayedBooking?.public_id ?? booking.public_id;
        router.push(`/${locale}/checkout/confirmed/${targetId}`);
        return;
      }

      if (status === 422) {
        setSubmitError(tSummary('submit_error_422'));
      } else if (status !== undefined && status >= 500) {
        toast(tSummary('submit_error_5xx'), 'error');
      } else {
        toast(tSummary('submit_error_generic'), 'error');
      }
    } finally {
      setSubmitting(false);
    }
  }, [
    appliedLoyaltyByVendor,
    appliedWalletMinor,
    booking.public_id,
    ensurePaymentIdempotencyKey,
    holdExpired,
    locale,
    promoCode,
    router,
    setSubmittedDueMinor,
    submitting,
    toast,
    tSummary,
  ]);

  const baseDue = booking.due_minor ?? booking.total_minor ?? 0;
  const totalLoyalty = Object.values(appliedLoyaltyByVendor).reduce((s, v) => s + v, 0);
  const displayedDue = Math.max(0, baseDue - appliedWalletMinor - totalLoyalty);

  return (
    <section className="mx-auto max-w-3xl px-4 py-8">
      <Stepper current="event" lifecycleStatus={booking.lifecycle_status} />
      <HoldCountdown expiresAt={booking.hold_expires_at} onExpired={handleHoldExpired} />
      <HoldExpiredModal open={holdExpired} />

      <h1 className="font-heading text-2xl font-bold">{t('review_title')}</h1>
      <p className="mt-1 text-sm text-neutral-600">{t('review_subtitle')}</p>

      <section className="mt-6 rounded-lg border border-neutral-200 bg-white p-4">
        <h2 className="text-sm font-semibold">{t('review_event_heading')}</h2>
        <dl className="mt-2 grid grid-cols-2 gap-2 text-sm">
          <div>
            <dt className="text-xs text-neutral-500">{t('starts_at')}</dt>
            <dd>{booking.event_starts_at ? formatDate(booking.event_starts_at, locale) : '—'}</dd>
          </div>
          <div>
            <dt className="text-xs text-neutral-500">{t('ends_at')}</dt>
            <dd>{booking.event_ends_at ? formatDate(booking.event_ends_at, locale) : '—'}</dd>
          </div>
        </dl>
      </section>

      <section className="mt-4 rounded-lg border border-neutral-200 bg-white p-4">
        <div className="flex items-start justify-between gap-3">
          <h2 className="text-sm font-semibold">{t('review_address_heading')}</h2>
          <Link
            href={`/${locale}/me/addresses?next=/${locale}/checkout/event`}
            className="text-xs text-primary-600 hover:underline"
            data-testid="event-manage-addresses-link"
          >
            {t('manage_addresses')}
          </Link>
        </div>
        {booking.address ? (
          <div className="mt-2 space-y-0.5 text-sm">
            <p className="font-medium">{booking.address.address_line}</p>
            {(booking.address.building || booking.address.floor || booking.address.apartment) && (
              <p className="text-neutral-600">
                {booking.address.building}
                {booking.address.floor ? `, ${booking.address.floor}` : ''}
                {booking.address.apartment ? `, ${booking.address.apartment}` : ''}
              </p>
            )}
            <p className="text-neutral-700">{booking.address.recipient_name}</p>
            <p className="text-neutral-600" dir="ltr">{booking.address.recipient_phone_e164}</p>
          </div>
        ) : (
          <p className="mt-2 text-sm text-neutral-500">—</p>
        )}
      </section>

      <section className="mt-4 rounded-lg border border-neutral-200 bg-white p-4">
        <h2 className="text-sm font-semibold">{t('review_amount_due')}</h2>
        <p className="mt-1 text-2xl font-bold tabular-nums">
          {new Intl.NumberFormat(locale === 'ar' ? 'ar-EG' : 'en-EG', {
            style: 'currency',
            currency: booking.currency || 'EGP',
            minimumFractionDigits: 0,
          }).format(displayedDue / 100)}
        </p>
        {promoCode ? (
          <p className="mt-1 text-xs text-neutral-500">{t('review_promo_applied', { code: promoCode })}</p>
        ) : null}
      </section>

      {submitError ? (
        <p
          data-testid="submit-error"
          role="alert"
          className="mt-3 rounded-lg border border-danger/30 bg-danger/5 px-4 py-2 text-sm text-danger"
        >
          {submitError}
        </p>
      ) : null}

      <div className="mt-4 flex justify-end gap-2">
        <Link href={`/${locale}/checkout/summary`} className="btn-secondary">
          {t('back_to_summary')}
        </Link>
        <button
          type="button"
          onClick={handleConfirm}
          disabled={submitting || holdExpired}
          aria-busy={submitting}
          className="btn-primary disabled:opacity-60 disabled:cursor-not-allowed"
          data-testid="event-confirm-and-pay"
        >
          {submitting ? t('confirming') : t('confirm_and_pay')}
        </button>
      </div>

      <p className="mt-3 text-center text-xs text-neutral-500">
        <Link href={`/${locale}/cart`} className="hover:underline">
          {t('start_over')}
        </Link>
      </p>
    </section>
  );
}
