import { useEffect, useState } from 'react';
import TuneIcon from '@mui/icons-material/Tune';
import { Box, Dialog, DialogContent, DialogTitle, Fade, Stack, Tooltip, Typography, keyframes } from '@mui/material';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import SlippageConfig from '../../../components/slippage-config';
import { whiteTooltipSx } from '../../utils/format';

const ping = keyframes`
  75%, 100% { transform: scale(2); opacity: 0; }
`;

function formatDateTime(ts: number | null): string {
  if (!ts) return '—';
  const d = new Date(ts);
  const pad = (n: number) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

interface ExchangeRateFooterProps {
  hasDynamicPricing: boolean;
  rate: {
    value: string | null;
    display: string | null;
    provider: string | null;
    providerDisplay: string | null;
    fetchedAt: number | null;
    status: 'loading' | 'available' | 'unavailable';
  };
  slippage: {
    percent: number;
    set: (config: { mode: string; percent: number; base_currency?: string }) => Promise<void>;
  };
  currencySymbol: string;
  isSubscription: boolean;
}

export default function ExchangeRateFooter({
  hasDynamicPricing,
  rate,
  slippage,
  currencySymbol,
  isSubscription,
}: ExchangeRateFooterProps) {
  const { t } = useLocaleContext();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [pendingConfig, setPendingConfig] = useState<{ mode: 'percent' | 'rate'; percent: number } | null>(null);
  const [submitting, setSubmitting] = useState(false);

  // Optimistic local slippage — sync from prop, update immediately on save
  const [localSlippage, setLocalSlippage] = useState(slippage?.percent ?? 0.5);
  useEffect(() => {
    setLocalSlippage(slippage?.percent ?? 0.5);
  }, [slippage?.percent]);

  if (!hasDynamicPricing || !rate.value || rate.status === 'unavailable') return null;

  // Use pre-formatted display (e.g. "$0.19") — no redundant "USD" suffix
  const rateDisplay = rate.display || `$${Number(rate.value).toFixed(2)}`;
  const showSlippage = isSubscription && typeof slippage?.set === 'function';

  const handleOpenDialog = () => {
    setPendingConfig({ mode: 'percent', percent: localSlippage });
    setDialogOpen(true);
  };

  const handleCloseDialog = () => {
    setDialogOpen(false);
    setPendingConfig(null);
  };

  const handleSlippageChange = (value: number) => {
    setPendingConfig((prev) => (prev ? { ...prev, percent: value } : { mode: 'percent' as const, percent: value }));
  };

  const handleConfigChange = (config: { mode: 'percent' | 'rate'; percent: number }) => {
    setPendingConfig(config);
  };

  const handleSubmit = async () => {
    if (!pendingConfig || !slippage?.set) return;
    setSubmitting(true);
    try {
      // Optimistic update — show new value immediately
      setLocalSlippage(pendingConfig.percent);
      await slippage.set({ ...pendingConfig, base_currency: 'USD' });
      setDialogOpen(false);
      setPendingConfig(null);
    } catch (err) {
      // Revert on error
      setLocalSlippage(slippage?.percent ?? 0.5);
      console.error('Failed to update slippage', err);
    } finally {
      setSubmitting(false);
    }
  };

  const labelSx = {
    fontSize: 11,
    fontWeight: 700,
    color: 'primary.main',
    letterSpacing: '0.02em',
  };

  // Hover tooltip content: full rate + provider + update time
  const providerName = rate.providerDisplay || rate.provider || '—';
  const updatedAt = formatDateTime(rate.fetchedAt);
  const fullRate = `$${rate.value}`;

  const tooltipSx = whiteTooltipSx;

  const rowSx = { fontSize: 12, color: 'text.secondary', lineHeight: 1.4 };
  const valSx = { fontSize: 12, fontWeight: 600, color: 'text.primary', lineHeight: 1.4 };

  const tooltipContent = (
    <Stack spacing={0.75}>
      {/* Full precision rate */}
      <Typography sx={{ fontSize: 13, fontWeight: 700, color: 'text.primary', mb: 0.25 }}>
        1 {currencySymbol} = {fullRate}
      </Typography>
      <Box sx={{ borderTop: '1px solid', borderColor: 'divider', pt: 0.75 }}>
        <Stack spacing={0.5}>
          <Stack direction="row" justifyContent="space-between" spacing={2}>
            <Typography sx={rowSx}>{t('payment.checkout.quote.detailProvider')}</Typography>
            <Typography sx={valSx}>{providerName}</Typography>
          </Stack>
          <Stack direction="row" justifyContent="space-between" spacing={2}>
            <Typography sx={rowSx}>{t('payment.checkout.quote.detailUpdatedAt')}</Typography>
            <Typography sx={valSx}>{updatedAt}</Typography>
          </Stack>
        </Stack>
      </Box>
    </Stack>
  );

  // Slippage tooltip
  const slippageTooltip = t('payment.checkout.quote.slippage.tooltip');

  return (
    <>
      <Box sx={{ width: '100%', pt: 3, pb: 1, borderTop: '1px solid', borderColor: 'divider' }}>
        <Fade in timeout={300}>
          <Stack direction="row" sx={{ alignItems: 'center', justifyContent: 'space-between' }}>
            {/* Rate with hover tooltip showing full rate + provider + update time */}
            <Tooltip title={tooltipContent} placement="top" arrow slotProps={{ popper: { sx: tooltipSx } }}>
              <Stack direction="row" alignItems="center" spacing={1} sx={{ cursor: 'default' }}>
                {/* Ping dot */}
                <Box sx={{ position: 'relative', width: 8, height: 8, flexShrink: 0 }}>
                  <Box
                    sx={{
                      position: 'absolute',
                      inset: 0,
                      borderRadius: '50%',
                      bgcolor: '#60a5fa',
                      opacity: 0.6,
                      animation: `${ping} 1s cubic-bezier(0, 0, 0.2, 1) infinite`,
                    }}
                  />
                  <Box
                    sx={{
                      position: 'relative',
                      width: 8,
                      height: 8,
                      borderRadius: '50%',
                      bgcolor: 'primary.main',
                    }}
                  />
                </Box>
                <Typography sx={labelSx}>
                  1 {currencySymbol} ≈ {rateDisplay}
                </Typography>
              </Stack>
            </Tooltip>

            {/* Slippage with tooltip + click to configure */}
            {showSlippage && (
              <Tooltip title={slippageTooltip} placement="top" arrow slotProps={{ popper: { sx: whiteTooltipSx } }}>
                <Stack
                  direction="row"
                  alignItems="center"
                  spacing={0.75}
                  onClick={handleOpenDialog}
                  sx={{
                    cursor: 'pointer',
                    '&:hover': { opacity: 1 },
                    '&:hover .tune-icon': { transform: 'rotate(90deg)' },
                    transition: 'opacity 0.2s',
                  }}>
                  <TuneIcon
                    className="tune-icon"
                    sx={{ fontSize: 16, color: 'primary.main', transition: 'transform 0.5s' }}
                  />
                  <Typography sx={labelSx}>
                    {t('payment.checkout.quote.detailSlippage')} {localSlippage}%
                  </Typography>
                </Stack>
              </Tooltip>
            )}
          </Stack>
        </Fade>
      </Box>

      <Dialog open={dialogOpen} onClose={handleCloseDialog} maxWidth="sm" fullWidth>
        <DialogTitle>{t('payment.checkout.quote.slippage.title')}</DialogTitle>
        <DialogContent>
          <SlippageConfig
            value={pendingConfig?.percent ?? localSlippage}
            onChange={handleSlippageChange}
            config={pendingConfig || { mode: 'percent' as const, percent: localSlippage }}
            onConfigChange={handleConfigChange}
            exchangeRate={rate.value ? String(rate.value) : null}
            baseCurrency="USD"
            disabled={submitting}
            sx={{ mt: 1 }}
            onCancel={handleCloseDialog}
            onSave={handleSubmit}
          />
        </DialogContent>
      </Dialog>
    </>
  );
}
