import Button from '@arcblock/ux/lib/Button';
import DID from '@arcblock/ux/lib/DID';
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import Toast from '@arcblock/ux/lib/Toast';
import { StripeForm, api, formatError, usePaymentContext } from '@blocklet/payment-react';
import type { TCustomer } from '@blocklet/payment-types';
import { CreditCard, Email, AccountBalance } from '@mui/icons-material';
import { Box, Stack, Typography } from '@mui/material';
import { useSetState } from 'ahooks';
import { useEffect } from 'react';

interface PaymentMethodData {
  id?: string;
  type: string;
  // Stripe payment methods
  card?: {
    brand: string;
    last4: string;
    exp_month: number;
    exp_year: number;
  };
  link?: {
    email: string;
  };
  us_bank_account?: {
    account_type: string;
    bank_name: string;
    last4: string;
  };
  billing_details?: {
    name?: string;
    email?: string;
    phone?: string;
  };
  // On-chain payment methods (arcblock/ethereum/base)
  payer?: string;
}

interface Props {
  subscriptionId: string;
  customer: TCustomer;
  paymentMethodDetails: PaymentMethodData | null;
  editable?: boolean;
  paymentMethodType: string;
  onUpdate?: () => void;
}

export default function PaymentMethodInfo({
  subscriptionId,
  customer,
  paymentMethodDetails,
  editable = false,
  onUpdate = () => {},
  paymentMethodType,
}: Props) {
  const { t, locale } = useLocaleContext();
  const { connect } = usePaymentContext();

  const [state, setState] = useSetState<{
    editing: boolean;
    submitting: boolean;
    setupIntentId: string | null;
    clientSecret: string | null;
    publishableKey: string | null;
  }>({
    editing: false,
    submitting: false,
    setupIntentId: null,
    clientSecret: null,
    publishableKey: null,
  });

  useEffect(() => {
    if (!state.editing) {
      setState({ clientSecret: null, publishableKey: null, setupIntentId: null });
    }
  }, [state.editing, setState]);

  const handleEdit = async () => {
    if (paymentMethodType === 'stripe') {
      try {
        setState({ submitting: true });
        const { data } = await api.post(`/api/subscriptions/${subscriptionId}/update-stripe-payment-method`);
        setState({
          editing: true,
          clientSecret: data.client_secret,
          publishableKey: data.publishable_key,
          setupIntentId: data.setup_intent_id,
          submitting: false,
        });
      } catch (err) {
        Toast.error(formatError(err));
        setState({ submitting: false });
      }
    } else {
      connect.open({
        action: 'change-payer',
        saveConnect: false,
        locale: locale as 'en' | 'zh',
        useSocket: true,
        messages: {
          scan: '',
          title: t('admin.subscription.changePayer.connect.title'),
          success: t('admin.subscription.changePayer.connect.success'),
          error: t('admin.subscription.changePayer.connect.error'),
          confirm: '',
        } as any,
        extraParams: { subscriptionId },
        onSuccess: () => {
          connect.close();
          Toast.success(t('admin.subscription.changePayer.connect.success'));
          onUpdate?.();
        },
        onClose: () => {
          connect.close();
        },
        onError: (err: any) => {
          Toast.error(formatError(err));
        },
      });
    }
  };

  const handleConfirm = () => {
    setTimeout(() => {
      Toast.success(t('admin.subscription.changePayer.connect.success'));
      setState({ editing: false, submitting: false });
      onUpdate?.();
    }, 2000);
  };

  const handleCancel = () => {
    setState({ editing: false, clientSecret: null, publishableKey: null, setupIntentId: null });
  };

  // Stripe form for editing/binding — must be checked before early returns
  if (state.editing && state.clientSecret && state.publishableKey) {
    return (
      <Box>
        <StripeForm
          clientSecret={state.clientSecret}
          intentType="setup_intent"
          publicKey={state.publishableKey}
          customer={customer}
          mode="setup"
          onConfirm={handleConfirm}
          onCancel={handleCancel}
          returnUrl={window.location.href}
        />
      </Box>
    );
  }

  if (!paymentMethodDetails) {
    if (!editable) {
      return (
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('admin.subscription.noPaymentMethod', { defaultValue: 'Not bound' })}
        </Typography>
      );
    }
    return (
      <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('admin.subscription.noPaymentMethod', { defaultValue: 'Not bound' })}
        </Typography>
        <Button variant="text" size="small" sx={{ color: 'text.link' }} loading={state.submitting} onClick={handleEdit}>
          {t('admin.subscription.bindPaymentMethod', { defaultValue: 'Bind now' })}
        </Button>
      </Stack>
    );
  }

  const { card, link, us_bank_account: usBankAccount, payer, type } = paymentMethodDetails;

  const renderPaymentMethodInfo = () => {
    if (type === 'card' && card) {
      return (
        <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
          <CreditCard sx={{ fontSize: 16, color: 'text.secondary' }} />
          <Typography variant="body2">
            {card.brand.toUpperCase()} •••• {card.last4}
          </Typography>
        </Stack>
      );
    }

    if (type === 'link' && link) {
      return (
        <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
          <Email sx={{ fontSize: 16, color: 'text.secondary' }} />
          <Typography variant="body2">
            {t('admin.subscription.changePayer.stripe.linkType')} ({link.email})
          </Typography>
        </Stack>
      );
    }

    if (type === 'us_bank_account' && usBankAccount) {
      return (
        <Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
          <AccountBalance sx={{ fontSize: 16, color: 'text.secondary' }} />
          <Typography variant="body2">
            {usBankAccount.bank_name || t('admin.subscription.changePayer.stripe.bankAccount')} ••••{' '}
            {usBankAccount.last4}
          </Typography>
        </Stack>
      );
    }

    if (['arcblock', 'ethereum', 'base'].includes(type) && payer) {
      return <DID did={payer} responsive={false} compact copyable={false} />;
    }

    return (
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {type || '-'}
      </Typography>
    );
  };

  return (
    <Stack direction="row" spacing={1} sx={{ alignItems: 'center', flex: 1 }}>
      {renderPaymentMethodInfo()}
      {editable && (
        <Button
          variant="text"
          size="small"
          sx={{
            color: 'text.link',
          }}
          loading={state.submitting}
          onClick={handleEdit}>
          {t('admin.subscription.changePayer.btn')}
        </Button>
      )}
    </Stack>
  );
}
