import React, { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import Toast from '@arcblock/ux/lib/Toast';
import {
  Box,
  Typography,
  TextField,
  Button,
  CircularProgress,
  Alert,
  Stack,
  Divider,
  Card,
  CardActionArea,
  Grid,
  Avatar,
} from '@mui/material';
import { styled } from '@mui/system';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import {
  usePaymentContext,
  getPrefix,
  formatError,
  formatAmountPrecisionLimit,
  api,
  formatBNStr,
  formatPrice,
  formatNumber,
  getTokenBalanceLink,
} from '@blocklet/payment-react';
import type { TPaymentCurrency, TPaymentMethod } from '@blocklet/payment-types';
import { joinURL } from 'ufo';
import { AccountBalanceWalletOutlined, ArrowBackOutlined, ArrowForwardOutlined } from '@mui/icons-material';
import Empty from '@arcblock/ux/lib/Empty';
import { BN, fromUnitToToken } from '@ocap/util';
import RechargeList from '../../../components/invoice/recharge';
import { goBackOrFallback, MAX_SAFE_AMOUNT } from '../../../libs/util';
import { useSessionContext } from '../../../contexts/session';
import { formatSmartDuration, TimeUnit } from '../../../libs/dayjs';
import { useArcsphere } from '../../../hooks/browser';

// 扩展PaymentCurrency类型以包含paymentMethod
interface ExtendedPaymentCurrency extends TPaymentCurrency {
  paymentMethod?: TPaymentMethod;
}

interface Subscription {
  id: string;
  description?: string;
  status: string;
  paymentMethod?: {
    logo?: string;
    name?: string;
  };
  paymentCurrency?: {
    symbol: string;
    decimal: number;
  };
  items?: Array<{
    price: any;
  }>;
}

const Root = styled(Stack)(({ theme }) => ({
  marginBottom: theme.spacing(3),
  gap: theme.spacing(3),
  flexDirection: 'column',
}));

const BalanceCard = styled(Card)(({ theme }) => ({
  padding: theme.spacing(2),
  backgroundColor: theme.palette.background.paper,
  border: `1px solid ${theme.palette.divider}`,
  borderRadius: theme.shape.borderRadius,
  marginBottom: theme.spacing(2),
}));

export default function BalanceRechargePage() {
  const { t, locale } = useLocaleContext();
  const { currencyId } = useParams<{ currencyId: string }>();
  const [searchParams] = useSearchParams();
  const inArcsphere = useArcsphere();
  const rechargeAddress = searchParams.get('rechargeAddress');
  const navigate = useNavigate();
  const { connect } = usePaymentContext();
  const [amount, setAmount] = useState('50');
  const [amountError, setAmountError] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const customInputRef = useRef<HTMLInputElement>(null);
  const [unitCycle, setUnitCycle] = useState<{
    amount: string;
    interval: TimeUnit;
    cycle: number;
  }>({
    amount: '0',
    interval: 'month',
    cycle: 1,
  });
  const [payerValue, setPayerValue] = useState<{
    paymentAddress: string;
    token: string;
  } | null>(null);
  const [customAmount, setCustomAmount] = useState(false);
  const [presetAmounts, setPresetAmounts] = useState<Array<{ amount: string; multiplier: number; label: string }>>([]);
  const { session } = useSessionContext();
  const [currency, setCurrency] = useState<ExtendedPaymentCurrency | null>(null);
  const [relatedSubscriptions, setRelatedSubscriptions] = useState<Subscription[]>([]);

  const paymentAddress = rechargeAddress || payerValue?.paymentAddress || session?.user?.did;

  const fetchData = async () => {
    try {
      setLoading(true);
      if (!currencyId) {
        // 如果没有 currencyId，重定向回客户页面
        navigate('/customer');
        return;
      }

      const { data } = await api.get(`/api/customers/recharge?currencyId=${currencyId}`);

      if (data.currency) {
        setCurrency(data.currency);
        setRelatedSubscriptions(data.relatedSubscriptions || []);

        if (data.recommendedRecharge && data.recommendedRecharge.amount && data.recommendedRecharge.amount !== '0') {
          const baseAmount = data.recommendedRecharge.amount;
          const decimal = data.currency.decimal || 0;
          const calcCycleAmount = (cycle: number) => {
            const cycleAmount = fromUnitToToken(new BN(baseAmount).mul(new BN(String(cycle))).toString(), decimal);
            return Math.ceil(parseFloat(cycleAmount)).toString();
          };
          setUnitCycle({
            amount: fromUnitToToken(baseAmount, decimal),
            interval: data.recommendedRecharge.interval as TimeUnit,
            cycle: data.recommendedRecharge.cycle,
          });

          const newPresetAmounts = [
            {
              amount: calcCycleAmount(1),
              multiplier: data.recommendedRecharge.cycle,
              label: t('common.estimatedDuration', {
                duration: formatSmartDuration(1, data.recommendedRecharge.interval as TimeUnit, {
                  t,
                }),
              }),
            },
            {
              amount: calcCycleAmount(4),
              multiplier: data.recommendedRecharge.cycle * 4,
              label: t('common.estimatedDuration', {
                duration: formatSmartDuration(4, data.recommendedRecharge.interval as TimeUnit, {
                  t,
                }),
              }),
            },
            {
              amount: calcCycleAmount(8),
              multiplier: data.recommendedRecharge.cycle * 8,
              label: t('common.estimatedDuration', {
                duration: formatSmartDuration(8, data.recommendedRecharge.interval as TimeUnit, {
                  t,
                }),
              }),
            },
          ];

          setPresetAmounts(newPresetAmounts);
          const midAmount = calcCycleAmount(4);
          if (!customAmount && !newPresetAmounts.find((item) => item.amount === midAmount)) {
            setAmount(midAmount);
          }
        } else {
          setPresetAmounts([
            { amount: '10', multiplier: 0, label: '' },
            { amount: '50', multiplier: 0, label: '' },
            { amount: '100', multiplier: 0, label: '' },
          ]);
        }

        const supportRecharge = ['arcblock', 'ethereum', 'base'].includes(data.currency?.paymentMethod?.type);
        if (supportRecharge) {
          const payerTokenRes = await api.get(
            `/api/customers/payer-token?currencyId=${currencyId}&payerAddress=${paymentAddress}`
          );
          if (payerTokenRes?.data) {
            setPayerValue(payerTokenRes.data);
          }
        }
      } else {
        setError(t('customer.balance.currency.notFound'));
      }
    } catch (err) {
      setError(formatError(err) || t('common.fetchError'));
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  const rechargeRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    fetchData();
  }, [currencyId]);

  useEffect(() => {
    if (rechargeRef.current && currency) {
      setTimeout(() => {
        if (rechargeRef.current) {
          const rechargePosition = rechargeRef.current.getBoundingClientRect();
          const absoluteTop = window.scrollY + rechargePosition.top;
          const scrollToPosition = absoluteTop - 120;
          window.scrollTo({
            top: scrollToPosition,
            behavior: 'smooth',
          });
        }
      }, 200);
    }
  }, [currency, loading]);

  const handleRecharge = () => {
    if (!currency) return;

    if (Number.isNaN(Number(amount))) {
      return;
    }

    connect.open({
      containerEl: undefined as unknown as Element,
      saveConnect: false,
      action: 'recharge-account',
      locale: locale as 'en' | 'zh',
      prefix: joinURL(getPrefix(), '/api/did'),
      extraParams: {
        customerDid: session?.user?.did,
        currencyId: currency.id,
        amount: Number(amount),
        rechargeAddress: rechargeAddress || session?.user?.did,
      },
      messages: {
        scan: t('common.connect.defaultScan'),
        title: t('customer.recharge.title'),
        confirm: t('common.connect.confirm'),
      } as any,
      onSuccess: () => {
        connect.close();
        Toast.success(t('customer.recharge.success'));
        fetchData();
      },
      onClose: () => {
        connect.close();
      },
      onError: (err: any) => {
        Toast.error(formatError(err));
      },
    });
  };

  const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    if (!currency) return;
    if (!/^\d*\.?\d*$/.test(value)) return;
    // 不允许以小数点开头
    if (value.startsWith('.')) return;
    if (Number(value) > MAX_SAFE_AMOUNT) {
      return;
    }
    const precision = currency.maximum_precision;
    const errorMessage = formatAmountPrecisionLimit(value, locale, precision || 6);
    setAmountError(errorMessage || '');
    setAmount(value);
  };

  const handleSelect = (selectedAmount: string) => {
    setAmount(selectedAmount);
    setCustomAmount(false);
  };

  const handleCustomSelect = () => {
    setCustomAmount(true);
    setAmount('');
    setTimeout(() => {
      customInputRef.current?.focus();
    }, 0);
  };

  const handleSubscriptionClick = (subscriptionId: string) => {
    navigate(`/customer/subscription/${subscriptionId}`);
  };

  if (loading) {
    return (
      <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50vh' }}>
        <CircularProgress />
      </Box>
    );
  }

  if (!['arcblock', 'ethereum', 'base'].includes(currency?.paymentMethod?.type || '')) {
    return (
      <Box>
        {!inArcsphere && (
          <Button startIcon={<ArrowBackOutlined />} variant="outlined" onClick={() => goBackOrFallback('/customer')}>
            {t('common.previous')}
          </Button>
        )}
        <Empty>{t('customer.recharge.unsupported')}</Empty>
      </Box>
    );
  }

  if (error) {
    return (
      <Box>
        {!inArcsphere && (
          <Button startIcon={<ArrowBackOutlined />} variant="outlined" onClick={() => goBackOrFallback('/customer')}>
            {t('common.previous')}
          </Button>
        )}
        <Alert severity="error" sx={{ mt: 2 }}>
          {error}
        </Alert>
      </Box>
    );
  }

  const currentBalance = formatBNStr(payerValue?.token || '0', currency?.decimal || 0, 6, false);
  const balanceLink = currency?.paymentMethod
    ? getTokenBalanceLink(currency.paymentMethod, paymentAddress || '')
    : undefined;

  return (
    <Root>
      <Stack
        direction="row"
        sx={{
          justifyContent: 'space-between',
          alignItems: 'center',
          position: 'relative',
        }}>
        {!inArcsphere ? (
          <Button
            startIcon={<ArrowBackOutlined />}
            variant="text"
            color="inherit"
            onClick={() => goBackOrFallback('/customer')}
            sx={{ color: 'text.secondary' }}>
            {t('common.previous')}
          </Button>
        ) : (
          <Box />
        )}
      </Stack>
      <Typography variant="h2" gutterBottom>
        {currency?.symbol} {t('customer.recharge.title')}
      </Typography>
      {currency && (
        <Box ref={rechargeRef}>
          <Stack sx={{ maxWidth: '760px' }}>
            <Box sx={{ mb: 4 }}>
              <BalanceCard elevation={0}>
                <Stack
                  direction="row"
                  spacing={2}
                  sx={{
                    justifyContent: 'space-between',
                    alignItems: 'center',
                  }}>
                  <Stack spacing={0.5}>
                    <Typography
                      variant="body2"
                      sx={{
                        color: 'text.secondary',
                      }}>
                      {t('customer.recharge.receiveAddress')}
                    </Typography>
                    <Typography variant="body1" sx={{ wordBreak: 'break-all', fontFamily: 'monospace' }}>
                      {paymentAddress || t('customer.balance.addressNotFound')}
                    </Typography>
                  </Stack>
                  {currency.logo && (
                    <Avatar
                      src={currency.logo}
                      alt={currency.name}
                      sx={{
                        width: {
                          xs: 30,
                          sm: 40,
                        },
                        height: {
                          xs: 30,
                          sm: 40,
                        },
                      }}
                    />
                  )}
                </Stack>
              </BalanceCard>

              <BalanceCard
                elevation={0}
                onClick={() => balanceLink && window.open(balanceLink, '_blank')}
                sx={{
                  color: 'text.primary',
                  borderRadius: 1,
                  transition: 'all 0.2s ease-in-out',
                  cursor: balanceLink ? 'pointer' : 'default',
                  position: 'relative',
                  '&:hover': balanceLink
                    ? {
                        '& .arrow-icon': {
                          opacity: 1,
                          transform: 'translateX(0)',
                        },
                      }
                    : undefined,
                }}>
                <Stack
                  direction="row"
                  sx={{
                    alignItems: 'center',
                    justifyContent: 'space-between',
                  }}>
                  <Stack>
                    <Typography
                      variant="body1"
                      color="inherit"
                      sx={{ display: 'flex', alignItems: 'center', gap: 1, color: 'text.secondary' }}>
                      <AccountBalanceWalletOutlined color="success" fontSize="small" />
                      {t('admin.customer.summary.balance')}
                    </Typography>
                    <Typography variant="h3" sx={{ fontWeight: 'bold', mt: 1, color: 'text.primary' }}>
                      {currentBalance} {currency.symbol}
                    </Typography>
                  </Stack>
                  {balanceLink && (
                    <ArrowForwardOutlined
                      className="arrow-icon"
                      sx={{
                        opacity: 0,
                        transform: 'translateX(-10px)',
                        transition: 'all 0.2s ease-in-out',
                        color: 'inherit',
                        fontSize: 30,
                      }}
                    />
                  )}
                </Stack>
              </BalanceCard>
            </Box>

            <Stack sx={{ mb: 3, backgroundColor: 'background.default', borderRadius: '16px' }}>
              <Grid container spacing={2}>
                {presetAmounts.map(({ amount: presetAmount, label, multiplier }) => (
                  <Grid
                    key={presetAmount}
                    size={{
                      xs: 6,
                      sm: 3,
                    }}>
                    <Card
                      variant="outlined"
                      sx={{
                        height: '100%',
                        display: 'flex',
                        flexDirection: 'column',
                        justifyContent: 'center',
                        transition: 'all 0.2s',
                        cursor: 'pointer',
                        borderRadius: '12px',
                        '&:hover': {
                          transform: 'translateY(-4px)',
                          boxShadow: 3,
                        },
                        ...(amount === presetAmount && !customAmount
                          ? {
                              borderColor: 'primary.main',
                              borderWidth: 2,
                              backgroundColor: 'primary.lighter',
                            }
                          : {}),
                      }}>
                      <CardActionArea
                        onClick={() => handleSelect(presetAmount)}
                        sx={{ height: '100%', p: 1.5, textAlign: 'center' }}>
                        <Typography
                          variant="h6"
                          align="center"
                          sx={{
                            fontWeight: 600,
                            color: amount === presetAmount && !customAmount ? 'primary.main' : 'text.primary',
                          }}>
                          {formatNumber(presetAmount)} {currency.symbol}
                        </Typography>
                        {multiplier > 0 && label && (
                          <Typography
                            variant="caption"
                            align="center"
                            sx={{
                              color: 'text.secondary',
                            }}>
                            {label}
                          </Typography>
                        )}
                      </CardActionArea>
                    </Card>
                  </Grid>
                ))}
                <Grid
                  size={{
                    xs: 6,
                    sm: 3,
                  }}>
                  <Card
                    variant="outlined"
                    sx={{
                      height: '100%',
                      display: 'flex',
                      flexDirection: 'column',
                      justifyContent: 'center',
                      transition: 'all 0.2s',
                      cursor: 'pointer',
                      borderRadius: '12px',
                      '&:hover': {
                        transform: 'translateY(-4px)',
                        boxShadow: '0 4px 10px rgba(0,0,0,0.1)',
                      },
                      ...(customAmount
                        ? {
                            borderColor: 'primary.main',
                            borderWidth: 2,
                            backgroundColor: 'primary.lighter',
                          }
                        : {}),
                    }}>
                    <CardActionArea onClick={handleCustomSelect} sx={{ height: '100%', p: 1 }}>
                      <Stack
                        direction="row"
                        spacing={1}
                        sx={{
                          justifyContent: 'center',
                          alignItems: 'center',
                        }}>
                        <Typography
                          variant="h6"
                          align="center"
                          sx={{ fontWeight: 600, color: customAmount ? 'primary.main' : 'text.primary' }}>
                          {t('customer.recharge.custom') || t('common.custom')}
                        </Typography>
                      </Stack>
                    </CardActionArea>
                  </Card>
                </Grid>
              </Grid>
            </Stack>

            {customAmount && (
              <Box sx={{ mb: 3 }}>
                <TextField
                  fullWidth
                  label={t('customer.recharge.amount')}
                  variant="outlined"
                  type="text"
                  value={amount}
                  error={!!amountError}
                  helperText={amountError}
                  onChange={handleAmountChange}
                  inputRef={customInputRef}
                  autoComplete="off"
                  slotProps={{
                    input: {
                      endAdornment: <Typography>{currency.symbol}</Typography>,
                    },
                    htmlInput: {
                      min: 0,
                      max: MAX_SAFE_AMOUNT,
                    },
                  }}
                />
                {amount && Number(amount) > 0 && Number(unitCycle.amount) > 0 && !amountError && (
                  <Typography
                    variant="body2"
                    sx={{
                      fontSize: 12,
                      color: 'text.lighter',
                      mt: 1,
                    }}>
                    {t('common.estimatedDuration', {
                      duration: formatSmartDuration(
                        Math.floor(Number(amount) / Number(unitCycle.amount)) < 1
                          ? parseFloat((Number(amount) / Number(unitCycle.amount)).toFixed(1))
                          : Math.floor(Number(amount) / Number(unitCycle.amount)),
                        unitCycle.interval,
                        { t }
                      ),
                    })}
                  </Typography>
                )}
              </Box>
            )}

            <Button
              fullWidth
              size="large"
              variant="contained"
              color="primary"
              onClick={handleRecharge}
              disabled={!amount || parseFloat(amount) <= 0 || !!amountError}
              sx={{
                mb: 4,
                py: 1.5,
                borderRadius: '8px',
                boxShadow: '0 4px 10px rgba(0,0,0,0.1)',
                '&:hover': {
                  boxShadow: '0 6px 15px rgba(0,0,0,0.15)',
                  transform: 'translateY(-2px)',
                },
                transition: 'all 0.2s',
              }}>
              {t('customer.recharge.submit')}
            </Button>
          </Stack>
          {relatedSubscriptions.length > 0 && (
            <Box sx={{ mb: 3 }}>
              <Typography variant="h4" gutterBottom>
                {t('customer.recharge.relatedSubscriptions')}
              </Typography>

              <Grid container spacing={2}>
                {relatedSubscriptions.map((subscription) => (
                  <Grid
                    key={subscription.id}
                    size={{
                      xs: 12,
                      sm: 6,
                      md: 4,
                      lg: 3,
                    }}>
                    <Stack
                      onClick={() => handleSubscriptionClick(subscription.id)}
                      className="base-card"
                      sx={{ height: '100%' }}>
                      <Stack
                        direction="row"
                        spacing={1.5}
                        sx={{
                          alignItems: 'center',
                          mb: 1,
                        }}>
                        <Typography
                          variant="subtitle1"
                          sx={{
                            fontWeight: 'medium',
                            overflow: 'hidden',
                            textOverflow: 'ellipsis',
                            whiteSpace: 'nowrap',
                            color: 'text.link',
                            cursor: 'pointer',
                          }}>
                          {subscription.description || subscription.id}
                        </Typography>
                      </Stack>

                      {subscription.items && subscription.items[0] && currency && (
                        <Typography variant="body1" sx={{ color: 'text.secondary' }}>
                          {formatPrice(
                            subscription.items[0].price,
                            currency,
                            subscription.items[0].price?.product?.unit_label
                          )}
                        </Typography>
                      )}
                    </Stack>
                  </Grid>
                ))}
              </Grid>
            </Box>
          )}
          <Divider sx={{ mb: 3 }} />

          <Typography variant="h4" gutterBottom>
            {t('customer.recharge.history')}
          </Typography>

          <RechargeList currency_id={currencyId} customer_id={session?.user?.did} recharge_address={paymentAddress} />
        </Box>
      )}
    </Root>
  );
}
