import { useState, useMemo, useEffect } from 'react';
import { Box, Stack, Typography, TextField, ToggleButton, ToggleButtonGroup, Button } from '@mui/material';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';

export type SlippageConfigValue = {
  mode: 'percent' | 'rate';
  percent: number;
  min_acceptable_rate?: string;
  base_currency?: string;
  updated_at_ms?: number;
};

export interface SlippageConfigProps {
  value: number;
  onChange: (value: number) => void;
  config?: SlippageConfigValue;
  onConfigChange?: (value: SlippageConfigValue) => void;
  exchangeRate?: string | null;
  baseCurrency?: string;
  disabled?: boolean;
  sx?: any;
  onCancel?: () => void;
  onSave?: () => void;
}

const PRESET_SLIPPAGE = [0.5, 1, 3, 5, 10];

export default function SlippageConfig({
  value,
  onChange,
  config = undefined,
  onConfigChange = undefined,
  exchangeRate = null,
  baseCurrency = 'USD',
  disabled = false,
  sx = {},
  onCancel = undefined,
  onSave = undefined,
}: SlippageConfigProps) {
  const { t } = useLocaleContext();
  const [inputValue, setInputValue] = useState('');
  const [inputMode, setInputMode] = useState<'percent' | 'rate'>(config?.mode || 'percent');
  const [error, setError] = useState<string | null>(null);
  const [isEditing, setIsEditing] = useState(false); // Track if user is actively editing input
  const percentValue = config?.percent ?? value;

  // Round exchange rate to 2 decimal places for simpler display and calculation
  const roundedRate = useMemo(() => {
    if (!exchangeRate) return null;
    const rateNum = Number(exchangeRate);
    if (Number.isNaN(rateNum) || rateNum <= 0) return null;
    return Math.round(rateNum * 100) / 100;
  }, [exchangeRate]);

  // Compute min rate from percent using rounded rate
  const computeMinRateFromPercent = (percent: number) => {
    if (!roundedRate) return '';
    const slippageMultiplier = 1 + percent / 100;
    return (roundedRate / slippageMultiplier).toFixed(2);
  };

  // Sync mode from config
  useEffect(() => {
    if (config?.mode && config.mode !== inputMode) {
      setInputMode(config.mode);
    }
  }, [config?.mode, inputMode]);

  // Sync input value based on mode - skip when user is actively editing
  useEffect(() => {
    // Skip sync when user is typing to prevent overwriting their input
    if (isEditing) {
      return;
    }

    if (inputMode === 'percent') {
      setInputValue(percentValue.toFixed(2));
      return;
    }

    if (config?.min_acceptable_rate) {
      setInputValue(String(config.min_acceptable_rate));
      return;
    }

    const minRate = computeMinRateFromPercent(percentValue);
    setInputValue(minRate);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [percentValue, inputMode, exchangeRate, config?.min_acceptable_rate, isEditing]);

  const handlePresetClick = (preset: number) => {
    if (disabled) return;
    setInputValue(preset.toFixed(2));
    setInputMode('percent');
    setError(null);
    onChange(preset);
    // Always pass min_acceptable_rate so backend saves the exact value user sees
    const minRate = computeMinRateFromPercent(preset);
    onConfigChange?.({
      mode: 'percent',
      percent: preset,
      ...(minRate ? { min_acceptable_rate: minRate } : {}),
    });
  };

  const handleInputChange = (newValue: string) => {
    setInputValue(newValue);
    setError(null);

    const numValue = Number(newValue);
    if (!newValue || Number.isNaN(numValue)) {
      setError(t('payment.checkout.quote.slippage.invalid'));
      return;
    }

    if (numValue <= 0) {
      setError(t('payment.checkout.quote.slippage.invalidPositive'));
      return;
    }

    if (inputMode === 'percent') {
      onChange(numValue);
      // Always pass min_acceptable_rate so backend saves the exact value user sees
      const minRate = computeMinRateFromPercent(numValue);
      onConfigChange?.({
        mode: 'percent',
        percent: numValue,
        ...(minRate ? { min_acceptable_rate: minRate } : {}),
      });
    } else {
      // Rate mode: compute equivalent percent from input rate using rounded rate
      if (!roundedRate) {
        setError(t('payment.checkout.quote.slippage.rateRequired'));
        return;
      }
      // No range restriction - accept any positive rate
      const percent = ((roundedRate - numValue) / numValue) * 100;
      onChange(Math.max(0, percent));
      onConfigChange?.({ mode: 'rate', percent: Math.max(0, percent), min_acceptable_rate: newValue });
    }
  };

  const handleModeChange = (_: any, newMode: 'percent' | 'rate' | null) => {
    if (disabled || !newMode) return;
    setInputMode(newMode);
    setError(null);

    if (newMode === 'rate') {
      if (!roundedRate) {
        setError(t('payment.checkout.quote.slippage.rateRequired'));
        return;
      }
      const minRate = config?.min_acceptable_rate || computeMinRateFromPercent(percentValue);
      setInputValue(minRate);
      onConfigChange?.({
        mode: 'rate',
        percent: percentValue,
        min_acceptable_rate: minRate,
      });
    } else {
      setInputValue(percentValue.toFixed(2));
      // Always pass min_acceptable_rate so backend saves the exact value user sees
      const minRate = computeMinRateFromPercent(percentValue);
      onConfigChange?.({
        mode: 'percent',
        percent: percentValue,
        ...(minRate ? { min_acceptable_rate: minRate } : {}),
      });
    }
  };

  const minAcceptableRate = useMemo(() => {
    if (!roundedRate) return null;
    const slippageMultiplier = 1 + percentValue / 100;
    return (roundedRate / slippageMultiplier).toFixed(2);
  }, [roundedRate, percentValue]);

  const currentRateLabel = useMemo(() => {
    if (!roundedRate) {
      return '—';
    }
    return roundedRate.toFixed(2);
  }, [roundedRate]);

  const handleCancel = () => {
    onCancel?.();
  };

  const handleSave = () => {
    onSave?.();
  };

  return (
    <Stack spacing={2.5} sx={sx}>
      {/* Description */}
      <Typography variant="body2" color="text.secondary">
        {t('payment.checkout.quote.slippageLimit.description')}
      </Typography>

      {/* Mode toggle */}
      <ToggleButtonGroup
        value={inputMode}
        exclusive
        onChange={handleModeChange}
        size="small"
        fullWidth
        disabled={disabled}>
        <ToggleButton value="percent">{t('payment.checkout.quote.slippageLimit.configTogglePercent')}</ToggleButton>
        <ToggleButton value="rate" disabled={!roundedRate}>
          {t('payment.checkout.quote.slippageLimit.configToggleRate')}
        </ToggleButton>
      </ToggleButtonGroup>

      {/* Percent mode */}
      {inputMode === 'percent' && (
        <Stack spacing={1.5}>
          <Stack direction="row" spacing={1}>
            {PRESET_SLIPPAGE.map((preset) => (
              <ToggleButton
                key={preset}
                value={preset}
                selected={Math.abs(percentValue - preset) < 0.01}
                onClick={() => handlePresetClick(preset)}
                size="small"
                disabled={disabled}
                sx={{
                  flex: 1,
                  py: 1,
                  borderRadius: 1,
                  border: '1px solid',
                  borderColor: 'divider',
                  '&.Mui-selected': {
                    bgcolor: 'primary.main',
                    color: 'primary.contrastText',
                    borderColor: 'primary.main',
                    '&:hover': {
                      bgcolor: 'primary.dark',
                    },
                  },
                }}>
                <Typography variant="body2">{preset}%</Typography>
              </ToggleButton>
            ))}
          </Stack>

          {/* Custom input */}
          <TextField
            size="small"
            fullWidth
            value={inputValue}
            onChange={(e) => handleInputChange(e.target.value)}
            onFocus={() => setIsEditing(true)}
            onBlur={() => setIsEditing(false)}
            error={!!error}
            helperText={error}
            disabled={disabled}
            label={t('common.custom')}
            InputProps={{
              endAdornment: (
                <Typography variant="body2" sx={{ color: 'text.secondary', mr: 1 }}>
                  %
                </Typography>
              ),
            }}
            placeholder="0.50"
          />
        </Stack>
      )}

      {/* Rate mode */}
      {inputMode === 'rate' && (
        <Stack spacing={1.5}>
          <TextField
            size="small"
            fullWidth
            value={inputValue}
            onChange={(e) => handleInputChange(e.target.value)}
            onFocus={() => setIsEditing(true)}
            onBlur={() => setIsEditing(false)}
            error={!!error}
            helperText={error}
            disabled={disabled || !roundedRate}
            label={t('payment.checkout.quote.slippage.rateInputLabel', { currency: baseCurrency })}
            InputProps={{
              endAdornment: (
                <Typography variant="body2" sx={{ color: 'text.secondary', mr: 1 }}>
                  {baseCurrency}
                </Typography>
              ),
            }}
            placeholder={roundedRate?.toFixed(2) || '0.00'}
          />
        </Stack>
      )}

      {/* Rate info - only show when exchange rate is available */}
      {roundedRate && (
        <Box
          sx={{
            borderRadius: 1,
            p: 1.5,
            bgcolor: 'action.hover',
          }}>
          <Stack spacing={0.5}>
            <Stack direction="row" justifyContent="space-between" alignItems="center">
              <Typography variant="body2" color="text.secondary">
                {t('payment.checkout.quote.slippageLimit.derivedCurrentRate')}
              </Typography>
              <Typography variant="body2" fontWeight={500}>
                {currentRateLabel} {baseCurrency}
              </Typography>
            </Stack>
            <Stack direction="row" justifyContent="space-between" alignItems="center">
              <Typography variant="body2" color="text.secondary">
                {t('payment.checkout.quote.slippageLimit.derivedMinRate')}
              </Typography>
              <Typography variant="body2" fontWeight={500} color="primary.main">
                {inputMode === 'rate' ? inputValue : minAcceptableRate || '—'} {baseCurrency}
              </Typography>
            </Stack>
          </Stack>
        </Box>
      )}

      {/* Actions */}
      <Stack direction="row" spacing={1} justifyContent="flex-end">
        <Button onClick={handleCancel} disabled={disabled} color="inherit">
          {t('common.cancel')}
        </Button>
        <Button variant="contained" onClick={handleSave} disabled={disabled || !!error}>
          {t('common.save')}
        </Button>
      </Stack>
    </Stack>
  );
}
