'use client';
import { Suspense, useEffect, useRef, type ReactNode } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useRouter, useSearchParams } from 'next/navigation';
import { useQueryClient } from '@tanstack/react-query';
import { CircularProgress, Paper, Stack, Typography } from '@mui/material';
import { AppButton, AppIcon, AppLoading } from '@/components';
import { ROUTES } from '@/constants';
import { useAcceptBnplSchedule, useBnplOrder } from '@/services/bnpl';
import { invalidateAfterBnplSettlement } from '@/services/bnpl/invalidations';
import { isBnplSettlementSuccess } from '@/services/bnpl/types';
import {
  BNPL_QUERY_OUTCOME,
  BNPL_QUERY_PROVIDER,
  BNPL_QUERY_REQUEST_ID,
  BNPL_QUERY_TRANSACTION_ID,
  CHECKOUT_METHOD_BNPL,
  CHECKOUT_QUERY_METHOD,
} from '@/services/bnpl/constants';
import {
  CHECKOUT_QUERY_BOOKING_ID,
  CHECKOUT_QUERY_REQUEST_ID,
} from '@/services/payment/constants';

/**
 * Return-from-provider surface — drives the tail of the BNPL checkout: report the return
 * (`useAcceptBnplSchedule`; the settle trigger in the mock, an order read on the real path), then a brief
 * settle-pending state backed by the bounded order poll until terminal. On settlement: hand off to the
 * **reused f9 confirmation** marked «paid via installments» (the booking confirmed exactly as the card
 * path); on decline: a retry (a fresh D4 = a new attempt) or the card fall-back; on window-lapse: back to
 * the request.
 */
export default function BnplReturnPage() {
  return (
    <Suspense fallback={<AppLoading />}>
      <BnplReturnScreen />
    </Suspense>
  );
}

function BnplReturnScreen() {
  const t = useTranslations('bnpl');
  const tp = useTranslations('payment');
  const locale = useLocale();
  const router = useRouter();
  const params = useSearchParams();
  const queryClient = useQueryClient();

  const requestId = Number(params.get(BNPL_QUERY_REQUEST_ID));
  const validId = Number.isInteger(requestId) && requestId > 0;
  const transactionIdParam = params.get(BNPL_QUERY_TRANSACTION_ID);
  const transactionId = transactionIdParam ? Number(transactionIdParam) : null;
  const provider = params.get(BNPL_QUERY_PROVIDER) ?? '';
  const outcome = params.get(BNPL_QUERY_OUTCOME) === 'failure' ? ('failure' as const) : ('success' as const);

  const accept = useAcceptBnplSchedule();
  const { mutate: acceptMutate } = accept;

  // Fire the settle report exactly once per mount — a refresh replays it (idempotent convergence).
  const firedRef = useRef(false);
  useEffect(() => {
    if (firedRef.current || !validId) return;
    firedRef.current = true;
    acceptMutate({ bookingRequestId: requestId, bnplTransactionId: transactionId, outcome });
  }, [acceptMutate, validId, requestId, transactionId, outcome]);

  const settled = accept.isSuccess || accept.isError;
  const acceptSawSuccess = accept.data ? isBnplSettlementSuccess(accept.data) : false;
  // Poll only for the late-settle case: when the accept result is ALREADY a settlement success (the mock
  // down-payment-cleared path), the navigation effect hands off immediately — reading the order would be a
  // needless fetch. Poll only when accept resolved without a settlement (real provider callback still in flight).
  const orderQuery = useBnplOrder(validId ? requestId : undefined, { enabled: settled && !acceptSawSuccess });
  const order = settled ? orderQuery.data : undefined;

  const succeeded = acceptSawSuccess || order?.status === 'settled';
  const windowExpired = accept.data?.requestStatus === 'payment_deadline_expired';
  const failed = !succeeded && !windowExpired && (accept.data?.status === 'failed' || order?.status === 'failed');

  // Hand off to the confirmation exactly once. The accept mutation already invalidated on immediate
  // success; a success that arrived later through the poll invalidates here instead (never twice).
  const navigatedRef = useRef(false);
  const bookingId = accept.data?.bookingId ?? order?.bookingId ?? null;
  useEffect(() => {
    if (!succeeded || navigatedRef.current) return;
    navigatedRef.current = true;
    if (!acceptSawSuccess) {
      invalidateAfterBnplSettlement(queryClient, requestId, bookingId);
    }
    const query = new URLSearchParams({
      [CHECKOUT_QUERY_REQUEST_ID]: String(requestId),
      [CHECKOUT_QUERY_METHOD]: CHECKOUT_METHOD_BNPL,
    });
    if (bookingId != null) query.set(CHECKOUT_QUERY_BOOKING_ID, String(bookingId));
    if (provider) query.set(BNPL_QUERY_PROVIDER, provider);
    router.replace(`/${locale}${ROUTES.CHECKOUT_CONFIRMATION}?${query.toString()}`);
  }, [succeeded, acceptSawSuccess, bookingId, queryClient, requestId, provider, router, locale]);

  if (!validId) {
    return (
      <StateCard icon="error" tone="var(--bal-error)" title={t('error_title')}>
        <AppButton variant="contained" onClick={() => router.replace(`/${locale}${ROUTES.BOOKINGS}`)}>
          {t('pay_with_card')}
        </AppButton>
      </StateCard>
    );
  }

  if (windowExpired) {
    // The payment window lapsed during the handoff — card payment is impossible now, so route to the
    // request (not the card checkout). Reuse the f9 window-expired copy + the matching back-to-request CTA.
    return (
      <StateCard icon="pending" tone="var(--bal-warning)" title={tp('window_expired_title')} body={tp('window_expired_body')}>
        <AppButton
          variant="contained"
          onClick={() => router.replace(`/${locale}${ROUTES.BOOKING_REQUEST_STATUS}/${requestId}`)}
        >
          {tp('back_to_request')}
        </AppButton>
      </StateCard>
    );
  }

  if (failed) {
    return (
      <StateCard icon="error" tone="var(--bal-error)" title={t('settle_failed_title')} body={t('settle_failed_body')}>
        <AppButton
          color="secondary"
          variant="contained"
          size="large"
          onClick={() => router.replace(`/${locale}${ROUTES.CHECKOUT_BNPL}?${BNPL_QUERY_REQUEST_ID}=${requestId}`)}
        >
          {t('retry_installments')}
        </AppButton>
        <AppButton
          variant="text"
          onClick={() => router.replace(`/${locale}${ROUTES.CHECKOUT}?${CHECKOUT_QUERY_REQUEST_ID}=${requestId}`)}
        >
          {t('pay_with_card')}
        </AppButton>
      </StateCard>
    );
  }

  // Settle-pending (and the brief succeeded → confirmation hand-off): a calm waiting state.
  return (
    <StateCard icon="installments" tone="var(--bal-secondary)" title={t('settling_title')} body={t('settling_body')}>
      <CircularProgress color="secondary" size="2.5rem" />
      <AppButton variant="text" disabled={orderQuery.isFetching} onClick={() => orderQuery.refetch()}>
        {t('check_again')}
      </AppButton>
    </StateCard>
  );
}

function StateCard({
  icon,
  tone,
  title,
  body,
  children,
}: {
  icon: string;
  tone: string;
  title: string;
  body?: string;
  children?: ReactNode;
}) {
  return (
    <Paper elevation={0} sx={{ p: 4, textAlign: 'center', border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
      <Stack sx={{ gap: 1.5, alignItems: 'center' }}>
        <AppIcon icon={icon} size={44} color={tone} />
        <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
          {title}
        </Typography>
        {body ? (
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {body}
          </Typography>
        ) : null}
        {children}
      </Stack>
    </Paper>
  );
}
