'use client'

import { useEffect, useState, useCallback } from 'react'
import {
	Button,
	Select,
	InputNumber,
	Switch,
	App,
	Spin,
	Image,
	Card,
} from 'antd'
import { SwapOutlined } from '@ant-design/icons'

interface MintInfo {
	mint: string
	symbol: string
	decimals: number
	logoURI: string
	price: string
	address: string
}

interface QuoteInfo {
	inAmount: string
	outAmount: string
	outAmountUi: number
	priceImpact: string
	route: string
}

const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'

function SwapPageContent() {
	const { message } = App.useApp()
	const [mintList, setMintList] = useState<MintInfo[]>([])
	const [loading, setLoading] = useState(false)
	const [quoting, setQuoting] = useState(false)
	const [swapLoading, setSwapLoading] = useState(false)

	const [inputToken, setInputToken] = useState<string>(USDC_MINT)
	const [outputToken, setOutputToken] = useState<string>('')
	const [inputAmount, setInputAmount] = useState<number | null>(null)
	const [isUsdMode, setIsUsdMode] = useState(true)
	const [quoteInfo, setQuoteInfo] = useState<QuoteInfo | null>(null)

	const fetchMintList = async () => {
		setLoading(true)
		try {
			const response = await fetch('/api/my-lp/mintList')
			const data = await response.json()
			setMintList(data.records || [])
		} catch (error) {
			console.error('Failed to fetch mint list:', error)
			message.error('获取代币列表失败')
		} finally {
			setLoading(false)
		}
	}

	const getQuote = useCallback(async () => {
		if (!inputToken || !outputToken || !inputAmount || inputAmount <= 0) {
			setQuoteInfo(null)
			return
		}

		setQuoting(true)
		try {
			const response = await fetch(
				`/api/swap?inputMint=${inputToken}&outputMint=${outputToken}&amount=${inputAmount}&mode=${isUsdMode ? 'usd' : 'amount'}`
			)
			const data = await response.json()

			if (data.success) {
				setQuoteInfo({
					inAmount: data.inAmount,
					outAmount: data.outAmount,
					outAmountUi: data.outAmountUi,
					priceImpact: data.priceImpact,
					route: data.route,
				})
			} else {
				setQuoteInfo(null)
				console.error('Quote error:', data.error)
			}
		} catch (error) {
			console.error('Failed to get quote:', error)
			setQuoteInfo(null)
		} finally {
			setQuoting(false)
		}
	}, [inputToken, outputToken, inputAmount, isUsdMode])

	useEffect(() => {
		fetchMintList()
	}, [])

	useEffect(() => {
		const timer = setTimeout(() => {
			if (inputAmount && inputAmount > 0) {
				getQuote()
			}
		}, 500)

		return () => clearTimeout(timer)
	}, [inputAmount, inputToken, outputToken, isUsdMode, getQuote])

	const handleSwap = async () => {
		if (!inputToken || !outputToken || !inputAmount || inputAmount <= 0) {
			message.warning('请选择代币并输入金额')
			return
		}

		setSwapLoading(true)
		message.loading({ content: '正在兑换...', key: 'swap', duration: 0 })

		try {
			const response = await fetch('/api/swap', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					inputMint: inputToken,
					outputMint: outputToken,
					amount: inputAmount,
					mode: isUsdMode ? 'usd' : 'amount',
					slippageBps: 200,
				}),
			})

			const data = await response.json()

			if (data.success) {
				message.success({
					content: `兑换成功！交易: ${data.txid.slice(0, 8)}...`,
					key: 'swap',
				})
				window.open(`https://solscan.io/tx/${data.txid}`, '_blank')
				setInputAmount(null)
				setQuoteInfo(null)
			} else {
				message.error({ content: data.error || '兑换失败', key: 'swap' })
			}
		} catch (error) {
			console.error('Swap error:', error)
			message.error({ content: '兑换失败', key: 'swap' })
		} finally {
			setSwapLoading(false)
		}
	}

	const handleSwitchTokens = () => {
		const temp = inputToken
		setInputToken(outputToken)
		setOutputToken(temp)
		setQuoteInfo(null)
	}

	const getTokenInfo = (address: string): MintInfo | undefined => {
		return mintList.find((m) => m.address === address)
	}

	const formatNumber = (num: number, decimals: number = 6): string => {
		if (num >= 1000) {
			return num.toFixed(2)
		} else if (num >= 1) {
			return num.toFixed(4)
		}
		return num.toFixed(decimals)
	}

	const getPlaceholder = (): string => {
		if (isUsdMode) {
			return '输入 USD 金额'
		}
		const token = getTokenInfo(inputToken)
		return `输入 ${token?.symbol || '代币'} 数量`
	}

	return (
		<main style={{ padding: '24px', maxWidth: '500px', margin: '0 auto' }}>
			<Card title="代币兑换">
				<Spin spinning={loading}>
					<div className="space-y-4">
						<div className="flex items-center justify-between mb-4">
							<span className="text-sm text-gray-500">
								{isUsdMode ? '按 USD 金额' : '按代币数量'}
							</span>
							<Switch
								checked={isUsdMode}
								onChange={setIsUsdMode}
								checkedChildren="USD"
								unCheckedChildren="数量"
							/>
						</div>

						<div className="bg-gray-50 dark:bg-gray-800 p-4 rounded-lg">
							<div className="text-xs text-gray-400 mb-2">支付</div>
							<div className="flex items-center gap-2 mb-2">
								<Select
									value={inputToken}
									onChange={(value) => {
										setInputToken(value)
										setQuoteInfo(null)
									}}
									style={{ width: 150 }}
									showSearch
									placeholder="选择代币"
									optionFilterProp="label"
									options={mintList.map((m) => ({
										label: m.symbol,
										value: m.address,
									}))}
									optionRender={(option) => (
										<div className="flex items-center gap-2">
											<Image
												src={
													mintList.find((m) => m.address === option.value)
														?.logoURI
												}
												alt={option.label as string}
												width={20}
												height={20}
												style={{ borderRadius: '50%' }}
												preview={false}
												fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
											/>
											<span>{option.label}</span>
										</div>
									)}
								/>
								<InputNumber
									value={inputAmount}
									onChange={(value) => setInputAmount(value)}
									placeholder={getPlaceholder()}
									style={{ flex: 1 }}
									min={0}
									step={isUsdMode ? 1 : 0.001}
									precision={isUsdMode ? 2 : 6}
								/>
							</div>
							{!isUsdMode && getTokenInfo(inputToken)?.price && (
								<div className="text-xs text-gray-400">
									≈ $
									{formatNumber(
										(inputAmount || 0) *
											Number(getTokenInfo(inputToken)?.price || 0)
									)}
								</div>
							)}
						</div>

						<div className="flex justify-center">
							<Button
								type="text"
								icon={<SwapOutlined />}
								onClick={handleSwitchTokens}
								disabled={!inputToken || !outputToken}
							/>
						</div>

						<div className="bg-gray-50 dark:bg-gray-800 p-4 rounded-lg">
							<div className="text-xs text-gray-400 mb-2">获得</div>
							<div className="flex items-center gap-2">
								<Select
									value={outputToken}
									onChange={(value) => {
										setOutputToken(value)
										setQuoteInfo(null)
									}}
									style={{ width: 150 }}
									showSearch
									placeholder="选择代币"
									optionFilterProp="label"
									options={mintList.map((m) => ({
										label: m.symbol,
										value: m.address,
									}))}
									optionRender={(option) => (
										<div className="flex items-center gap-2">
											<Image
												src={
													mintList.find((m) => m.address === option.value)
														?.logoURI
												}
												alt={option.label as string}
												width={20}
												height={20}
												style={{ borderRadius: '50%' }}
												preview={false}
												fallback="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
											/>
											<span>{option.label}</span>
										</div>
									)}
								/>
								<div className="flex-1 text-right">
									{quoting ? (
										<Spin size="small" />
									) : quoteInfo ? (
										<div>
											<div className="text-lg font-bold">
												{formatNumber(quoteInfo.outAmountUi)}
											</div>
											{getTokenInfo(outputToken)?.price && (
												<div className="text-xs text-gray-400">
													≈ $
													{formatNumber(
														quoteInfo.outAmountUi *
															Number(getTokenInfo(outputToken)?.price || 0)
													)}
												</div>
											)}
										</div>
									) : (
										<span className="text-gray-400">-</span>
									)}
								</div>
							</div>
						</div>

						{quoteInfo && (
							<div className="text-xs text-gray-500 space-y-1 p-2 bg-gray-50 dark:bg-gray-800 rounded">
								<div className="flex justify-between">
									<span>价格影响:</span>
									<span
										style={{
											color:
												Number(quoteInfo.priceImpact) > 1
													? '#ff4d4f'
													: Number(quoteInfo.priceImpact) > 0.5
														? '#faad14'
														: '#52c41a',
										}}
									>
										{(Number(quoteInfo.priceImpact) * 100).toFixed(2)}%
									</span>
								</div>
								{quoteInfo.route && (
									<div className="flex justify-between">
										<span>路由:</span>
										<span className="text-right max-w-[200px] truncate">
											{quoteInfo.route}
										</span>
									</div>
								)}
							</div>
						)}

						<Button
							type="primary"
							block
							size="large"
							onClick={handleSwap}
							loading={swapLoading}
							disabled={
								!inputToken ||
								!outputToken ||
								!inputAmount ||
								inputAmount <= 0 ||
								inputToken === outputToken
							}
						>
							{inputToken === outputToken && inputToken
								? '请选择不同的代币'
								: '兑换'}
						</Button>
					</div>
				</Spin>
			</Card>

			<div className="mt-4 text-xs text-gray-400 text-center">
				<p>使用 Jupiter Ultra API 进行兑换</p>
				<p>滑点: 2%</p>
			</div>
		</main>
	)
}

export default function SwapPage() {
	return <SwapPageContent />
}
