import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Dialog from '@arcblock/ux/lib/Dialog';
import Toast from '@arcblock/ux/lib/Toast';
import { api, formatError } from '@blocklet/payment-react';
import {
  Alert,
  Button,
  CircularProgress,
  FormControl,
  FormHelperText,
  InputLabel,
  Link,
  MenuItem,
  Select,
  Stack,
  TextField,
  Typography,
} from '@mui/material';
import { useSetState } from 'ahooks';
import { useEffect } from 'react';

interface ExchangeRateProvider {
  id: string;
  name: string;
  type: 'token-data' | 'coingecko' | 'coinmarketcap';
  enabled: boolean;
  priority: number;
  status: 'active' | 'degraded' | 'paused' | 'inactive';
  paused_reason: string | null;
  config: Record<string, any> | null;
}

interface EditProviderDialogProps {
  provider: ExchangeRateProvider;
  isCreate?: boolean;
  open: boolean;
  onClose: () => void;
  onSave: () => void;
}

const BASE_URL_PLACEHOLDERS = {
  'token-data': 'https://token-data.arcblock.io',
  coingecko: 'https://api.coingecko.com/api/v3',
  coinmarketcap: 'https://pro-api.coinmarketcap.com/v1',
};

const API_KEY_PLACEHOLDERS = {
  coinmarketcap: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
  coingecko: 'CG-xxxxxxxxxxxxxxxxxxxxxxxx',
};

const TYPE_NAME_DEFAULTS: Record<ExchangeRateProvider['type'], string> = {
  'token-data': 'Token Data',
  coingecko: 'CoinGecko',
  coinmarketcap: 'CoinMarketCap',
};

export default function EditProviderDialog({
  provider,
  isCreate = false,
  open,
  onClose,
  onSave,
}: EditProviderDialogProps) {
  const { t } = useLocaleContext();
  const [state, setState] = useSetState({
    name: provider.name || '',
    type: provider.type || 'token-data',
    base_url: provider.config?.base_url || '',
    api_key: provider.config?.api_key || '',
    priority: provider.priority,
    status: provider.status,
    paused_reason: provider.paused_reason || '',
    loading: false,
    error: null as string | null,
    testing: false,
    testResult: null as {
      success: boolean;
      responseTime?: number;
      error?: string;
      rate?: string;
      timestamp?: number;
      symbol?: string;
    } | null,
    apiKeyTouched: false,
  });

  useEffect(() => {
    setState({
      name: provider.name || '',
      type: provider.type || 'token-data',
      base_url: provider.config?.base_url || '',
      api_key: provider.config?.api_key || '',
      priority: provider.priority,
      status: provider.status,
      paused_reason: provider.paused_reason || '',
      error: null,
      apiKeyTouched: false,
    });
  }, [provider, open]);

  const handleSave = async () => {
    if (isCreate && !state.name.trim()) {
      setState({ error: t('admin.exchangeRateProvider.edit.nameRequired') });
      return;
    }

    try {
      setState({ loading: true, error: null });

      const updates: any = {
        name: state.name.trim(),
        type: state.type,
        priority: state.priority,
        status: state.status,
        config: {
          ...(state.base_url && { base_url: state.base_url }),
        },
      };
      if (isCreate || state.apiKeyTouched) {
        updates.config.api_key = state.api_key;
      }

      if (state.status === 'paused' && state.paused_reason) {
        updates.paused_reason = state.paused_reason;
      } else if (state.status !== 'paused') {
        updates.paused_reason = null;
      }

      if (isCreate) {
        await api.post('/api/exchange-rate-providers', updates);
      } else {
        await api.put(`/api/exchange-rate-providers/${provider.id}`, updates);
      }
      onSave();
    } catch (err) {
      setState({ error: formatError(err) });
      Toast.error(formatError(err));
    } finally {
      setState({ loading: false });
    }
  };

  const handleCancel = () => {
    setState({
      name: provider.name || '',
      type: provider.type || 'token-data',
      base_url: provider.config?.base_url || '',
      api_key: provider.config?.api_key || '',
      priority: provider.priority,
      status: provider.status,
      paused_reason: provider.paused_reason || '',
      error: null,
      testing: false,
      testResult: null,
      apiKeyTouched: false,
    });
    onClose();
  };

  const handleTestConnection = async () => {
    setState({ testing: true, testResult: null });

    try {
      const response = await api.post('/api/exchange-rate-providers/test-connection', {
        type: state.type,
        provider_id: isCreate ? undefined : provider.id,
        config: {
          ...(state.base_url && { base_url: state.base_url }),
          ...(state.apiKeyTouched && { api_key: state.api_key }),
        },
      });

      setState({ testResult: response.data });
    } catch (err) {
      setState({
        testResult: {
          success: false,
          error: formatError(err),
        },
      });
    } finally {
      setState({ testing: false });
    }
  };

  return (
    <Dialog
      open={open}
      onClose={handleCancel}
      maxWidth="sm"
      fullWidth
      title={
        isCreate
          ? t('admin.exchangeRateProvider.create.title')
          : t('admin.exchangeRateProvider.edit.title', { name: provider.name })
      }
      PaperProps={{
        sx: {
          borderRadius: 2,
        },
      }}
      actions={
        <Stack direction="row" spacing={2}>
          <Button variant="outlined" onClick={handleCancel} disabled={state.loading}>
            {t('common.cancel')}
          </Button>
          <Button variant="contained" onClick={handleSave} disabled={state.loading}>
            {state.loading ? t('common.saving') : t('common.save')}
          </Button>
        </Stack>
      }>
      <Stack spacing={3}>
        {state.error && (
          <Alert severity="error" onClose={() => setState({ error: null })}>
            {state.error}
          </Alert>
        )}

        <TextField
          label={t('admin.exchangeRateProvider.edit.name')}
          value={state.name}
          onChange={(e) => setState({ name: e.target.value })}
          helperText={t('admin.exchangeRateProvider.edit.nameHelp')}
          fullWidth
          required
          disabled={false}
        />

        <FormControl fullWidth required>
          <InputLabel>{t('admin.exchangeRateProvider.edit.type')}</InputLabel>
          <Select
            value={state.type}
            label={t('admin.exchangeRateProvider.edit.type')}
            onChange={(e) => {
              const nextType = e.target.value as ExchangeRateProvider['type'];
              setState((prev) => {
                const shouldDefaultName = isCreate && (!prev.name || prev.name === TYPE_NAME_DEFAULTS[prev.type]);
                return {
                  type: nextType,
                  name: shouldDefaultName ? TYPE_NAME_DEFAULTS[nextType] : prev.name,
                };
              });
            }}
            disabled={!isCreate}>
            <MenuItem value="token-data">Token Data (ArcBlock)</MenuItem>
            <MenuItem value="coingecko">CoinGecko</MenuItem>
            <MenuItem value="coinmarketcap">CoinMarketCap</MenuItem>
          </Select>
          <FormHelperText>{t('admin.exchangeRateProvider.edit.typeHelp')}</FormHelperText>
        </FormControl>

        <TextField
          label={t('admin.exchangeRateProvider.edit.baseUrl')}
          value={state.base_url}
          onChange={(e) => setState({ base_url: e.target.value })}
          helperText={t('admin.exchangeRateProvider.edit.baseUrlHelp', {
            defaultUrl: BASE_URL_PLACEHOLDERS[state.type] || '',
          })}
          placeholder={BASE_URL_PLACEHOLDERS[state.type] || ''}
          fullWidth
        />

        {state.type === 'coinmarketcap' && (
          <Stack spacing={1}>
            <TextField
              label={t('admin.exchangeRateProvider.edit.apiKey')}
              value={state.api_key}
              onChange={(e) => setState({ api_key: e.target.value, apiKeyTouched: true })}
              helperText={t('admin.exchangeRateProvider.edit.apiKeyHelp')}
              placeholder={API_KEY_PLACEHOLDERS[state.type] || ''}
              type="password"
              fullWidth
            />
            <Typography variant="caption" color="text.secondary">
              {t('admin.exchangeRateProvider.edit.apiKeyLinkText')}{' '}
              <Link href="https://pro.coinmarketcap.com/account" target="_blank" rel="noreferrer">
                {t('admin.exchangeRateProvider.edit.apiKeyLinkAction')}
              </Link>
            </Typography>
          </Stack>
        )}

        <Stack direction="row" spacing={2} alignItems="flex-start">
          <Button
            variant="outlined"
            onClick={handleTestConnection}
            disabled={state.testing}
            startIcon={state.testing ? <CircularProgress size={16} /> : undefined}>
            {state.testing
              ? t('admin.exchangeRateProvider.edit.testing')
              : t('admin.exchangeRateProvider.edit.testConnection')}
          </Button>
        </Stack>

        {state.testResult && (
          <Alert
            severity={state.testResult.success ? 'success' : 'error'}
            onClose={() => setState({ testResult: null })}>
            {state.testResult.success
              ? t('admin.exchangeRateProvider.edit.testSuccess', {
                  time: state.testResult.responseTime,
                  rate: state.testResult.rate,
                  symbol: state.testResult.symbol,
                  timestamp: state.testResult.timestamp,
                })
              : t('admin.exchangeRateProvider.edit.testFailed', {
                  error: state.testResult.error,
                })}
          </Alert>
        )}

        <TextField
          label={t('admin.exchangeRateProvider.edit.priority')}
          type="number"
          value={state.priority}
          onChange={(e) => {
            const value = parseInt(e.target.value, 10);
            setState({ priority: Number.isNaN(value) ? 1 : Math.max(1, value) });
          }}
          helperText={t('admin.exchangeRateProvider.edit.priorityHelp')}
          fullWidth
          inputProps={{ min: 1 }}
        />

        <FormControl fullWidth>
          <InputLabel>{t('admin.exchangeRateProvider.edit.status')}</InputLabel>
          <Select
            value={state.status}
            label={t('admin.exchangeRateProvider.edit.status')}
            onChange={(e) => setState({ status: e.target.value as any })}>
            <MenuItem value="active">{t('admin.exchangeRateProvider.status.active')}</MenuItem>
            <MenuItem value="degraded">{t('admin.exchangeRateProvider.status.degraded')}</MenuItem>
            <MenuItem value="paused">{t('admin.exchangeRateProvider.status.paused')}</MenuItem>
            <MenuItem value="inactive">{t('admin.exchangeRateProvider.status.inactive')}</MenuItem>
          </Select>
          <FormHelperText>{t('admin.exchangeRateProvider.edit.statusHelp')}</FormHelperText>
        </FormControl>

        {state.status === 'paused' && (
          <TextField
            label={t('admin.exchangeRateProvider.edit.pausedReason')}
            value={state.paused_reason}
            onChange={(e) => setState({ paused_reason: e.target.value })}
            multiline
            rows={3}
            fullWidth
            helperText={t('admin.exchangeRateProvider.edit.pausedReasonHelp')}
          />
        )}
      </Stack>
    </Dialog>
  );
}
