'use client';
import { FunctionComponent } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { Divider, Paper, Stack, Typography } from '@mui/material';
import StatusTimeline, { type TimelineNode, type TimelineNodeState } from '@/components/common/StatusTimeline';
import StatusChip, { StatusKind } from '@/components/StatusChip';
import Money from '@/components/common/Money';
import PriceBreakdown from '@/components/PriceBreakdown';
import RefundEtaBanner from '@/components/RefundEtaBanner';
import AppAlert from '@/components/common/AppAlert';
import { formatShamsiDate } from '@/utils';
import {
  CUSTOMER_REFUND_STEP_ORDER,
  refundCustomerStep,
  refundStepIndex,
  type CustomerRefundStep,
  type RefundSummary,
} from '@/services/refunds/types';

export interface RefundStatusCardProps {
  refund: RefundSummary;
}

/** The three happy steps → the semantic chip kind. `failed` is handled distinctly (never a fourth step). */
const STEP_KIND: Record<CustomerRefundStep, StatusKind> = {
  submitted: 'pending',
  on_its_way: 'info',
  completed: 'verified',
};

/**
 * The customer's read-only refund view (f10): the three-step progress (submitted → on its way →
 * completed), the refunded amount, the per-channel ETA (BNPL's honest ~7–10-day window), and — when the
 * backend serves the decomposition — the fee-leg split for transparency. `failed`/`rejected` render a
 * distinct needs-attention state with contact-support copy, **never a retry button** (retry is admin-only,
 * DEFERRED to f15). Shared: the dedicated refund-status screen and the booking-detail refund section both
 * render it. Money is display-only via the money util; labels are i18n keys, never raw codes.
 * @component RefundStatusCard
 */
const RefundStatusCard: FunctionComponent<RefundStatusCardProps> = ({ refund }) => {
  const t = useTranslations('refunds');
  const locale = useLocale();

  const step = refundCustomerStep(refund.refundStatus);
  const isFailed = step === 'failed';
  // Succeeded → mark all steps complete (past the last index); otherwise sit on the mapped step.
  const activeStep =
    refund.refundStatus === 'succeeded' ? CUSTOMER_REFUND_STEP_ORDER.length : refundStepIndex(refund.refundStatus);
  const timelineNodes: TimelineNode[] = CUSTOMER_REFUND_STEP_ORDER.map((s, index) => {
    const state: TimelineNodeState = index < activeStep ? 'completed' : index === activeStep ? 'current' : 'pending';
    const timestamp =
      s === 'submitted' && refund.createdAt
        ? formatShamsiDate(refund.createdAt, locale)
        : s === 'completed' && refund.completedAt
          ? formatShamsiDate(refund.completedAt, locale)
          : undefined;
    return { key: s, label: t(`step_${s}`), state, timestamp };
  });

  const hasDecomposition = refund.platformFeeRefundedIrr != null && refund.nursePayoutRefundedIrr != null;

  return (
    <Stack sx={{ gap: 2.5 }} data-testid="refund-status-card" data-status={refund.refundStatus}>
      {isFailed ? (
        // A failed/rejected refund must NOT show any success-framed progress, amount, or ETA — that would
        // contradict "needs attention" and, for BNPL, falsely imply the money is on its way. Only the
        // contact-support copy (+ the reference, for support) renders.
        <AppAlert severity="error" variant="outlined" data-testid="refund-failed" sx={{ marginY: 0 }}>
          <Stack sx={{ gap: 0.5 }}>
            <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
              {t('failed_title')}
            </Typography>
            <Typography variant="body2">{t('failed_body')}</Typography>
            {refund.externalRevertReference && (
              <Typography variant="caption" sx={{ fontWeight: 500, direction: 'ltr' }}>
                {t('reference_label')}: {refund.externalRevertReference}
              </Typography>
            )}
          </Stack>
        </AppAlert>
      ) : (
        <>
          <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 'var(--bal-radius-md)' }}>
            <Stack sx={{ gap: 2 }}>
              <Stack sx={{ alignItems: 'center' }}>
                <StatusChip status={STEP_KIND[step]} label={t(`rstatus_${step}`)} />
              </Stack>
              <StatusTimeline nodes={timelineNodes} />
            </Stack>
          </Paper>

          <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 'var(--bal-radius-md)' }}>
            <Stack sx={{ gap: 1.25 }}>
              <Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'baseline', gap: 2 }}>
                <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
                  {t('total_refunded_label')}
                </Typography>
                <Money amountIrr={refund.totalRefundedIrr} size="md" tone="emphasis" />
              </Stack>
              {refund.externalRevertReference && (
                <>
                  <Divider />
                  <Stack direction="row" sx={{ justifyContent: 'space-between', gap: 2 }}>
                    <Typography variant="body2" sx={{ color: 'text.secondary' }}>
                      {t('reference_label')}
                    </Typography>
                    <Typography variant="body2" sx={{ fontWeight: 500, direction: 'ltr' }}>
                      {refund.externalRevertReference}
                    </Typography>
                  </Stack>
                </>
              )}
            </Stack>
          </Paper>

          {hasDecomposition && (
            <PriceBreakdown
              rows={[
                {
                  key: 'platform_fee_refunded',
                  label: t('row_platform_fee_refunded'),
                  amountIrr: refund.platformFeeRefundedIrr as string,
                },
                {
                  key: 'nurse_payout_refunded',
                  label: t('row_nurse_payout_refunded'),
                  amountIrr: refund.nursePayoutRefundedIrr as string,
                },
              ]}
              totalLabel={t('fee_split_title')}
              totalAmountIrr={refund.totalRefundedIrr}
            />
          )}

          <RefundEtaBanner channel={refund.refundChannel} eta={refund.expectedCustomerRefundEta} />
        </>
      )}
    </Stack>
  );
};

export default RefundStatusCard;
