/* eslint-disable react/no-unstable-nested-components */
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Dialog from '@arcblock/ux/lib/Dialog';
import Toast from '@arcblock/ux/lib/Toast';
import { api, ConfirmDialog, formatError, formatTime, Table, Status, Switch } from '@blocklet/payment-react';
import { DeleteOutlined, EditOutlined } from '@mui/icons-material';
import { Alert, Button, IconButton, Stack, Tooltip, Typography } from '@mui/material';
import { useRequest, useSetState } from 'ahooks';
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';

import EditProviderDialog from './edit-dialog';

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;
  last_success_at: string | null;
  last_failure_at: string | null;
  failure_count: number;
  created_at: string;
  updated_at: string;
}

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

const fetchProviders = (): Promise<{ data: ExchangeRateProvider[] }> => {
  return api.get('/api/exchange-rate-providers').then((res: any) => res.data);
};

const getStatusColor = (status: string) => {
  switch (status) {
    case 'active':
      return 'success';
    case 'degraded':
      return 'warning';
    case 'paused':
      return 'default';
    case 'inactive':
      return 'error';
    default:
      return 'default';
  }
};

export default function ExchangeRateProviders() {
  const { t } = useLocaleContext();
  const [searchParams, setSearchParams] = useSearchParams();
  const [state, setState] = useSetState({
    editingProvider: null as ExchangeRateProvider | null,
    isCreating: false,
    deletingProvider: null as ExchangeRateProvider | null,
    updatingProviderId: null as string | null,
    confirmDisableProvider: null as ExchangeRateProvider | null,
  });

  const { loading, error, data, refresh } = useRequest(fetchProviders);

  const handleEdit = (provider: ExchangeRateProvider) => {
    setState({ editingProvider: provider, isCreating: false });
  };

  const handleCloseEdit = () => {
    setState({ editingProvider: null, isCreating: false });
    if (searchParams.get('create') === '1') {
      const nextParams = new URLSearchParams(searchParams);
      nextParams.delete('create');
      setSearchParams(nextParams);
    }
  };

  const handleSave = async () => {
    await refresh();
    handleCloseEdit();
    Toast.success(t('common.saved'));
    if (searchParams.get('create') === '1') {
      const nextParams = new URLSearchParams(searchParams);
      nextParams.delete('create');
      setSearchParams(nextParams);
    }
  };

  const handleCreate = () => {
    setState({
      editingProvider: {
        id: '',
        name: 'Token Data',
        type: 'token-data',
        enabled: true,
        priority: (data?.data?.length || 0) + 1,
        status: 'active',
        paused_reason: '',
        config: { base_url: '' },
        last_failure_at: null,
        last_success_at: null,
        failure_count: 0,
        created_at: '',
        updated_at: '',
      },
      isCreating: true,
    });
  };

  useEffect(() => {
    const shouldCreate = searchParams.get('create') === '1';
    if (shouldCreate && !state.isCreating && !state.editingProvider) {
      handleCreate();
    }
  }, [searchParams, state.isCreating, state.editingProvider, data?.data]);

  const handleDelete = async () => {
    if (!state.deletingProvider) return;

    try {
      await api.delete(`/api/exchange-rate-providers/${state.deletingProvider.id}`);
      Toast.success(t('common.deleted'));
      await refresh();
      setState({ deletingProvider: null });
    } catch (err) {
      Toast.error(formatError(err));
    }
  };

  const handleToggleEnabled = async (provider: ExchangeRateProvider, enabled: boolean) => {
    setState({ updatingProviderId: provider.id });
    try {
      await api.put(`/api/exchange-rate-providers/${provider.id}`, {
        enabled,
      });
      Toast.success(t('common.saved'));
      await refresh();
    } catch (err) {
      Toast.error(formatError(err));
    } finally {
      setState({ updatingProviderId: null });
    }
  };

  if (error) {
    return <Alert severity="error">{formatError(error)}</Alert>;
  }

  const columns = [
    {
      label: t('admin.exchangeRateProvider.table.name'),
      name: 'name',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          const baseUrl = provider.config?.base_url || DEFAULT_BASE_URLS[provider.type];
          return (
            <Stack direction="column" spacing={0.5}>
              <Typography variant="body2" fontWeight={500}>
                {provider.name}
              </Typography>
              {baseUrl && (
                <Typography variant="caption" color="text.secondary">
                  {baseUrl}
                </Typography>
              )}
            </Stack>
          );
        },
      },
    },
    {
      label: t('admin.exchangeRateProvider.table.participation'),
      name: 'participation',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          const included = provider.enabled && provider.status !== 'paused' && provider.status !== 'inactive';
          return (
            <Status
              label={
                included
                  ? t('admin.exchangeRateProvider.participation.included')
                  : t('admin.exchangeRateProvider.participation.excluded')
              }
              color={included ? 'success' : 'default'}
            />
          );
        },
      },
    },
    {
      label: t('admin.exchangeRateProvider.table.health'),
      name: 'health',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          const healthLabel = t(`admin.exchangeRateProvider.health.${provider.status}`);
          if (provider.paused_reason) {
            return (
              <Tooltip title={provider.paused_reason} arrow>
                <span>
                  <Status label={healthLabel} color={getStatusColor(provider.status)} />
                </span>
              </Tooltip>
            );
          }
          return <Status label={healthLabel} color={getStatusColor(provider.status)} />;
        },
      },
    },
    {
      label: t('admin.exchangeRateProvider.table.recentActivity'),
      name: 'recent_activity',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          const lastUpdateAt = provider.last_success_at || provider.last_failure_at;
          const lastUpdateDisplay = lastUpdateAt ? formatTime(lastUpdateAt) : '-';
          const failureWindowMs = 24 * 60 * 60 * 1000;
          const failureCount24h =
            provider.last_failure_at && Date.now() - new Date(provider.last_failure_at).getTime() <= failureWindowMs
              ? provider.failure_count
              : 0;
          return (
            <Stack direction="column" spacing={0.25}>
              <Typography variant="caption" color="text.secondary">
                {t('admin.exchangeRateProvider.table.lastUpdate', { time: lastUpdateDisplay })}
              </Typography>
              <Typography variant="caption" color="text.secondary">
                {t('admin.exchangeRateProvider.table.failures24h', {
                  count: failureCount24h,
                })}
              </Typography>
            </Stack>
          );
        },
      },
    },
    {
      label: t('admin.exchangeRateProvider.table.enabled'),
      name: 'enabled',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          return (
            <Switch
              checked={provider.enabled}
              onChange={(e) => {
                const nextEnabled = e.target.checked;
                if (!nextEnabled) {
                  setState({ confirmDisableProvider: provider });
                  return;
                }
                handleToggleEnabled(provider, nextEnabled);
              }}
              disabled={state.updatingProviderId === provider.id}
              size="small"
            />
          );
        },
      },
    },
    {
      label: t('common.actions'),
      name: 'id',
      options: {
        customBodyRenderLite: (_: string, index: number) => {
          const provider = data?.data?.[index];
          if (!provider) return null;
          return (
            <Stack direction="row" spacing={0.5}>
              <IconButton size="small" onClick={() => handleEdit(provider)}>
                <EditOutlined fontSize="small" />
              </IconButton>
              <IconButton size="small" onClick={() => setState({ deletingProvider: provider })} color="error">
                <DeleteOutlined fontSize="small" />
              </IconButton>
            </Stack>
          );
        },
      },
    },
  ];

  return (
    <>
      <Typography variant="subtitle1" sx={{ color: 'text.secondary', whiteSpace: 'break-spaces', mt: 3, mb: 2 }}>
        {t('admin.exchangeRateProvider.medianStrategyNote')}
      </Typography>
      <Table
        data={data?.data || []}
        columns={columns}
        loading={loading}
        toolbar={false}
        footer={false}
        options={{
          count: data?.data?.length || 0,
          page: 0,
          rowsPerPage: 100,
        }}
        emptyNodeText={t('common.noData')}
      />
      {state.confirmDisableProvider && (
        <ConfirmDialog
          title={t('admin.exchangeRateProvider.disableConfirmTitle')}
          message={t('admin.exchangeRateProvider.disableConfirmMessage')}
          onConfirm={() => {
            const provider = state.confirmDisableProvider as ExchangeRateProvider;
            setState({ confirmDisableProvider: null });
            handleToggleEnabled(provider, false);
          }}
          onCancel={() => setState({ confirmDisableProvider: null })}
        />
      )}

      {state.editingProvider && (
        <EditProviderDialog
          provider={state.editingProvider}
          isCreate={state.isCreating}
          open={!!state.editingProvider}
          onClose={handleCloseEdit}
          onSave={handleSave}
        />
      )}

      {state.deletingProvider && (
        <Dialog
          open={!!state.deletingProvider}
          onClose={() => setState({ deletingProvider: null })}
          maxWidth="sm"
          title={t('admin.exchangeRateProvider.delete.title')}
          PaperProps={{
            sx: {
              borderRadius: 2,
            },
          }}
          actions={
            <Stack direction="row" spacing={2}>
              <Button variant="outlined" onClick={() => setState({ deletingProvider: null })}>
                {t('common.cancel')}
              </Button>
              <Button variant="contained" color="error" onClick={handleDelete}>
                {t('common.delete')}
              </Button>
            </Stack>
          }>
          <Typography>
            {t('admin.exchangeRateProvider.delete.confirm', { name: state.deletingProvider.name })}
          </Typography>
        </Dialog>
      )}
    </>
  );
}
