import { Landmark, Minus, Plus } from 'lucide-react'
import { type ReactNode, useState } from 'react'
import { useTranslation } from 'react-i18next'
import lengthBlueBtn from '@/assets/system/length-blue-btn.webp'
import lengthGreenBtn from '@/assets/system/length-green-btn.webp'
import { SmartBackground } from '@/components/smart-background.tsx'
import { Input } from '@/components/ui/input.tsx'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select.tsx'
import { useWithdrawSubmit } from '@/hooks/use-withdraw-submit'
import { useWithdrawVm } from '@/hooks/use-withdraw-vm'
import { cn } from '@/lib/utils'
import { useModalStore } from '@/store'
import type { FinanceCurrencyConfig, FinanceWithdrawBank } from '@/type'
const PANEL_CLASS =
'rounded-md border border-[rgba(110,229,243,0.24)] bg-[linear-gradient(180deg,rgba(7,30,43,0.9),rgba(3,15,26,0.94))] shadow-[inset_0_0_calc(var(--design-unit)*10)_rgba(88,225,238,0.08)]'
function formatNumber(value: number) {
return new Intl.NumberFormat('en-US').format(value)
}
function getPaymentGlyph(code: string, name: string) {
if (code.toLowerCase().includes('alipay')) {
return '支'
}
return name.trim().slice(0, 1).toUpperCase() || code.slice(0, 1).toUpperCase()
}
function BankOptionLogo({ bank }: { bank: FinanceWithdrawBank }) {
if (bank.logo.trim()) {
return (
)
}
return (
)
}
function WithdrawField({
label,
children,
}: {
label: string
children: ReactNode
}) {
return (
)
}
function AmountShell({
amount,
availableBalanceText,
onAmountChange,
onMinus,
onPlus,
}: {
amount: number
availableBalanceText: string
onAmountChange: (value: number) => void
onMinus: () => void
onPlus: () => void
}) {
function handleInputChange(value: string) {
const nextValue = Number(value.replace(/[^\d]/g, ''))
onAmountChange(Number.isFinite(nextValue) ? nextValue : 0)
}
return (
)
}
function QuickAmountCard({
amount,
preview,
active,
onClick,
}: {
amount: number
preview: string
active: boolean
onClick: () => void
}) {
return (
)
}
function PaymentCard({
active,
label,
glyph,
onClick,
}: {
active: boolean
label: string
glyph: string
onClick: () => void
}) {
return (
)
}
function InputShell({
value,
onChange,
placeholder,
error,
errorMessage,
uppercase = false,
type = 'text',
}: {
value: string
onChange: (value: string) => void
placeholder: string
error?: boolean
errorMessage?: string
uppercase?: boolean
type?: 'text' | 'email' | 'tel'
}) {
return (
onChange(event.target.value)}
placeholder={placeholder}
className={cn(
'h-design-30 rounded-[calc(var(--design-unit)*5)] border px-design-8 !text-design-10 placeholder:!text-design-10',
uppercase && 'uppercase',
error
? 'border-[#B93F44] bg-[rgba(34,13,16,0.78)] text-[#FCEEEE]'
: 'border-[rgba(103,227,239,0.24)] bg-[linear-gradient(180deg,rgba(10,47,57,0.84),rgba(5,23,32,0.92))] text-[#ACF1F6]',
)}
/>
{error && errorMessage ? (
{errorMessage}
) : null}
)
}
function PreviewRow({
label,
value,
highlight = false,
}: {
label: string
value: ReactNode
highlight?: boolean
}) {
return (
)
}
function MobileWithdraw() {
const { t } = useTranslation()
const vm = useWithdrawVm()
const withdrawSubmitMutation = useWithdrawSubmit()
const setModalOpen = useModalStore((state) => state.setModalOpen)
const [hasSubmitted, setHasSubmitted] = useState(false)
const [activeQuickAmountId, setActiveQuickAmountId] = useState(
null,
)
function handleAmountChange(nextAmount: number) {
vm.setAmount(Math.max(0, nextAmount))
setActiveQuickAmountId(null)
}
function handleQuickAmountSelect(optionId: string, amount: number) {
vm.setAmount(Math.max(0, amount))
setActiveQuickAmountId(optionId)
}
function resetWithdrawFormState() {
setHasSubmitted(false)
setActiveQuickAmountId(null)
vm.resetForm()
}
function handleCloseWithdraw() {
resetWithdrawFormState()
setModalOpen('desktopWithdrawTopup', false)
}
function handleConfirmWithdraw() {
if (withdrawSubmitMutation.isPending) {
return
}
setHasSubmitted(true)
if (
vm.amountRequiredError ||
vm.amountExceedsBalance ||
vm.amountBelowPaymentMinimum ||
vm.amountAbovePaymentMaximum ||
vm.holderNameError ||
vm.bankAccountError ||
vm.paymentChannelCodeError ||
vm.paymentTypeError ||
vm.bankCodeError ||
vm.receiverEmailError ||
vm.receiverPhoneError
) {
return
}
withdrawSubmitMutation.mutate(
{
bank_code: vm.bankCode,
channel_code: vm.paymentChannelCode,
idempotency_key: String(Date.now()),
payment_type: vm.paymentType,
receive_account: vm.bankAccount.trim(),
receiver_email: vm.receiverEmail.trim(),
receiver_mobile: vm.receiverPhone.trim(),
receiver_name: vm.holderName.trim(),
receive_type: 'bank',
withdraw_coin: vm.amount,
},
{
onSuccess: () => {
handleCloseWithdraw()
},
},
)
}
return (
handleAmountChange(vm.amount - 1)}
onPlus={() => handleAmountChange(vm.amount + 1)}
/>
{hasSubmitted && vm.amountRequiredError ? (
{t('gameDesktop.withdraw.errors.amountRequired')}
) : null}
{hasSubmitted && vm.amountExceedsBalance ? (
{t('gameDesktop.withdraw.errors.amountExceedsBalance')}
) : null}
{hasSubmitted && vm.amountBelowPaymentMinimum ? (
{t('gameDesktop.withdraw.errors.amountBelowPaymentMinimum', {
amount: vm.paymentMinimumAmountLabel,
})}
) : null}
{hasSubmitted && vm.amountAbovePaymentMaximum ? (
{t('gameDesktop.withdraw.errors.amountAbovePaymentMaximum', {
amount: vm.paymentMaximumAmountLabel,
})}
) : null}
{vm.quickAmounts.map((option) => (
handleQuickAmountSelect(option.id, option.diamonds)
}
/>
))}
{vm.sortedPayChannels.length > 0 ? (
{vm.sortedPayChannels.map((channel) => (
vm.setPaymentChannelCode(channel.code)}
/>
))}
) : (
{t('gameDesktop.withdraw.errors.paymentChannelUnavailable')}
)}
{hasSubmitted && vm.paymentChannelCodeError ? (
{t('gameDesktop.withdraw.errors.paymentChannelRequired')}
) : null}
{hasSubmitted && vm.paymentTypeError ? (
{t('gameDesktop.withdraw.errors.paymentTypeRequired')}
) : null}
{vm.sortedBanks.length === 0 ? (
{t('gameDesktop.withdraw.errors.bankCodeUnavailable')}
) : null}
{hasSubmitted && vm.bankCodeError ? (
{t('gameDesktop.withdraw.errors.bankCodeRequired')}
) : null}
{vm.withdrawCopy.rateHint}
{vm.withdrawCopy.processingLabel}:{' '}
{vm.withdrawCopy.processingValue}
{vm.withdrawCopy.noticeLabel}:{' '}
{vm.withdrawCopy.feeNote}
{t('gameDesktop.withdraw.cancel')}
{withdrawSubmitMutation.isPending
? t('commonUi.action.submitting')
: `${t('gameDesktop.withdraw.confirm')}`}
)
}
export default MobileWithdraw