'use client';

import { useState, useEffect, useCallback } from 'react';
import PortalLayout from '@/app/layout-portal';
import AuthGuard from '@/components/AuthGuard';
import { paymentService, type TokenInfo, type MAOSDiscountTier } from '@/lib/payment';
import {
  connectWallet, switchToChain270, getInjectedProvider,
  formatWeiToETH, formatBytes, type WalletProvider,
} from '@/lib/wallet';
import {
  Wallet, Loader2, CheckCircle, XCircle,
  RefreshCw, AlertTriangle,
} from 'lucide-react';
import Overview from './components/Overview';
import PricingView from './components/PricingView';
import TokensView from './components/TokensView';
import TiersView from './components/TiersView';

type ViewMode = 'overview' | 'pricing' | 'tokens' | 'tiers';
type TxStatus = { ok: boolean; msg: string } | null;

export default function AdminPaymentPage() {
  const [address, setAddress] = useState<string | null>(null);
  const [provider, setProvider] = useState<WalletProvider | null>(null);
  const [connecting, setConnecting] = useState(false);
  const [wrongChain, setWrongChain] = useState(false);
  const [walletType, setWalletType] = useState<string | null>(null);
  const [view, setView] = useState<ViewMode>('overview');
  const [txStatus, setTxStatus] = useState<TxStatus>(null);

  // Contract state
  const [owner, setOwner] = useState<string | null>(null);
  const [deployed, setDeployed] = useState(false);
  const [basePrice, setBasePrice] = useState<bigint>(BigInt(0));
  const [freeTier, setFreeTier] = useState<bigint>(BigInt(0));
  const [tokens, setTokens] = useState<TokenInfo[]>([]);
  const [tiers, setTiers] = useState<MAOSDiscountTier[]>([]);
  const [totalUploads, setTotalUploads] = useState<bigint>(BigInt(0));
  const [revenues, setRevenues] = useState<Record<string, bigint>>({});
  const [loading, setLoading] = useState(true);
  const [contractBalance, setContractBalance] = useState<Record<string, string>>({});

  const isOwner = !!(address && owner && address.toLowerCase() === owner.toLowerCase());

  // ── Load all contract state ──
  const refresh = useCallback(async () => {
    setLoading(true);
    setTxStatus(null);
    try {
      paymentService.isDeployed().then(setDeployed).catch(() => setDeployed(false));
      const [own, price, free, t, tiersData, uploads] = await Promise.all([
        paymentService.getOwner(),
        paymentService.getBasePricePerMB(),
        paymentService.getFreeTierBytes(),
        paymentService.getSupportedTokens(),
        paymentService.getMAOSDiscountTiers(),
        paymentService.getTotalUploads(),
      ]);
      setOwner(own);
      setBasePrice(price);
      setFreeTier(free);
      setTiers(tiersData);

      // Deduplicate by symbol
      const seen = new Set<string>();
      const uniqueTokens = t.filter(tk => {
        if (seen.has(tk.symbol)) return false;
        seen.add(tk.symbol);
        return true;
      });
      setTokens(uniqueTokens);

      const symbols = uniqueTokens.map(tk => tk.symbol);
      const revEntries = await Promise.all(
        symbols.map(s => paymentService.getTotalRevenue(s))
      );
      const revMap: Record<string, bigint> = {};
      symbols.forEach((s, i) => { revMap[s] = revEntries[i]; });
      setRevenues(revMap);

      // Balances via RPC
      const balMap: Record<string, string> = {};
      for (const tk of t) {
        try {
          const client = paymentService['getPublicClient']();
          if (tk.symbol === 'ETH') {
            const bal = await client.getBalance({ address: paymentService['contractAddress'] });
            balMap['ETH'] = bal.toString();
          } else if (tk.address && tk.address !== '0x0000000000000000000000000000000000000000') {
            const ERC20_BAL_ABI = [{ type: 'function', name: 'balanceOf', inputs: [{ type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' }] as const;
            const bal = await client.readContract({
              address: tk.address as `0x${string}`,
              abi: ERC20_BAL_ABI,
              functionName: 'balanceOf',
              args: [paymentService['contractAddress']],
            });
            balMap[tk.symbol] = (bal as bigint).toString();
          }
        } catch { /* skip */ }
      }
      setContractBalance(balMap);
      setTotalUploads(uploads);
      setTokens(t);
    } catch (e) {
      console.warn('Failed to load contract state:', e);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { refresh(); }, [refresh]);

  // ── Connect wallet ──
  async function handleConnect() {
    setConnecting(true);
    setTxStatus(null);
    try {
      const result = await connectWallet();
      const prov = getInjectedProvider();
      setAddress(result.address);
      setProvider(prov);
      if (result.chainId !== 270) {
        setWrongChain(true);
        const switched = await switchToChain270(prov || undefined);
        if (switched) setWrongChain(false);
      }
      if (window.maosv6) setWalletType('MAOS Wallet');
      else if (window.ethereum?.isRabby) setWalletType('Rabby');
      else if (window.ethereum?.isMetaMask) setWalletType('MetaMask');
      else setWalletType('Wallet');
    } catch (e: any) {
      setTxStatus({ ok: false, msg: e.message || 'Connect failed' });
    } finally {
      setConnecting(false);
    }
  }

  // ── Admin action helper ──
  async function doTx(label: string, fn: () => Promise<string>) {
    if (!provider) return;
    setTxStatus(null);
    try {
      const hash = await fn();
      setTxStatus({ ok: true, msg: `${label} success: ${hash.slice(0, 10)}...` });
      await refresh();
    } catch (e: any) {
      setTxStatus({ ok: false, msg: `${label} failed: ${e.message || e}` });
    }
  }

  // ── Form state ──
  const [priceInput, setPriceInput] = useState('');
  const [freeInput, setFreeInput] = useState('');
  const [tierBalance, setTierBalance] = useState('');
  const [tierBps, setTierBps] = useState('');
  const [tierRemoveIdx, setTierRemoveIdx] = useState<number>(-1);
  const [tokenSymbol, setTokenSymbol] = useState('');
  const [tokenAddr, setTokenAddr] = useState('');
  const [tokenDec, setTokenDec] = useState('18');
  const [tokenWei, setTokenWei] = useState('');
  const [tokenEnabled, setTokenEnabled] = useState(true);

  return (
    <AuthGuard requireAdmin redirectTo="/dashboard">
    <PortalLayout>
      {/* ── Header ── */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-white">Payment Admin</h1>
          <p className="text-sm text-surface-400 mt-1">Manage IPFS Portal payment contract</p>
        </div>
        <div className="flex items-center gap-3">
          {address && (
            <span className="text-xs text-surface-400 flex items-center gap-1.5">
              <span className={`w-1.5 h-1.5 rounded-full ${isOwner ? 'bg-accent-green' : 'bg-surface-500'}`} />
              {isOwner ? 'Owner' : 'Viewer'}
            </span>
          )}
          <button onClick={refresh} disabled={loading} className="p-2 rounded-lg bg-surface-800 hover:bg-surface-700 text-surface-400 transition-colors">
            <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
          </button>
        </div>
      </div>

      {/* ── Connect wallet ── */}
      {!address && (
        <div className="glass rounded-xl p-6 text-center space-y-4">
          <Wallet className="w-8 h-8 text-surface-500 mx-auto" />
          <p className="text-sm text-surface-400">Connect wallet to view admin panel</p>
          <button onClick={handleConnect} disabled={connecting}
            className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-brand-500 hover:bg-brand-400 disabled:opacity-50 text-white text-sm font-medium transition-colors"
          >
            {connecting ? <><Loader2 className="w-4 h-4 animate-spin" /> Connecting...</> : <><Wallet className="w-4 h-4" /> Connect Wallet</>}
          </button>
        </div>
      )}

      {wrongChain && (
        <div className="flex items-center gap-2 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20 text-amber-400 text-sm mb-4">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          Please switch to zkSync Local (chain 270)
        </div>
      )}

      {address && (
        <>
          {/* ── Nav tabs ── */}
          <div className="flex gap-1 mb-6 p-1 rounded-lg bg-surface-800/50 w-fit">
            {(['overview', 'pricing', 'tokens', 'tiers'] as ViewMode[]).map(v => (
              <button key={v} onClick={() => setView(v)}
                className={`px-3 py-1.5 rounded-md text-xs font-medium capitalize transition-colors ${
                  view === v ? 'bg-surface-700 text-white' : 'text-surface-400 hover:text-surface-200'
                }`}
              >
                {v === 'overview' ? 'Overview' : v === 'pricing' ? 'Pricing' : v === 'tokens' ? 'Tokens' : 'Discount Tiers'}
              </button>
            ))}
          </div>

          {/* ── Loading ── */}
          {loading ? (
            <div className="flex items-center gap-2 text-surface-400 text-sm py-12 justify-center">
              <Loader2 className="w-4 h-4 animate-spin" /> Loading contract state...
            </div>
          ) : (
            <>
              {view === 'overview' && (
                <Overview
                  totalUploads={totalUploads}
                  tokens={tokens}
                  revenues={revenues}
                  contractBalance={contractBalance}
                  contractAddress={paymentService['contractAddress']}
                  owner={owner}
                  isOwner={isOwner}
                  address={address}
                  deployed={deployed}
                  onNavigate={(v: string) => setView(v as ViewMode)}
                />
              )}

              {view === 'pricing' && (
                <PricingView
                  basePrice={basePrice}
                  freeTier={freeTier}
                  isOwner={isOwner}
                  tokens={tokens}
                  contractBalance={contractBalance}
                  priceInput={priceInput}
                  setPriceInput={setPriceInput}
                  freeInput={freeInput}
                  setFreeInput={setFreeInput}
                  doTx={doTx}
                  provider={provider}
                  address={address}
                />
              )}

              {view === 'tokens' && (
                <TokensView
                  tokens={tokens}
                  isOwner={isOwner}
                  contractBalance={contractBalance}
                  tokenSymbol={tokenSymbol}
                  setTokenSymbol={setTokenSymbol}
                  tokenAddr={tokenAddr}
                  setTokenAddr={setTokenAddr}
                  tokenDec={tokenDec}
                  setTokenDec={setTokenDec}
                  tokenWei={tokenWei}
                  setTokenWei={setTokenWei}
                  tokenEnabled={tokenEnabled}
                  setTokenEnabled={setTokenEnabled}
                  doTx={doTx}
                  provider={provider}
                  address={address}
                />
              )}

              {view === 'tiers' && (
                <TiersView
                  tiers={tiers}
                  isOwner={isOwner}
                  tierBalance={tierBalance}
                  setTierBalance={setTierBalance}
                  tierBps={tierBps}
                  setTierBps={setTierBps}
                  doTx={doTx}
                  provider={provider}
                />
              )}
            </>
          )}

          {/* ── TX Status ── */}
          {txStatus && (
            <div className={`fixed bottom-6 right-6 flex items-center gap-2 px-4 py-3 rounded-xl shadow-lg text-sm animate-fade-in ${
              txStatus.ok
                ? 'bg-accent-green/10 border border-accent-green/20 text-accent-green'
                : 'bg-accent-rose/10 border border-accent-rose/20 text-accent-rose'
            }`}>
              {txStatus.ok ? <CheckCircle className="w-4 h-4 shrink-0" /> : <XCircle className="w-4 h-4 shrink-0" />}
              {txStatus.msg}
            </div>
          )}
        </>
      )}
    </PortalLayout>
    </AuthGuard>
  );
}
