import { useState, useEffect } from 'react';
import { View, Text, TextInput, TouchableOpacity, ActivityIndicator, Modal<% if (styling !== 'nativewind') { %>, StyleSheet<% } %> } from 'react-native';
import { useWallet } from '@lazorkit/wallet-mobile-adapter';
import { Connection, PublicKey } from '@solana/web3.js';
import * as Linking from 'expo-linking';

const TOKENS = [
  { symbol: 'SOL', mint: 'So11111111111111111111111111111111111111112', decimals: 9 },
  { symbol: 'USDC', mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6 },
  { symbol: 'USDT', mint: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', decimals: 6 },
  { symbol: 'BONK', mint: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', decimals: 5 },
  { symbol: 'JUP', mint: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', decimals: 6 },
];

const SLIPPAGE_OPTIONS = [50, 100, 300];

const JUPITER_API = 'https://api.jup.ag/swap/v1';
const JUP_API_KEY = process.env.EXPO_PUBLIC_JUPITER_API_KEY || '';

function useBalances(walletAddress: string | undefined) {
  const [balances, setBalances] = useState<Record<string, number>>({});
  useEffect(() => {
    if (!walletAddress) return;
    const rpc = process.env.EXPO_PUBLIC_SOLANA_RPC || 'https://api.devnet.solana.com';
    const conn = new Connection(rpc);
    const pk = new PublicKey(walletAddress);
    conn.getBalance(pk).then((bal) => setBalances((b) => ({ ...b, SOL: bal / 1e9 }))).catch(() => {});
    conn.getParsedTokenAccountsByOwner(pk, { programId: new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') })
      .then((res) => {
        const tokenBals: Record<string, number> = {};
        res.value.forEach((acc) => {
          const info = acc.account.data.parsed.info;
          const token = TOKENS.find((t) => t.mint === info.mint);
          if (token) tokenBals[token.symbol] = info.tokenAmount.uiAmount || 0;
        });
        setBalances((b) => ({ ...b, ...tokenBals }));
      }).catch(() => {});
  }, [walletAddress]);
  return balances;
}
<% if (styling !== 'nativewind') { %>
const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#fff', padding: 24, paddingTop: 60 },
  card: { backgroundColor: '#0a0a0a', borderRadius: 16, padding: 20 },
  header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 24 },
  title: { fontSize: 18, fontWeight: '600', color: '#fafafa' },
  address: { fontSize: 12, color: '#737373' },
  inputCard: { backgroundColor: '#171717', borderWidth: 1, borderColor: '#262626', borderRadius: 12, padding: 16 },
  label: { fontSize: 12, color: '#737373', marginBottom: 8 },
  labelRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 8 },
  switchText: { fontSize: 12, color: '#737373' },
  inputRow: { flexDirection: 'row', alignItems: 'center' },
  input: { flex: 1, fontSize: 24, fontWeight: '500', color: '#fafafa' },
  outputText: { flex: 1, fontSize: 24, fontWeight: '500', color: '#737373' },
  arrow: { alignItems: 'center', marginVertical: 8 },
  arrowBox: { width: 32, height: 32, backgroundColor: '#171717', borderWidth: 1, borderColor: '#262626', borderRadius: 8, alignItems: 'center', justifyContent: 'center' },
  arrowText: { color: '#737373', fontSize: 16 },
  tokenBtn: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#262626', paddingHorizontal: 12, paddingVertical: 8, borderRadius: 8, gap: 6 },
  tokenText: { fontSize: 14, fontWeight: '500', color: '#fafafa' },
  tokenArrow: { fontSize: 10, color: '#737373' },
  button: { marginTop: 16, backgroundColor: '#fafafa', paddingVertical: 14, borderRadius: 12, alignItems: 'center' },
  buttonSecondary: { marginTop: 8, backgroundColor: 'transparent', borderWidth: 1, borderColor: '#262626', paddingVertical: 12, borderRadius: 12, alignItems: 'center' },
  buttonDisabled: { opacity: 0.5 },
  buttonText: { color: '#0a0a0a', fontSize: 14, fontWeight: '500' },
  buttonTextSecondary: { color: '#fafafa', fontSize: 13, fontWeight: '500' },
  result: { marginTop: 12, fontSize: 14, textAlign: 'center' },
  footer: { marginTop: 16, fontSize: 12, color: '#737373', textAlign: 'center' },
  quote: { fontSize: 12, color: '#737373', marginTop: 8 },
  slippageRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 12 },
  slippageLabel: { fontSize: 12, color: '#737373' },
  slippageBtn: { paddingHorizontal: 8, paddingVertical: 4, borderRadius: 4, backgroundColor: '#262626' },
  slippageBtnActive: { backgroundColor: '#fafafa' },
  slippageBtnText: { fontSize: 12, color: '#a3a3a3' },
  slippageBtnTextActive: { color: '#0a0a0a' },
  modal: { flex: 1, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0.5)' },
  modalContent: { backgroundColor: '#171717', borderTopLeftRadius: 16, borderTopRightRadius: 16, padding: 16, paddingBottom: 32 },
  modalTitle: { fontSize: 16, fontWeight: '600', marginBottom: 16, textAlign: 'center', color: '#fafafa' },
  modalItem: { paddingVertical: 14, borderBottomWidth: 1, borderBottomColor: '#262626' },
  modalItemText: { fontSize: 16, color: '#fafafa' },
});
<% } %>
export function Swap() {
  const { disconnect, wallet, signAndSendTransaction, signMessage } = useWallet();
  const balances = useBalances(wallet?.smartWallet);
  const [fromToken, setFromToken] = useState(TOKENS[0]);
  const [toToken, setToToken] = useState(TOKENS[1]);
  const [amount, setAmount] = useState('');
  const [slippage, setSlippage] = useState(SLIPPAGE_OPTIONS[0]);
  const [quote, setQuote] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [signing, setSigning] = useState(false);
  const [result, setResult] = useState<{ success: boolean; message: string } | null>(null);
  const [showPicker, setShowPicker] = useState<'from' | 'to' | null>(null);
  const redirectUrl = Linking.createURL('/');

  const switchTokens = () => { setFromToken(toToken); setToToken(fromToken); setAmount(''); setQuote(null); };

  useEffect(() => {
    if (!amount || parseFloat(amount) <= 0) { setQuote(null); return; }
    const timeout = setTimeout(async () => {
      try {
        const inputAmount = Math.floor(parseFloat(amount) * 10 ** fromToken.decimals);
        const headers: Record<string, string> = {};
        if (JUP_API_KEY) headers['x-api-key'] = JUP_API_KEY;
        const res = await fetch(`${JUPITER_API}/quote?inputMint=${fromToken.mint}&outputMint=${toToken.mint}&amount=${inputAmount}&slippageBps=${slippage}&restrictIntermediateTokens=true`, { headers });
        const data = await res.json();
        if (data.outAmount) setQuote(data);
        else setQuote(null);
      } catch (e) { console.error('Quote error:', e); setQuote(null); }
    }, 500);
    return () => clearTimeout(timeout);
  }, [amount, fromToken, toToken, slippage]);

  const outputAmount = quote ? (parseInt(quote.outAmount) / 10 ** toToken.decimals).toFixed(toToken.decimals === 6 ? 2 : 4) : '0.00';

  const handleSwap = async () => {
    if (!wallet?.smartWallet || !quote) return;
    setLoading(true); setResult(null);
    try {
      const headers: Record<string, string> = { 'Content-Type': 'application/json' };
      if (JUP_API_KEY) headers['x-api-key'] = JUP_API_KEY;
      const swapRes = await fetch(`${JUPITER_API}/swap-instructions`, {
        method: 'POST', headers,
        body: JSON.stringify({ quoteResponse: quote, userPublicKey: wallet.smartWallet, wrapAndUnwrapSol: true, dynamicComputeUnitLimit: true }),
      });
      if (!swapRes.ok) throw new Error(`Jupiter API error: ${await swapRes.text()}`);
      const { setupInstructions = [], swapInstruction, cleanupInstruction, addressLookupTableAddresses = [] } = await swapRes.json();
      if (!swapInstruction) throw new Error('No swap instruction returned');

      const toInstruction = (ix: any) => ({
        programId: new PublicKey(ix.programId),
        keys: ix.accounts.map((acc: any) => ({ pubkey: new PublicKey(acc.pubkey), isSigner: acc.isSigner, isWritable: acc.isWritable })),
        data: Buffer.from(ix.data, 'base64'),
      });
      const instructions = [...setupInstructions.map(toInstruction), toInstruction(swapInstruction), ...(cleanupInstruction ? [toInstruction(cleanupInstruction)] : [])];

      let addressLookupTableAccounts: any[] = [];
      if (addressLookupTableAddresses.length > 0) {
        const rpc = process.env.EXPO_PUBLIC_SOLANA_RPC || 'https://api.devnet.solana.com';
        const conn = new Connection(rpc);
        const alts = await Promise.all(addressLookupTableAddresses.map(async (addr: string) => (await conn.getAddressLookupTable(new PublicKey(addr))).value));
        addressLookupTableAccounts = alts.filter(Boolean);
      }

      const sig = await signAndSendTransaction({ instructions, transactionOptions: { feeToken: 'USDC', addressLookupTableAccounts } }, { redirectUrl });
      setResult({ success: true, message: `Swapped! ${sig.slice(0, 8)}...` });
      setAmount(''); setQuote(null);
    } catch (e) { console.error('Swap error:', e); setResult({ success: false, message: e instanceof Error ? e.message : 'Swap failed' }); }
    finally { setLoading(false); }
  };

  const handleSignMessage = async () => {
    setSigning(true); setResult(null);
    try {
      const message = `Verify wallet ownership\nTimestamp: ${Date.now()}`;
      const signature = await signMessage(message, { redirectUrl });
      setResult({ success: true, message: `Signed: ${signature.slice(0, 16)}...` });
    } catch (e) { console.error('Sign error:', e); setResult({ success: false, message: e instanceof Error ? e.message : 'Sign failed' }); }
    finally { setSigning(false); }
  };

  const addr = wallet?.smartWallet || '';

  return (
<% if (styling === 'nativewind') { %>
    <View className="flex-1 bg-white p-6 pt-16">
      <View className="bg-neutral-900 rounded-2xl p-5">
        <View className="flex-row items-center justify-between mb-6"><Text className="text-lg font-semibold text-white">Swap</Text><TouchableOpacity onPress={() => disconnect()}><Text className="text-xs text-neutral-500">{addr.slice(0, 6)}...{addr.slice(-4)}</Text></TouchableOpacity></View>
        <View className="bg-neutral-800 border border-neutral-700 rounded-xl p-4">
          <View className="flex-row justify-between mb-2"><Text className="text-xs text-neutral-500">From</Text><Text className="text-xs text-neutral-500">Balance: {(balances[fromToken.symbol] ?? 0).toFixed(4)}</Text></View>
          <View className="flex-row items-center"><TextInput className="flex-1 text-2xl font-medium text-white" placeholder="0.00" placeholderTextColor="#737373" value={amount} onChangeText={setAmount} keyboardType="numeric" /><TouchableOpacity className="flex-row items-center bg-neutral-700 px-3 py-2 rounded-lg" onPress={() => setShowPicker('from')}><Text className="text-sm font-medium text-white mr-1">{fromToken.symbol}</Text><Text className="text-xs text-neutral-400">▼</Text></TouchableOpacity></View>
          <TouchableOpacity onPress={() => setAmount(String(balances[fromToken.symbol] ?? 0))}><Text className="text-xs text-neutral-500 mt-1">Max</Text></TouchableOpacity>
        </View>
        <View className="items-center my-2"><TouchableOpacity onPress={switchTokens} className="w-8 h-8 bg-neutral-800 border border-neutral-700 rounded-lg items-center justify-center"><Text className="text-neutral-500">↓</Text></TouchableOpacity></View>
        <View className="bg-neutral-800 border border-neutral-700 rounded-xl p-4">
          <View className="flex-row justify-between mb-2"><Text className="text-xs text-neutral-500">To</Text><Text className="text-xs text-neutral-500">Balance: {(balances[toToken.symbol] ?? 0).toFixed(4)}</Text></View>
          <View className="flex-row items-center"><Text className="flex-1 text-2xl font-medium text-neutral-500">{outputAmount}</Text><TouchableOpacity className="flex-row items-center bg-neutral-700 px-3 py-2 rounded-lg" onPress={() => setShowPicker('to')}><Text className="text-sm font-medium text-white mr-1">{toToken.symbol}</Text><Text className="text-xs text-neutral-400">▼</Text></TouchableOpacity></View>
          {quote && <Text className="text-xs text-neutral-500 mt-2">via Jupiter · {quote.routePlan?.[0]?.swapInfo?.label || 'Best route'}</Text>}
        </View>
        <View className="flex-row items-center justify-between mt-3"><Text className="text-xs text-neutral-500">Slippage</Text><View className="flex-row gap-1">{SLIPPAGE_OPTIONS.map((s) => (<TouchableOpacity key={s} onPress={() => setSlippage(s)} className={`px-2 py-1 rounded ${slippage === s ? 'bg-white' : 'bg-neutral-700'}`}><Text className={`text-xs ${slippage === s ? 'text-black' : 'text-neutral-400'}`}>{s / 100}%</Text></TouchableOpacity>))}</View></View>
        <TouchableOpacity className={`mt-4 bg-white py-3.5 rounded-xl items-center ${loading || !quote ? 'opacity-50' : ''}`} onPress={handleSwap} disabled={loading || !quote}>{loading ? <ActivityIndicator color="#0a0a0a" size="small" /> : <Text className="text-black text-sm font-medium">Swap</Text>}</TouchableOpacity>
        <TouchableOpacity className={`mt-2 border border-neutral-700 py-3 rounded-xl items-center ${signing ? 'opacity-50' : ''}`} onPress={handleSignMessage} disabled={signing}>{signing ? <ActivityIndicator color="#fafafa" size="small" /> : <Text className="text-white text-sm font-medium">Sign Message</Text>}</TouchableOpacity>
        {result && <Text className={`mt-3 text-sm text-center ${result.success ? 'text-neutral-400' : 'text-red-400'}`}>{result.message}</Text>}
        <Text className="mt-4 text-xs text-center text-neutral-500">Gas sponsored · Powered by LazorKit + Jupiter</Text>
      </View>
      <Modal visible={!!showPicker} transparent animationType="slide" onRequestClose={() => setShowPicker(null)}>
        <TouchableOpacity className="flex-1 justify-end bg-black/50" activeOpacity={1} onPress={() => setShowPicker(null)}>
          <View className="bg-neutral-800 rounded-t-2xl p-4 pb-8"><Text className="text-base font-semibold text-center mb-4 text-white">Select Token</Text>{TOKENS.filter(t => t.symbol !== (showPicker === 'from' ? toToken.symbol : fromToken.symbol)).map(t => (<TouchableOpacity key={t.symbol} className="py-3.5 border-b border-neutral-700" onPress={() => { showPicker === 'from' ? setFromToken(t) : setToToken(t); setShowPicker(null); }}><Text className="text-base text-white">{t.symbol}</Text></TouchableOpacity>))}</View>
        </TouchableOpacity>
      </Modal>
    </View>
<% } else { %>
    <View style={styles.container}>
      <View style={styles.card}>
        <View style={styles.header}><Text style={styles.title}>Swap</Text><TouchableOpacity onPress={() => disconnect()}><Text style={styles.address}>{addr.slice(0, 6)}...{addr.slice(-4)}</Text></TouchableOpacity></View>
        <View style={styles.inputCard}>
          <View style={styles.labelRow}><Text style={styles.label}>From</Text><Text style={styles.label}>Balance: {(balances[fromToken.symbol] ?? 0).toFixed(4)}</Text></View>
          <View style={styles.inputRow}><TextInput style={styles.input} placeholder="0.00" placeholderTextColor="#737373" value={amount} onChangeText={setAmount} keyboardType="numeric" /><TouchableOpacity style={styles.tokenBtn} onPress={() => setShowPicker('from')}><Text style={styles.tokenText}>{fromToken.symbol}</Text><Text style={styles.tokenArrow}>▼</Text></TouchableOpacity></View>
          <TouchableOpacity onPress={() => setAmount(String(balances[fromToken.symbol] ?? 0))}><Text style={styles.switchText}>Max</Text></TouchableOpacity>
        </View>
        <View style={styles.arrow}><TouchableOpacity onPress={switchTokens} style={styles.arrowBox}><Text style={styles.arrowText}>↓</Text></TouchableOpacity></View>
        <View style={styles.inputCard}>
          <View style={styles.labelRow}><Text style={styles.label}>To</Text><Text style={styles.label}>Balance: {(balances[toToken.symbol] ?? 0).toFixed(4)}</Text></View>
          <View style={styles.inputRow}><Text style={styles.outputText}>{outputAmount}</Text><TouchableOpacity style={styles.tokenBtn} onPress={() => setShowPicker('to')}><Text style={styles.tokenText}>{toToken.symbol}</Text><Text style={styles.tokenArrow}>▼</Text></TouchableOpacity></View>
          {quote && <Text style={styles.quote}>via Jupiter · {quote.routePlan?.[0]?.swapInfo?.label || 'Best route'}</Text>}
        </View>
        <View style={styles.slippageRow}><Text style={styles.slippageLabel}>Slippage</Text><View style={{ flexDirection: 'row', gap: 4 }}>{SLIPPAGE_OPTIONS.map((s) => (<TouchableOpacity key={s} onPress={() => setSlippage(s)} style={[styles.slippageBtn, slippage === s && styles.slippageBtnActive]}><Text style={[styles.slippageBtnText, slippage === s && styles.slippageBtnTextActive]}>{s / 100}%</Text></TouchableOpacity>))}</View></View>
        <TouchableOpacity style={[styles.button, (loading || !quote) && styles.buttonDisabled]} onPress={handleSwap} disabled={loading || !quote}>{loading ? <ActivityIndicator color="#0a0a0a" size="small" /> : <Text style={styles.buttonText}>Swap</Text>}</TouchableOpacity>
        <TouchableOpacity style={[styles.buttonSecondary, signing && styles.buttonDisabled]} onPress={handleSignMessage} disabled={signing}>{signing ? <ActivityIndicator color="#fafafa" size="small" /> : <Text style={styles.buttonTextSecondary}>Sign Message</Text>}</TouchableOpacity>
        {result && <Text style={[styles.result, { color: result.success ? '#737373' : '#ef4444' }]}>{result.message}</Text>}
        <Text style={styles.footer}>Gas sponsored · Powered by LazorKit + Jupiter</Text>
      </View>
      <Modal visible={!!showPicker} transparent animationType="slide" onRequestClose={() => setShowPicker(null)}>
        <TouchableOpacity style={styles.modal} activeOpacity={1} onPress={() => setShowPicker(null)}>
          <View style={styles.modalContent}><Text style={styles.modalTitle}>Select Token</Text>{TOKENS.filter(t => t.symbol !== (showPicker === 'from' ? toToken.symbol : fromToken.symbol)).map(t => (<TouchableOpacity key={t.symbol} style={styles.modalItem} onPress={() => { showPicker === 'from' ? setFromToken(t) : setToToken(t); setShowPicker(null); }}><Text style={styles.modalItemText}>{t.symbol}</Text></TouchableOpacity>))}</View>
        </TouchableOpacity>
      </Modal>
    </View>
<% } %>
  );
}
