'use client';
import {useWalletAccess,WalletAccessMessage} from './wallet-action-link';
import {Dialog,DialogContent} from './ui/dialog';

import {useState, type ReactNode} from 'react';
import Link from 'next/link';
import {ArrowDown, ArrowLeft, ArrowLeftRight, Eye, EyeOff, Info, Plus, RefreshCw, Wallet} from 'lucide-react';
import {Tabs, TabsList, TabsTrigger} from './ui/tabs';
import {useSite} from './site-shell';
import {LocalizedNumberInput} from './localized-number-input';
import {tradeCopy} from '@/lib/trade-copy';
import {rialToToman, tokenDecimal, type TradeSide} from '@/lib/trade';
import {formatInvestmentAmount} from '@/lib/investment-amount';
import {calculateMarketTrade, availableMarketTradeBalances, marketTradeAmountAtPercent} from '@/lib/market-trade';
import {wallexAssets, type WallexQuote, type WallexSymbol} from '@/lib/wallex';

const ZERO = BigInt(0);

export function MarketAssetTrade({symbol, quote, now, icon, onLogin}: {
  symbol: WallexSymbol; quote?: WallexQuote; now: number; icon: ReactNode; onLogin: () => void;
}) {
  const {locale, user, sessionStatus, customer} = useSite(), c = tradeCopy(locale);
  const tradeAccess=useWalletAccess('trading'),[accessNotice,setAccessNotice]=useState(false);
  const restriction=user?tradeAccess.message:'';
  const asset = wallexAssets.find(item => item.symbol === symbol)!;
  const [side, setSide] = useState<TradeSide>('buy');
  const [amount, setAmount] = useState('');
  const [review, setReview] = useState(false);
  const [visibility, setVisibility] = useState<{userId: string; hidden: boolean} | null>(null);
  const say = (fa: string, en: string, ar: string) => locale === 'en' ? en : locale === 'ar' ? ar : fa;
  const format = (value: string) => formatInvestmentAmount(value, locale);
  const buy = side === 'buy';
  const calculation = calculateMarketTrade(amount, side, quote?.symbol === symbol ? quote : undefined, now);
  const balances = user && customer.status === 'ready' && customer.data
    ? availableMarketTradeBalances(customer.data.positions, symbol) : {cashRial: null, tokenAtomic: null};
  const available = buy ? balances.cashRial : balances.tokenAtomic;
  const hidden = visibility?.userId === user?.id && visibility ? visibility.hidden : !!customer.data?.preferences?.hide_balances;
  const balanceText = hidden ? '••••' : available === null ? c.unavailable : format(buy ? rialToToman(available) : tokenDecimal(available));
  const insufficient = !calculation.error && available !== null && (buy ? calculation.grossRial > available : calculation.tokenAtomic > available);
  const quoteUnavailable = calculation.error === 'quote';
  const error = quoteUnavailable ? say('قیمت تازه یا دقت تعداد این دارایی در دسترس نیست.', 'A fresh price or quantity precision is unavailable.', 'السعر الحديث أو دقة الكمية غير متاحين.')
    : calculation.error === 'minimum' ? say('مبلغ برای کوچک‌ترین مقدار قابل محاسبه این دارایی کافی نیست.', 'The amount is below the smallest supported quantity.', 'المبلغ أقل من أصغر كمية قابلة للحساب.')
    : calculation.error === 'range' ? c.range
    : calculation.error && amount ? say(`مقدار معتبر وارد کنید؛ ${buy ? 'مبلغ تومان تا یک رقم اعشار' : `تعداد توکن تا ${format(String(quote?.amountPrecision ?? 0))} رقم اعشار`} قابل محاسبه است.`, `Enter a valid amount with up to ${buy ? 1 : quote?.amountPrecision ?? 0} decimal places.`, `أدخل قيمة صحيحة حتى ${buy ? 1 : quote?.amountPrecision ?? 0} منازل عشرية.`) : '';
  const setDirection = (next: TradeSide) => {
    if (next === side) return;
    setAmount(calculation.error ? '' : next === 'sell' ? calculation.quantity : calculation.grossToman);
    setSide(next); setReview(false);
  };
  const choosePercent = (percent: number) => setAmount(marketTradeAmountAtPercent(side, percent, balances.cashRial, balances.tokenAtomic, quote));
  const tokenChip = <span className="trade-currency market-trade-token">{icon}<b dir="ltr">{asset.base}</b></span>;
  const cashChip = <span className="trade-currency"><span className="trade-toman-icon" aria-hidden="true">ت</span><b>TMN</b></span>;
  const balanceError = insufficient ? buy ? c.insufficientCash : c.insufficientToken : '';

  return <aside className={`token-trade-panel market-asset-trade trade-${side}`} aria-label={`${c.title} ${asset.title}`}>
    <div className="market-trade-heading"><ArrowLeftRight size={19}/><h3>{review && user ? c.review : c.trade}</h3><span dir="ltr">{asset.base} / TMN</span></div>
    {review && user && !restriction ? <div className="trade-body market-trade-review">
      <div className="trade-review-symbol">{icon}<strong dir="ltr">{asset.base}</strong><span>{buy ? c.buy : c.sell}</span></div>
      <dl className="trade-review-rows">
        <div><dt>{c.units}</dt><dd>{calculation.error ? '—' : format(calculation.quantity)} <small>{asset.base}</small></dd></div>
        <div><dt>{c.price}</dt><dd>{quoteUnavailable ? '—' : format(quote!.price)} {c.toman}</dd></div>
        <div><dt>{c.gross}</dt><dd>{calculation.error ? '—' : format(calculation.grossToman)} {c.toman}</dd></div>
        <div><dt>{c.fee}</dt><dd>{c.feePending}</dd></div>
        {buy && !calculation.error && calculation.unusedToman !== '0' && <div><dt>{c.unused}</dt><dd>{format(calculation.unusedToman)} {c.toman}</dd></div>}
      </dl>
      {error && <p className="trade-error" role="alert">{error}</p>}
      {balanceError && <output className="trade-balance-warning">{balanceError}</output>}
      <p className="trade-note"><Info size={15}/>{c.notFinal}</p>
      <button className="trade-submit" type="button" disabled>{c.confirmPending}</button>
      <button className="trade-return" type="button" onClick={() => setReview(false)}>{c.back}</button>
    </div> : <div className="trade-body">
      <div className="trade-controls"><Tabs value={side} onValueChange={value => setDirection(value as TradeSide)}><TabsList className="trade-side-tabs"><TabsTrigger value="buy">{c.buy}</TabsTrigger><TabsTrigger value="sell">{c.sell}</TabsTrigger></TabsList></Tabs><span className="market-trade-estimate">{c.estimate}</span></div>
      <div className="trade-balance"><span><Wallet size={15}/>{buy ? c.wallet : c.availableToken}</span><div>{user ? <>
        <b dir={available === null ? 'auto' : 'ltr'}>{customer.status === 'loading' ? c.loading : balanceText}</b>{available !== null && <small>{buy ? c.toman : asset.base}</small>}
        <button type="button" onClick={() => setVisibility({userId: user.id, hidden: !hidden})} className="trade-icon-button" aria-label={hidden ? c.show : c.hide}>{hidden ? <Eye size={15}/> : <EyeOff size={15}/>}</button>
      </> : <button type="button" className="trade-text-button" onClick={onLogin}>{c.login}</button>}</div></div>
      {user && customer.status === 'error' && <output className="trade-data-error">{c.balanceError}<button type="button" onClick={() => void customer.reload()}><RefreshCw size={13}/>{c.retry}</button></output>}
      <div className="trade-conversion">
        <div className="trade-amount-block"><div className="trade-field-label"><label htmlFor={`market-trade-${symbol}`}>{c.pay}</label><button type="button" onClick={() => choosePercent(100)} disabled={available === null || available === ZERO || quoteUnavailable} className="trade-max">{c.max}</button></div>
          <div className="trade-input-row"><LocalizedNumberInput id={`market-trade-${symbol}`} locale={locale} value={amount} onValueChange={setAmount} inputMode="decimal" autoComplete="off" maxLength={48} placeholder="۰" aria-label={buy ? c.buyAmount : c.sellAmount} aria-invalid={!!amount && !!error} aria-describedby={error ? `market-trade-error-${symbol}` : undefined} dir="ltr"/>{buy ? cashChip : tokenChip}</div>
          <div className="trade-presets">{[25, 50, 75, 100].map(percent => <button key={percent} type="button" disabled={available === null || available === ZERO || quoteUnavailable} onClick={() => choosePercent(percent)}>{format(String(percent))}٪</button>)}</div>
        </div>
        <div className="trade-swap-line"><button type="button" onClick={() => setDirection(buy ? 'sell' : 'buy')} aria-label={c.switchSide}><ArrowDown size={22}/></button></div>
        <div className="trade-amount-block trade-receive"><span className="trade-field-label">{c.receive}<small>{c.estimate}</small></span><div className="trade-input-row"><output className="trade-receive-value" aria-live="polite" aria-label={c.receive} dir="ltr">{calculation.error ? quoteUnavailable ? '—' : format('0') : format(buy ? calculation.quantity : calculation.grossToman)}</output>{buy ? tokenChip : cashChip}</div><span className="trade-unit-note">{say('تعداد بر اساس دقت همین دارایی محاسبه می‌شود.', 'Quantity uses this asset’s supported precision.', 'تُحسب الكمية وفق دقة هذا الأصل.')}</span></div>
      </div>
      <div className="trade-price-line"><span>{c.price}</span><strong>{quoteUnavailable ? '—' : format(quote!.price)} <small>{c.toman}</small></strong></div>
      {buy && !calculation.error && calculation.unusedToman !== '0' && <p className="trade-rounding">{c.unused}: {format(calculation.unusedToman)} {c.toman}</p>}
      {error && <p className="trade-error" id={`market-trade-error-${symbol}`} role="alert">{error}</p>}
      {balanceError && <output className="trade-balance-warning">{balanceError}{buy && <Link href="/wallet/deposit"><Plus size={13}/>{c.deposit}</Link>}</output>}
      {restriction&&<p className="trade-error" role="status">{restriction}</p>}<button type="button" className="trade-submit" disabled={sessionStatus === 'loading' || (tradeAccess.allowed && (!!calculation.error || (!!user && insufficient)))} onClick={() => !user ? onLogin() : !tradeAccess.allowed ? setAccessNotice(true) : setReview(true)}>{sessionStatus === 'loading' ? c.loading : user ? buy ? c.reviewBuy : c.reviewSell : buy ? c.loginBuy : c.loginSell}<span dir="ltr">{asset.base}</span><ArrowLeft size={18}/></button>
      <p className="trade-note"><Info size={14}/>{c.pending}</p>
      <div className="trade-bottom-links"><Link href="/wallet"><Wallet size={16}/>{c.walletPage}</Link></div>
    </div>}
  <Dialog open={accessNotice} onOpenChange={setAccessNotice}><DialogContent className="planck-modal" dir="rtl"><WalletAccessMessage {...tradeAccess}/></DialogContent></Dialog>
  </aside>;
}
