'use client';
import { FunctionComponent, useRef, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Checkbox, CircularProgress, FormControlLabel, Paper, Skeleton, Stack, Typography } from '@mui/material';
import { AppButton, AppIcon, InstallmentScheduleRow } from '@/components';
import AppAlert from '@/components/common/AppAlert';
import { ApiError } from '@/lib/api/errors';
import { useBnplSchedule, useIssueBnplToken } from '@/services/bnpl';
import type { IssueBnplTokenResult, ProviderCode } from '@/services/bnpl/types';

interface ScheduleStepProps {
  bookingRequestId: number;
  providerCode: ProviderCode;
  planId: string;
  onBack: () => void;
  /** The provider handoff — the page follows `redirectUrl`. */
  onIssued: (result: IssueBnplTokenResult) => void;
  /** A `409` (already paid / in progress / window lapsed) — the page converges by reading the order. */
  onConverged: () => void;
}

/**
 * D4 · تایید طرح و قرارداد — the repayment schedule + contract acceptance. Renders the **served** repayment
 * rows (پیش‌پرداخت today + قسط ۱…N with Shamsi due dates + amounts), the ownership-truth note (the
 * agreement is customer ↔ provider; Balinyaar is paid in full), and a contract-acceptance checkbox that
 * **gates** the final action. «تایید نهایی و پرداخت پیش‌پرداخت» issues the provider token and hands off
 * (the page follows the redirect); on success the booking confirms exactly as the card path.
 */
const ScheduleStep: FunctionComponent<ScheduleStepProps> = ({
  bookingRequestId,
  providerCode,
  planId,
  onBack,
  onIssued,
  onConverged,
}) => {
  const t = useTranslations('bnpl');
  const tc = useTranslations('common');

  const { data: schedule, isLoading, isError, refetch } = useBnplSchedule(bookingRequestId, providerCode, planId);
  const issue = useIssueBnplToken();

  const [accepted, setAccepted] = useState(false);
  // One idempotency key per handoff attempt, reused across retries of that attempt (mirrors C6).
  const attemptKeyRef = useRef<string | null>(null);
  const providerName = t(`provider_${providerCode}`);

  const busy = issue.isPending || issue.isSuccess;

  const handleConfirm = () => {
    attemptKeyRef.current ??= crypto.randomUUID();
    issue.mutate(
      { bookingRequestId, providerCode, planId, idempotencyKey: attemptKeyRef.current },
      {
        onSuccess: (result) => onIssued(result),
        onError: (error) => {
          if (error instanceof ApiError && error.status === 409) onConverged();
        },
      },
    );
  };

  // Handoff in progress — the provider redirect is being followed.
  if (busy) {
    return (
      <Paper elevation={0} sx={{ p: 4, borderRadius: 2, border: '1px solid', borderColor: 'divider', textAlign: 'center' }}>
        <Stack sx={{ gap: 1.5, alignItems: 'center' }}>
          <CircularProgress color="secondary" size="2.5rem" />
          <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
            {t('redirecting', { provider: providerName })}
          </Typography>
        </Stack>
      </Paper>
    );
  }

  if (isLoading) return <ScheduleSkeleton />;

  if (isError || !schedule) {
    return (
      <Stack sx={{ gap: 2 }}>
        <AppAlert severity="error" variant="outlined" sx={{ marginY: 0 }}>
          {t('error_body')}
        </AppAlert>
        <AppButton variant="outlined" color="secondary" onClick={() => refetch()}>
          {tc('retry')}
        </AppButton>
      </Stack>
    );
  }

  const inlineError =
    issue.error && !(issue.error instanceof ApiError && issue.error.status === 409) ? t('settle_failed_body') : null;

  return (
    <Stack sx={{ gap: 2 }}>
      <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
        {t('schedule_title')}
      </Typography>

      <Stack sx={{ gap: 1 }}>
        {schedule.rows.map((row) => (
          <InstallmentScheduleRow key={`${row.kind}-${row.sequence}`} row={row} />
        ))}
      </Stack>

      {/* The ownership truth: the installment agreement is customer ↔ provider; Balinyaar is paid in full. */}
      <Paper
        elevation={0}
        sx={{
          p: 1.75,
          borderRadius: 2,
          border: '1px solid',
          borderColor: 'var(--bal-secondary)',
          backgroundColor: 'var(--bal-secondary-soft)',
        }}
      >
        <Stack direction="row" sx={{ gap: 1, alignItems: 'flex-start' }}>
          <AppIcon icon="info" size={18} color="var(--bal-secondary-dark)" />
          <Typography variant="caption" sx={{ color: 'var(--bal-secondary-dark)', lineHeight: 1.9 }}>
            {t('contract_note', { provider: providerName })}
          </Typography>
        </Stack>
      </Paper>

      <FormControlLabel
        control={<Checkbox checked={accepted} onChange={(e) => setAccepted(e.target.checked)} color="secondary" />}
        label={
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t('contract_consent')}
          </Typography>
        }
        sx={{ alignItems: 'flex-start', m: 0 }}
      />

      {inlineError ? (
        <AppAlert severity="error" variant="outlined" sx={{ marginY: 0 }}>
          {inlineError}
        </AppAlert>
      ) : null}

      <Stack sx={{ gap: 1 }}>
        <AppButton
          color="secondary"
          variant="contained"
          size="large"
          disabled={!accepted}
          onClick={handleConfirm}
          sx={{ py: 1.25 }}
        >
          {t('pay_down_payment')}
        </AppButton>
        <AppButton variant="text" color="primary" onClick={onBack}>
          {tc('back')}
        </AppButton>
      </Stack>
    </Stack>
  );
};

function ScheduleSkeleton() {
  return (
    <Stack sx={{ gap: 1.5 }}>
      <Skeleton variant="text" width="40%" height={28} />
      {[0, 1, 2, 3].map((i) => (
        <Skeleton key={i} variant="rounded" height={56} />
      ))}
      <Skeleton variant="rounded" height={64} />
      <Skeleton variant="rounded" height={48} />
    </Stack>
  );
}

export default ScheduleStep;
