'use client';
import { FunctionComponent, useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import { Alert, Box, Chip, MenuItem, Skeleton, Stack, TextField, Typography } from '@mui/material';
import { formatNumber, formatShamsiDate } from '@/utils';
import type { AdminRefundResult, RefundChannel } from '@/services/refunds/types';
import { useApproveRefund, useInitiateRefund, useRefundPreview, useRejectRefund } from '@/services/refunds';
import AppButton from '../common/AppButton';
import PriceBreakdown, { type PriceBreakdownRow } from '../PriceBreakdown';
import ConfirmDialog from './ConfirmDialog';

export interface RefundPanelProps {
  bookingId: number;
  ticketId: number;
  onDone?: (result: AdminRefundResult) => void;
}

const CHANNELS: readonly RefundChannel[] = ['psp_card', 'bnpl_revert', 'manual'];

/**
 * The admin refund tool — always opened **from a ticket** (never a standalone form; every initiate carries
 * the `ticketId`, phase §5). Renders the **server-computed** tiered percentage + fee/payout decomposition
 * (via the shared PriceBreakdown; the client never recomputes the split), a channel selector, the BNPL ETA
 * banner, and the read-only clawback notice when the nurse was already paid. Drives
 * initiate → (provider-revert failure) retry / reject. Money stays IRR digit-strings end to end.
 * @component RefundPanel
 */
const RefundPanel: FunctionComponent<RefundPanelProps> = ({ bookingId, ticketId, onDone }) => {
  const t = useTranslations('admin');
  const locale = useLocale();
  const { enqueueSnackbar } = useSnackbar();

  const preview = useRefundPreview(bookingId, ticketId);
  const initiate = useInitiateRefund();
  const approve = useApproveRefund();
  const reject = useRejectRefund();

  const [channel, setChannel] = useState<RefundChannel | ''>('');
  const [notes, setNotes] = useState('');
  const [result, setResult] = useState<AdminRefundResult | null>(null);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [rejectOpen, setRejectOpen] = useState(false);

  const p = preview.data;
  const effectiveChannel = (channel || p?.refundChannel) as RefundChannel | undefined;
  const busy = initiate.isPending || approve.isPending || reject.isPending;

  const doInitiate = () => {
    if (!p) return;
    initiate.mutate(
      { bookingId, ticketId, refundChannel: effectiveChannel, reasonCategory: 'customer_request', reasonNotes: notes.trim() || undefined },
      {
        onSuccess: (r) => {
          setResult(r);
          setConfirmOpen(false);
          if (r.status === 'succeeded' || r.status === 'processing') {
            enqueueSnackbar(t('refund_done'), { variant: 'success' });
            onDone?.(r);
          }
        },
        onError: () => setConfirmOpen(false),
      },
    );
  };

  const doRetry = () => {
    if (!result) return;
    approve.mutate(result.refundId, {
      onSuccess: (r) => {
        setResult(r);
        if (r.status === 'succeeded' || r.status === 'processing') {
          enqueueSnackbar(t('refund_done'), { variant: 'success' });
          onDone?.(r);
        }
      },
    });
  };

  const doReject = (reason?: string) => {
    if (!result) return;
    reject.mutate(
      { refundId: result.refundId, reason: reason ?? '' },
      {
        onSuccess: () => {
          setRejectOpen(false);
          setResult({ ...result, status: 'rejected' });
        },
      },
    );
  };

  if (preview.isLoading) return <Skeleton variant="rounded" height={260} />;
  if (preview.isError || !p) {
    return (
      <Alert severity="error" variant="outlined">
        {t('error_generic')}
      </Alert>
    );
  }

  const rows: PriceBreakdownRow[] = [
    { key: 'fee', label: t('refund_row_fee'), amountIrr: p.platformFeeRefundedIrr },
    { key: 'payout', label: t('refund_row_payout'), amountIrr: p.nursePayoutRefundedIrr },
  ];
  const activeResult = result;
  const failed = activeResult?.status === 'failed';
  const finalDone = activeResult && (activeResult.status === 'succeeded' || activeResult.status === 'processing' || activeResult.status === 'rejected');
  const pct = formatNumber(p.refundPercentageApplied, locale, { style: 'percent', maximumFractionDigits: 0 });

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
      <Stack direction="row" sx={{ gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
        <Typography variant="subtitle1" sx={{ fontWeight: 800 }}>
          {t('refund_preview_title')}
        </Typography>
        <Chip size="small" variant="outlined" label={t('refund_linked_booking', { id: bookingId })} />
        <Chip size="small" label={`${t('refund_percentage')}: ${pct}`} sx={{ bgcolor: 'var(--bal-primary-soft)', fontWeight: 700 }} />
      </Stack>

      <PriceBreakdown rows={rows} totalLabel={t('refund_row_total')} totalAmountIrr={p.amountIrr} />

      {!activeResult ? (
        <>
          <TextField
            select
            size="small"
            label={t('refund_channel')}
            helperText={t('refund_channel_hint')}
            value={channel || p.refundChannel}
            onChange={(e) => setChannel(e.target.value as RefundChannel)}
            sx={{ maxWidth: 260 }}
          >
            {CHANNELS.map((c) => (
              <MenuItem key={c} value={c}>
                {t(`channel_${c}`)}
              </MenuItem>
            ))}
          </TextField>

          {p.expectedCustomerRefundEta ? (
            <Alert severity="info" variant="outlined" icon={false}>
              {t('refund_eta', { date: formatShamsiDate(p.expectedCustomerRefundEta, locale) })}
              {effectiveChannel === 'bnpl_revert' ? ` — ${t('refund_eta_bnpl')}` : ''}
            </Alert>
          ) : null}

          {p.willCreateClawback ? (
            <Alert severity="warning" variant="outlined">
              {t('refund_clawback_notice')}
            </Alert>
          ) : null}

          <TextField
            size="small"
            label={t('refund_notes_ph')}
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            multiline
            minRows={2}
          />

          <AppButton variant="contained" color="primary" startIcon="refunds" onClick={() => setConfirmOpen(true)} disabled={busy} sx={{ alignSelf: 'flex-start' }}>
            {t('refund_initiate')}
          </AppButton>
        </>
      ) : failed ? (
        <>
          <Alert severity="error" variant="outlined">
            {t('refund_provider_failed')}
          </Alert>
          <Stack direction="row" sx={{ gap: 1 }}>
            <AppButton variant="contained" color="primary" startIcon="refresh" onClick={doRetry} disabled={busy}>
              {t('refund_approve')}
            </AppButton>
            <AppButton variant="outlined" color="error" onClick={() => setRejectOpen(true)} disabled={busy}>
              {t('refund_reject')}
            </AppButton>
          </Stack>
        </>
      ) : finalDone ? (
        <Alert severity={activeResult?.status === 'rejected' ? 'warning' : 'success'} variant="outlined">
          {t(`rstatus_${activeResult!.status}`)}
        </Alert>
      ) : null}

      <ConfirmDialog
        open={confirmOpen}
        title={t('refund_initiate')}
        body={t('refund_confirm', { id: bookingId })}
        confirmLabel={t('refund_initiate')}
        cancelLabel={t('cancel')}
        onConfirm={doInitiate}
        onClose={() => setConfirmOpen(false)}
        loading={initiate.isPending}
      />
      <ConfirmDialog
        open={rejectOpen}
        title={t('refund_reject')}
        confirmLabel={t('refund_reject')}
        cancelLabel={t('cancel')}
        confirmColor="error"
        onConfirm={doReject}
        onClose={() => setRejectOpen(false)}
        loading={reject.isPending}
        requireReason
        reasonLabel={t('reason_label')}
      />
    </Box>
  );
};

export default RefundPanel;
