import React, { useCallback, useEffect, useMemo, useState } from "react";
import {
  AppBar,
  Toolbar,
  Typography,
  Container,
  Box,
  Card,
  CardContent,
  Button,
  Chip,
  TextField,
  Select,
  MenuItem,
  InputLabel,
  FormControl,
  LinearProgress,
  Snackbar,
  Alert,
  Tooltip,
  Tabs,
  Tab,
  Divider,
} from "@mui/material";
import Grid from '@mui/material/GridLegacy';
import {
  BrowserProvider,
  Contract,
  formatUnits,
  parseUnits,
  MaxUint256,
  Eip1193Provider,
  isAddress,
} from "ethers";
import {GOLD_SALE_CONTRACT_ADDRESS, GOLD_RGOLD_TOKEN_ADDRESS, GOLD_SUPPORTED_STABLECOINS, GOLD_ERC20_ABI, GOLD_RGOLD_ABI, GOLD_RGOLD_SALE_ABI } from "../../../const";
import {
  Logout as LogoutIcon,
  ExpandMore as ExpandMoreIcon,
} from "@mui/icons-material";


const ARBITRUM_CHAIN_ID = 42161; // Arbitrum One

const SALE_CONTRACT_ADDRESS = GOLD_SALE_CONTRACT_ADDRESS;
const RGOLD_TOKEN_ADDRESS = GOLD_RGOLD_TOKEN_ADDRESS;


const TOKENS = GOLD_SUPPORTED_STABLECOINS;
type PaymentToken = { symbol: string; address: string; decimals: number };
const PAYMENT_TOKENS: PaymentToken[] = Object.values(TOKENS as Record<string, PaymentToken>);


type TokenKey = keyof typeof TOKENS;

const ERC20_ABI = GOLD_ERC20_ABI

const RGOLD_ABI = GOLD_RGOLD_ABI

const SALE_ABI = GOLD_RGOLD_SALE_ABI
// --------------------
// Types
// --------------------
interface Tranche {
  id: number;
  total: bigint;
  sold: bigint;
  startTime: number; // seconds
  endTime: number;   // seconds
  minPurchase: bigint;
  maxPurchase: bigint;
  perBuyerCap: bigint;
  report: string;
  active: boolean;
}

interface Snack {
  open: boolean;
  msg: string;
  sev: "success" | "error" | "info" | "warning";
}

// Utilities
function fmtToken(value?: bigint, decimals = 18, dp = 4) {
  if (value === undefined) return "-";
  try {
    const s = formatUnits(value, decimals);
    const [i, f = ""] = s.split(".");
    return f ? `${i}.${f.slice(0, dp)}` : i;
  } catch {
    return String(value);
  }
}

  function secs(ts: number) { return new Date(ts * 1000).toLocaleString(); }

  // Address shortener for connection chip
  function shortAddr(addr?: string) {
    if (!addr) return "";
    return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
  }

  function toDec(value?: bigint, decimals = 18, dp = 6) {
    if (value === undefined) return "0";
    try {
      const s = formatUnits(value, decimals);
      const [i, f = ""] = s.split(".");
      const frac = f.slice(0, dp).replace(/0+$/g, "");
      return frac ? `${i}.${frac}` : i;
    } catch { return String(value ?? 0); }
  }

  function extractErrorMessage(err: unknown): string {
    const e: any = err;
    const message =
      e?.reason ||
      e?.data?.message ||
      e?.data?.originalError?.message ||
      e?.error?.message ||
      e?.error?.data?.message ||
      e?.error?.data?.originalError?.message ||
      e?.info?.error?.message ||
      e?.info?.error?.data?.message ||
      e?.shortMessage ||
      e?.message;
    if (typeof message === "string" && message.trim().length > 0) {
      return message;
    }
    try {
      return JSON.stringify(message ?? err);
    } catch {
      return "";
    }
  }

  function humanizeErrorMessage(err: unknown, fallback = "Something went wrong. Please try again.") {
    const raw = extractErrorMessage(err) || "";
    const lower = raw.toLowerCase();

    if (lower.includes("user denied") || lower.includes("user rejected") || lower.includes("action rejected")) {
      return "Transaction cancelled in wallet.";
    }
    if (lower.includes("insufficient funds") || lower.includes("insufficient balance")) {
      return "Insufficient balance to complete this action.";
    }

    const cleaned = raw
      .replace(/execution reverted:?/gi, "")
      .replace(/metamask error:?/gi, "")
      .replace(/error: /gi, "")
      .replace(/(vm exception while processing transaction:)/gi, "")
      .replace(/reverted with the following reason:/gi, "")
      .replace(/\(error=.*$/i, "")
      .trim();

    if (!cleaned) return fallback;

    if (cleaned.length > 160) {
      const sentenceEnd = cleaned.indexOf(". ");
      if (sentenceEnd > 0 && sentenceEnd < 160) {
        return `${cleaned.slice(0, sentenceEnd + 1).trim()}`;
      }
      return `${cleaned.slice(0, 157).trim()}…`;
    }

    return cleaned;
  }

export default function RGoldSaleApp() {
  // --------------------
  // State
  // --------------------
  const [provider, setProvider] = useState<BrowserProvider | null>(null);
  const [account, setAccount] = useState<string>("");
  const [rgold, setRgold] = useState<Contract | null>(null);
  const [sale, setSale] = useState<Contract | null>(null);
  const [tab, setTab] = useState("buy");

  const [price, setPrice] = useState<bigint>();
  const [discountedPrice, setDiscountedPrice] = useState<bigint>();
  const [discountBps, setDiscountBps] = useState<bigint>();

  const [tranches, setTranches] = useState<Tranche[]>([]);
  const [loadingTranches, setLoadingTranches] = useState(false);

  const [buyAmount, setBuyAmount] = useState<string>(""); // RGOLD amount
  const [payToken, setPayToken] = useState<PaymentToken>(PAYMENT_TOKENS[0]);
  const [quote, setQuote] = useState<bigint>();
  const [allowance, setAllowance] = useState<bigint>();
  const [payBalance, setPayBalance] = useState<bigint>();

  const [isAdmin, setIsAdmin] = useState(false);
  const [adminRoles, setAdminRoles] = useState<{ def?: string; mgr?: string }>({});

  const [commissionActive, setCommissionActive] = useState(false);
  const [commissionBpsInput, setCommissionBpsInput] = useState<string>("");
  const [treasuryAddress, setTreasuryAddress] = useState<string>("");

  const [trancheForm, setTrancheForm] = useState({
    totalAmount: "",
    startTime: "",
    endTime: "",
    minPurchase: "",
    maxPurchase: "",
    perBuyerCap: "",
    backingReport: "",
  });

  const [manageTrancheId, setManageTrancheId] = useState<string>("");
  const [manageNewEndTime, setManageNewEndTime] = useState<string>("");
  const [reclaimToAddress, setReclaimToAddress] = useState<string>("");

  const [newTreasury, setNewTreasury] = useState<string>("");
  const [withdrawToken, setWithdrawToken] = useState<string>(PAYMENT_TOKENS[0]?.address ?? "");

  const [snack, setSnack] = useState<Snack>({ open: false, msg: "", sev: "info" });

  // --------------------
  // Init / Connect
  // --------------------
  const connect = useCallback(async () => {
    const eth = (window as any).ethereum as (Eip1193Provider & { request?: (args: { method: string; params?: any[] }) => Promise<any> }) | undefined;
    if (!eth) {
      setSnack({ open: true, msg: "No injected wallet found", sev: "error" });
      return;
    }
    const prov = new BrowserProvider(eth);
    const net = await prov.getNetwork();
    if (Number(net.chainId) != ARBITRUM_CHAIN_ID) {
      try {
        await eth?.request?.({
          method: "wallet_switchEthereumChain",
          params: [{ chainId: "0xA4B1" }], // 42161
        });
      } catch (e: any) {
        setSnack({ open: true, msg: "Please switch to Arbitrum One", sev: "error" });
        return;
      }
    }

    const signer = await prov.getSigner();
    const addr = await signer.getAddress();

    const rg = new Contract(RGOLD_TOKEN_ADDRESS, RGOLD_ABI, prov);
    const sl = new Contract(SALE_CONTRACT_ADDRESS, SALE_ABI, signer);

    setProvider(prov);
    setAccount(addr);
    setRgold(rg);
    setSale(sl);
  }, []);

  const disconnect = useCallback(() => {
    setProvider(null);
    setAccount("");
    setRgold(null);
    setSale(null);
    setTranches([]);
    setAllowance(undefined);
    setQuote(undefined);
  }, []);

  useEffect(() => {
    const eth = (window as any).ethereum;
    if (!eth) return;
    const onAcc = (accs: string[]) => setAccount(accs[0] || "");
    const onChain = () => disconnect();
    eth.on?.("accountsChanged", onAcc);
    eth.on?.("chainChanged", onChain);
    return () => {
      eth?.removeListener?.("accountsChanged", onAcc);
      eth?.removeListener?.("chainChanged", onChain);
    };
  }, [disconnect]);

  // --------------------
  // Loaders
  // --------------------
  const loadPrices = useCallback(async () => {
    if (!rgold) return;
    try {
      // Try v2 style names first
      const [p, dp, bps] = await Promise.all([
        (rgold as any).price?.() ?? (rgold as any).getLatestPriceInUSD?.(),
        (rgold as any).discountedPrice?.() ?? (rgold as any).getDiscountedPriceInUSD?.(),
        (rgold as any).discountBps?.() ?? (rgold as any).discountBPS?.(),
      ]);
      if (!p || !dp || !bps) throw new Error("Price functions unavailable");
      setPrice(p as bigint);
      setDiscountedPrice(dp as bigint);
      setDiscountBps(bps as bigint);
    } catch (e: any) {
      setSnack({ open: true, msg: "Failed to load prices", sev: "error" });
    }
  }, [rgold]);

  const loadTranches = useCallback(async () => {
    if (!sale) return;
    try {
      setLoadingTranches(true);
      const count: bigint = await sale.trancheCount();
      const total = Number(count);
      const now = Math.floor(Date.now() / 1000);
      const list: Tranche[] = [];
      // Align indexing with HTML implementation which uses 1..count
      for (let i = 1; i <= total; i++) {
        const t = await sale.trancheInfo(i);
        const start = Number((t.startTime ?? t[2]) as any);
        const end = Number((t.endTime ?? t[3]) as any);
        const activeByTime = now >= start && now <= end;
        const tr: Tranche = {
          id: i,
          total: (t.total ?? t[0]) as bigint,
          sold: (t.sold ?? t[1]) as bigint,
          startTime: start,
          endTime: end,
          minPurchase: (t.minPurchase ?? t[4]) as bigint,
          maxPurchase: (t.maxPurchase ?? t[5]) as bigint,
          perBuyerCap: (t.perBuyerCap ?? t[6]) as bigint,
          report: String(t.report ?? t[7] ?? ""),
          // Use on-chain active flag (fallback to time) — matches HTML behavior
          active: Boolean((t as any).active ?? (t as any)[8] ?? activeByTime),
        };
        if (tr.endTime > now) list.push(tr); // hide expired
      }
      setTranches(list);
    } catch (e: any) {
      setSnack({ open: true, msg: "Failed to load tranches", sev: "error" });
    } finally { setLoadingTranches(false); }
  }, [sale]);

  const loadAdmin = useCallback(async () => {
    if (!sale || !account) return;
    try {
      const [def, mgr] = await Promise.all([
        sale.DEFAULT_ADMIN_ROLE(),
        sale.SALE_MANAGER_ROLE(),
      ]);
      setAdminRoles({ def, mgr });
      const [isDef, isMgr] = await Promise.all([
        sale.hasRole(def, account),
        sale.hasRole(mgr, account),
      ]);
      const admin = Boolean(isDef || isMgr);
      setIsAdmin(admin);
      if (admin) {
        const [active, treasury] = await Promise.all([
          sale.commissionActive(),
          sale.treasury(),
        ]);
        const commissionBpsFn =
          (sale as any).commissionBps ??
          (sale as any).commissionBPS ??
          (sale as any).commissionbps;
        const bps = typeof commissionBpsFn === "function" ? await commissionBpsFn() : undefined;
        setCommissionActive(Boolean(active));
        if (bps !== undefined) {
          const value = typeof bps === "bigint" ? bps : BigInt(bps ?? 0);
          setCommissionBpsInput(value.toString());
        }
        setTreasuryAddress(String(treasury));
      }
    } catch {}
  }, [sale, account]);

  // Quote for current buy input
  const refreshQuote = useCallback(async () => {
    if (!sale || !buyAmount) { setQuote(undefined); return; }
    try {
      const amt = parseUnits(buyAmount || "0", 18); // RGOLD has 18 decimals
      const q = await sale.getAmountToPay(amt, payToken.address);
      setQuote(q);
    } catch { setQuote(undefined); }
  }, [sale, buyAmount, payToken]);

  // Allowance for payment token
  const refreshAllowance = useCallback(async () => {
    if (!provider || !account || !sale) { setAllowance(undefined); return; }
    try {
      const erc = new Contract(payToken.address, ERC20_ABI, provider);
      const a = await erc.allowance(account, SALE_CONTRACT_ADDRESS);
      setAllowance(a);
    } catch { setAllowance(undefined); }
  }, [provider, account, sale, payToken]);

  const refreshBalance = useCallback(async () => {
    if (!provider || !account) { setPayBalance(undefined); return; }
    try {
      const erc = new Contract(payToken.address, ERC20_ABI, provider);
      const b = await erc.balanceOf(account);
      setPayBalance(b);
    } catch { setPayBalance(undefined); }
  }, [provider, account, payToken]);

  // Effects
  useEffect(() => { if (rgold) loadPrices(); }, [rgold, loadPrices]);
  useEffect(() => { if (sale) loadTranches(); }, [sale, loadTranches]);
  useEffect(() => { if (sale && account) loadAdmin(); }, [sale, account, loadAdmin]);
  useEffect(() => { refreshQuote(); }, [buyAmount, payToken, refreshQuote]);
  useEffect(() => { refreshAllowance(); }, [payToken, provider, sale, account, refreshAllowance]);
  useEffect(() => { refreshBalance(); }, [payToken, provider, account, refreshBalance]);

  const activeTranche = useMemo(() => tranches.find(t => t.active), [tranches]);

  useEffect(() => {
    if (!isAdmin && tab === "admin") {
      setTab("buy");
    }
  }, [isAdmin, tab]);

  const approveIfNeeded = useCallback(async (rgoldAmount: bigint) => {
    if (!provider || !sale || !account) return;
    try {
      const signer = await provider.getSigner();
      const ercRO = new Contract(payToken.address, ERC20_ABI, provider);
      const erc = new Contract(payToken.address, ERC20_ABI, signer);

      // Compute exact payment required now
      const need: bigint = await sale.getAmountToPay(rgoldAmount, payToken.address);

      // Fetch current allowance if state is stale/undefined
      const current: bigint =
        allowance !== undefined ? allowance : await ercRO.allowance(account, SALE_CONTRACT_ADDRESS);

      if (current >= need) return;

      const tx = await erc.approve(SALE_CONTRACT_ADDRESS, MaxUint256);
      await tx.wait();
      setSnack({ open: true, msg: `Approved ${payToken.symbol}`, sev: "success" });
      refreshAllowance();
    } catch (e: any) {
      console.error("Approval error:", e);
      setSnack({ open: true, msg: humanizeErrorMessage(e, "Approval failed. Please try again."), sev: "error" });
    }
  }, [provider, sale, account, payToken, allowance, refreshAllowance]);

  const buy = useCallback(async () => {
    if (!sale || !activeTranche || !provider || !account) return;
    try {
      const amt = parseUnits(buyAmount || "0", 18);
      if (amt <= BigInt(0)) { setSnack({ open: true, msg: "Enter amount > 0", sev: "warning" }); return; }

      // Client-side checks against tranche limits
      if (amt < activeTranche.minPurchase || amt > activeTranche.maxPurchase) {
        setSnack({ open: true, msg: "Amount outside tranche min/max", sev: "error" });
        return;
      }
      // Ensure sufficient stablecoin balance before prompting wallet
      const need: bigint = await sale.getAmountToPay(amt, payToken.address);
      const ercRO = new Contract(payToken.address, ERC20_ABI, provider);
      const bal: bigint = await ercRO.balanceOf(account);
      if (bal < need) {
        setSnack({ open: true, msg: `Insufficient ${payToken.symbol} balance`, sev: "error" });
        return;
      }
      // Auto-approve like the HTML flow
      await approveIfNeeded(amt);
      const tx = await sale.buyTokens(activeTranche.id, amt, payToken.address);
      await tx.wait();
      setSnack({ open: true, msg: "Purchase successful", sev: "success" });
      setBuyAmount("");
      loadTranches();
    } catch (e: any) {
      console.error("Purchase error:", e);
      setSnack({ open: true, msg: humanizeErrorMessage(e, "Purchase failed. Please try again."), sev: "error" });
    }
  }, [sale, activeTranche, buyAmount, payToken, approveIfNeeded, loadTranches]);

  const runTx = useCallback(
    async (promise: Promise<any>, successMessage: string, refresh?: () => void) => {
      setSnack({ open: true, msg: "Please confirm the transaction in your wallet...", sev: "info" });
      try {
        const tx = await promise;
        setSnack({ open: true, msg: "Transaction submitted, awaiting confirmation...", sev: "info" });
        await tx.wait();
        setSnack({ open: true, msg: successMessage, sev: "success" });
        refresh?.();
      } catch (e: any) {
        console.error("Transaction error:", e);
        const message = humanizeErrorMessage(e, "Transaction failed. Please try again.");
        setSnack({ open: true, msg: message, sev: "error" });
        throw e;
      }
    },
    []
  );

  const parseDateToSeconds = (value: string) => {
    if (!value) return 0;
    const ms = Date.parse(value);
    return Number.isNaN(ms) ? 0 : Math.floor(ms / 1000);
  };

  const createTranche = useCallback(async () => {
    if (!sale) return;
    const { totalAmount, startTime, endTime, minPurchase, maxPurchase, perBuyerCap, backingReport } = trancheForm;
    if (!totalAmount || !startTime || !endTime || !minPurchase || !maxPurchase || !perBuyerCap || !backingReport) {
      setSnack({ open: true, msg: "All fields are required to create a tranche.", sev: "error" });
      return;
    }
    const start = parseDateToSeconds(startTime);
    const end = parseDateToSeconds(endTime);
    if (start === 0 || end === 0 || end <= start) {
      setSnack({ open: true, msg: "Invalid start or end time.", sev: "error" });
      return;
    }
    try {
      const total = parseUnits(totalAmount, 18);
      const perBuyer = parseUnits(perBuyerCap, 18);
      const min = parseUnits(minPurchase, 18);
      const max = parseUnits(maxPurchase, 18);

      if (min <= BigInt(0) || max <= BigInt(0) || perBuyer <= BigInt(0) || total <= BigInt(0)) {
        setSnack({ open: true, msg: "All numerical values must be greater than zero.", sev: "error" });
        return;
      }
      if (min > max) {
        setSnack({ open: true, msg: "Minimum purchase cannot exceed maximum purchase.", sev: "error" });
        return;
      }
      if (max > perBuyer) {
        setSnack({ open: true, msg: "Maximum purchase cannot exceed per-buyer cap.", sev: "error" });
        return;
      }
      if (perBuyer > total) {
        setSnack({ open: true, msg: "Per-buyer cap cannot exceed total amount.", sev: "error" });
        return;
      }

      await runTx(
        sale.createTranche(total, start, end, min, max, perBuyer, backingReport),
        "Tranche created successfully!",
        () => {
          loadTranches();
          setTrancheForm({
            totalAmount: "",
            startTime: "",
            endTime: "",
            minPurchase: "",
            maxPurchase: "",
            perBuyerCap: "",
            backingReport: "",
          });
        }
      );
    } catch (e) {
      // runTx already surfaces the error
    }
  }, [sale, trancheForm, runTx, loadTranches]);

  const updateTrancheEndTime = useCallback(async () => {
    if (!sale) return;
    if (!manageTrancheId || !manageNewEndTime) {
      setSnack({ open: true, msg: "Tranche ID and new end time are required.", sev: "error" });
      return;
    }
    const trancheId = Number(manageTrancheId);
    if (!Number.isInteger(trancheId) || trancheId <= 0) {
      setSnack({ open: true, msg: "Enter a valid tranche ID.", sev: "error" });
      return;
    }
    const newEnd = parseDateToSeconds(manageNewEndTime);
    if (!newEnd) {
      setSnack({ open: true, msg: "Enter a valid new end time.", sev: "error" });
      return;
    }
    try {
      await runTx(
        sale.updateTrancheEndTime(trancheId, newEnd),
        "Tranche end time updated!",
        () => {
          loadTranches();
          setManageNewEndTime("");
        }
      );
    } catch (e) {}
  }, [sale, manageTrancheId, manageNewEndTime, runTx, loadTranches]);

  const reclaimUnsold = useCallback(async () => {
    if (!sale) return;
    if (!manageTrancheId || !reclaimToAddress) {
      setSnack({ open: true, msg: "Tranche ID and reclaim address are required.", sev: "error" });
      return;
    }
    const trancheId = Number(manageTrancheId);
    if (!Number.isInteger(trancheId) || trancheId <= 0) {
      setSnack({ open: true, msg: "Enter a valid tranche ID.", sev: "error" });
      return;
    }
    if (!isAddress(reclaimToAddress)) {
      setSnack({ open: true, msg: "Enter a valid Ethereum address.", sev: "error" });
      return;
    }
    try {
      await runTx(
        sale.reclaimUnsold(trancheId, reclaimToAddress),
        "Unsold tokens reclaimed!",
        () => {
          loadTranches();
          setReclaimToAddress("");
        }
      );
    } catch (e) {}
  }, [sale, manageTrancheId, reclaimToAddress, runTx, loadTranches]);

  const setCommissionBps = useCallback(async () => {
    if (!sale) return;
    const value = commissionBpsInput.trim();
    if (!value) {
      setSnack({ open: true, msg: "Commission BPS is required.", sev: "error" });
      return;
    }
    const num = Number(value);
    if (!Number.isFinite(num) || num < 0) {
      setSnack({ open: true, msg: "Commission BPS must be zero or positive.", sev: "error" });
      return;
    }
    try {
      await runTx(
        sale.setCommissionBps(BigInt(Math.floor(num))),
        "Commission updated!",
        () => loadAdmin()
      );
    } catch (e) {}
  }, [sale, commissionBpsInput, runTx, loadAdmin]);

  const toggleCommission = useCallback(async () => {
    if (!sale) return;
    try {
      const next = !commissionActive;
      await runTx(
        sale.toggleCommission(next),
        `Commission is now ${next ? "ACTIVE" : "INACTIVE"}.`,
        () => {
          setCommissionActive(() => next);
        }
      );
    } catch (e) {}
  }, [sale, commissionActive, runTx]);

  const setTreasury = useCallback(async () => {
    if (!sale) return;
    if (!newTreasury || !isAddress(newTreasury)) {
      setSnack({ open: true, msg: "Enter a valid treasury address.", sev: "error" });
      return;
    }
    try {
      await runTx(
        sale.setTreasury(newTreasury),
        "Treasury address updated!",
        () => {
          setTreasuryAddress(newTreasury);
          setNewTreasury("");
        }
      );
    } catch (e) {}
  }, [sale, newTreasury, runTx]);

  const withdrawFunds = useCallback(async () => {
    if (!sale) return;
    if (!withdrawToken || !isAddress(withdrawToken)) {
      setSnack({ open: true, msg: "Select a valid token to withdraw.", sev: "error" });
      return;
    }
    try {
      await runTx(
        sale.withdrawFunds(withdrawToken),
        "Withdrawal transaction sent!"
      );
    } catch (e) {}
  }, [sale, withdrawToken, runTx]);

  // --------------------
  // Render helpers
  // --------------------
  function Stat({ label, value }: { label: string; value: string }) {
    return (
      <Box sx={{ display: "flex", alignItems: "center", gap: 1, minWidth: 240, flex: "1 1 240px" }}>
        <Typography variant="body2" color="text.secondary">{label}:</Typography>
        <Typography variant="body2" fontWeight={600}>{value}</Typography>
      </Box>
    );
  }

  function TrancheCard({ t }: { t: Tranche }) {
    const pct = Number((t.sold * BigInt(100)) / (t.total || BigInt(1)));
    return (
      <Card variant="outlined" sx={{ mb: 2 }}>
        <CardContent>
          <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1, gap: 2, flexWrap: "wrap" }}>
            <Typography variant="h6">Tranche #{t.id}</Typography>
            <Chip label={t.active ? "Active" : "Upcoming"} color={t.active ? "success" : "default"} />
          </Box>

          <Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
            <Stat label="Start" value={secs(t.startTime)} />
            <Stat label="End" value={secs(t.endTime)} />
            <Stat label="Min" value={`${fmtToken(t.minPurchase)} RGOLD`} />
            <Stat label="Max" value={`${fmtToken(t.maxPurchase)} RGOLD`} />
            <Stat label="Per-buyer Cap" value={`${fmtToken(t.perBuyerCap)} RGOLD`} />
            <Stat label="Sold" value={`${fmtToken(t.sold)} RGOLD`} />
            <Stat label="Total" value={`${fmtToken(t.total)} RGOLD`} />
          </Box>

          <Box sx={{ mt: 2 }}>
            <LinearProgress variant="determinate" value={pct} />
            <Typography variant="caption">{pct}% sold</Typography>
          </Box>

          {t.report && (
            <Typography variant="body2" sx={{ mt: 1 }} color="text.secondary">{t.report}</Typography>
          )}
        </CardContent>
      </Card>
    );
  }

  return (
    <Box>
    <AppBar position="static" color="transparent" elevation={0} >
  <Toolbar sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
    
    {/* Left content */}
    <Box sx={{ textAlign: "left", mt:1 }}>
      <Typography variant="h4" fontWeight={700}>
        RGOLD Token Sale
      </Typography>
      <Typography variant="subtitle1" color="text.secondary" sx={{ mt: 1 }}>
        Acquire asset-backed gold tokens from professionally managed sales.
      </Typography>
    </Box>

    {/* Right content */}
    <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
      {account && (
        <Chip
          label={`Connected: ${shortAddr(account)}`}
          color="success"
          variant="outlined"
          size="small"
        />
      )}
      {account ? (
        <Button variant="outlined" onClick={disconnect} startIcon={<LogoutIcon />} sx={{
                bgcolor: "#0b3d91",
                textTransform: "none",
                fontSize: 14,
                color: "#FFFFFF",
                "&:hover": { bgcolor: "#083475" },
              }}>
          Disconnect
        </Button>
      ) : (
        <Button variant="contained" onClick={connect} sx={{
                bgcolor: "#0b3d91",
                textTransform: "none",
                fontSize: 14,
                color: "#FFFFFF",
                "&:hover": { bgcolor: "#083475" },
              }}>
          Connect Wallet
        </Button>
      )}
    </Box>

  </Toolbar>
</AppBar>


      <Container sx={{ mt: 3 }}>
        {!account && (
          <Alert sx={{ mt: 1 }} severity="warning">Connect your wallet to view pricing and participate in the sale.</Alert>
        )}

        {account && (
          <>
            {/* Pricing summary card */}
            <Card variant="outlined" sx={{ mb: 3 }}>
              <CardContent>
                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
                  <Box sx={{ flex: '1 1 260px', minWidth: 260 }}>
                    <Typography variant="caption" color="text.secondary">Live Gold Spot Price</Typography>
                    <Typography variant="h4" fontWeight={700}>{`$${fmtToken(price, 18, 2)}`}</Typography>
                  </Box>
                  <Box sx={{ flex: '1 1 260px', minWidth: 260 }}>
                    <Typography variant="caption" color="text.secondary">Your Discounted Price</Typography>
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
                      <Typography variant="h4" fontWeight={700} color="success.main">{`$${fmtToken(discountedPrice, 18, 3)}`}</Typography>
                      <Chip size="small" label={`${(Number((discountBps ?? BigInt(0)).toString())/100).toFixed(0)}% Discount`} color="success" variant="filled" />
                    </Box>
                  </Box>
                </Box>
              </CardContent>
            </Card>

            {loadingTranches && <LinearProgress sx={{ mb: 2 }} />}

            <Card variant="outlined" sx={{ mb: 2 }}>
              <CardContent>
                <Tabs
                  value={tab}
                  onChange={(_, value) => setTab(value)}
                  textColor="primary"
                  indicatorColor="primary"
                  sx={{ mb: 2 }}
                >
                  <Tab label="Public Sale" value="buy" />
                  {isAdmin && (<Tab label="Admin Panel" value="admin" />)}
                </Tabs>

                {tab === "buy" && (
                  <>
                    {tranches.length ? (
                      <TrancheCard t={activeTranche ?? tranches[0]} />
                    ) : (
                      <Alert severity="info">No active or upcoming sales at this time.</Alert>
                    )}

                    <Typography variant="subtitle1" sx={{ mt: 2, mb: 1, fontWeight: 700 }}>Amount to Buy (RGOLD)</Typography>
                    <Box sx={{ display: "flex", flexWrap: "wrap", gap: 2 }}>
                      <Box sx={{ flex: "1 1 260px", minWidth: 260 }}>
                        <TextField
                          placeholder="0.0"
                          fullWidth
                          value={buyAmount}
                          onChange={(e) => setBuyAmount(e.target.value)}
                          disabled={!account || !activeTranche}
                        />
                      </Box>

                      <Box sx={{ flex: "1 1 260px", minWidth: 260 }}>
                        <FormControl fullWidth>
                          <InputLabel>Pay with</InputLabel>
                          <Select
                            label="Pay with"
                            value={payToken.symbol}
                            onChange={(e) => {
                              const t = PAYMENT_TOKENS.find(x => x.symbol === e.target.value);
                              if (t) setPayToken(t);
                            }}
                            disabled={!account}
                          >
                            {PAYMENT_TOKENS.map((t) => (
                              <MenuItem key={t.symbol} value={t.symbol}>{t.symbol}</MenuItem>
                            ))}
                          </Select>
                        </FormControl>
                        {account && (
                          <Typography variant="caption" color="text.secondary" sx={{ mt: 0.5, display: 'block' }}>
                            Balance: {fmtToken(payBalance, payToken.decimals)} {payToken.symbol}
                          </Typography>
                        )}
                      </Box>

                      <Box sx={{ flex: "1 1 260px", minWidth: 260 }}>
                        <TextField
                          label="Estimated Cost"
                          fullWidth
                          value={quote ? `${fmtToken(quote, payToken.decimals)} ${payToken.symbol}` : "-"}
                          disabled
                        />
                      </Box>

                      <Box sx={{ flex: "1 1 100%", display: "flex", gap: 1, justifyContent: "flex-end", mt: 1 }}>
                        <Button variant="contained" onClick={buy} disabled={!activeTranche || !account}>Buy RGOLD</Button>
                      </Box>
                    </Box>
                  </>
                )}

                {tab === "admin" && (
                  <Box>
                    <Typography variant="h5" sx={{ fontWeight: 700, mb: 2 }}>
                      Sale &amp; Platform Management
                    </Typography>
                    <Grid container spacing={3}>
                      <Grid item xs={12} lg={6}>
                        <Card variant="outlined">
                          <CardContent>
                            <Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
                              Create New Tranche
                            </Typography>
                            <Grid container spacing={2}>
                              <Grid item xs={12} sm={6}>
                                <TextField
                                  label="Total RGOLD Supply"
                                  placeholder="10000"
                                  type="number"
                                  value={trancheForm.totalAmount}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, totalAmount: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12} sm={6}>
                                <TextField
                                  label="Per Buyer Cap"
                                  placeholder="500"
                                  type="number"
                                  value={trancheForm.perBuyerCap}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, perBuyerCap: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12} sm={6}>
                                <TextField
                                  label="Min Purchase"
                                  placeholder="1"
                                  type="number"
                                  value={trancheForm.minPurchase}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, minPurchase: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12} sm={6}>
                                <TextField
                                  label="Max Purchase"
                                  placeholder="100"
                                  type="number"
                                  value={trancheForm.maxPurchase}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, maxPurchase: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12}>
                                <TextField
                                  label="Start Time"
                                  type="datetime-local"
                                  InputLabelProps={{ shrink: true }}
                                  value={trancheForm.startTime}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, startTime: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12}>
                                <TextField
                                  label="End Time"
                                  type="datetime-local"
                                  InputLabelProps={{ shrink: true }}
                                  value={trancheForm.endTime}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, endTime: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                              <Grid item xs={12}>
                                <TextField
                                  label="Backing Report Reference"
                                  placeholder="SGS NI 43-101 Report..."
                                  value={trancheForm.backingReport}
                                  onChange={(e) => setTrancheForm((f) => ({ ...f, backingReport: e.target.value }))}
                                  fullWidth
                                />
                              </Grid>
                            </Grid>
                            <Button sx={{ mt: 3 }} variant="contained" onClick={createTranche} fullWidth>
                              Create Tranche
                            </Button>
                          </CardContent>
                        </Card>
                      </Grid>

                      <Grid item xs={12} lg={6}>
                        <Box sx={{ display: "flex", flexDirection: "column", gap: 3, height: "100%" }}>
                          <Card variant="outlined">
                            <CardContent>
                              <Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
                                Manage Tranche
                              </Typography>
                              <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
                                <TextField
                                  label="Tranche ID"
                                  placeholder="1"
                                  type="number"
                                  value={manageTrancheId}
                                  onChange={(e) => setManageTrancheId(e.target.value)}
                                  fullWidth
                                />
                                <TextField
                                  label="New End Time"
                                  type="datetime-local"
                                  InputLabelProps={{ shrink: true }}
                                  value={manageNewEndTime}
                                  onChange={(e) => setManageNewEndTime(e.target.value)}
                                  fullWidth
                                />
                                <Button variant="outlined" onClick={updateTrancheEndTime}>
                                  Set End Time
                                </Button>
                                <Divider sx={{ my: 1 }} />
                                <TextField
                                  label="Reclaim To Address"
                                  placeholder="0x..."
                                  value={reclaimToAddress}
                                  onChange={(e) => setReclaimToAddress(e.target.value)}
                                  fullWidth
                                />
                                <Button variant="outlined" onClick={reclaimUnsold}>
                                  Reclaim Unsold Tokens
                                </Button>
                              </Box>
                            </CardContent>
                          </Card>

                          <Card variant="outlined">
                            <CardContent>
                              <Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
                                Treasury &amp; Fees
                              </Typography>
                              <TextField
                                label="Commission (BPS)"
                                placeholder="e.g., 150 for 1.5%"
                                type="number"
                                value={commissionBpsInput}
                                onChange={(e) => setCommissionBpsInput(e.target.value)}
                                fullWidth
                              />
                              <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mt: 2 }}>
                                <Button variant="contained" onClick={setCommissionBps}>
                                  Set Commission
                                </Button>
                                <Button variant="outlined" onClick={toggleCommission}>
                                  {commissionActive ? "Deactivate Commission" : "Activate Commission"}
                                </Button>
                              </Box>
                            </CardContent>
                          </Card>

                          <Card variant="outlined" sx={{ mt: "auto" }}>
                            <CardContent>
                              <Typography variant="h6" sx={{ fontWeight: 700, mb: 2 }}>
                                Withdraw Funds
                              </Typography>
                              <Typography variant="body2" color="text.secondary">
                                Current Treasury:
                              </Typography>
                              <Typography variant="body2" sx={{ fontWeight: 600, wordBreak: "break-all", mb: 2 }}>
                                {treasuryAddress || "-"}
                              </Typography>
                              <TextField
                                label="New Treasury Address"
                                placeholder="0x... (New Treasury Address)"
                                value={newTreasury}
                                onChange={(e) => setNewTreasury(e.target.value)}
                                fullWidth
                              />
                              <Button sx={{ mt: 2 }} variant="outlined" onClick={setTreasury}>
                                Set Treasury Address
                              </Button>
                              <Divider sx={{ my: 2 }} />
                              <FormControl fullWidth>
                                <InputLabel>Token to Withdraw</InputLabel>
                                <Select
                                  label="Token to Withdraw"
                                  value={withdrawToken}
                                  onChange={(e) => setWithdrawToken(e.target.value)}
                                >
                                  {PAYMENT_TOKENS.map((t) => (
                                    <MenuItem key={t.address} value={t.address}>{t.symbol}</MenuItem>
                                  ))}
                                </Select>
                              </FormControl>
                              <Button sx={{ mt: 2 }} color="error" variant="contained" onClick={withdrawFunds}>
                                Withdraw All Funds
                              </Button>
                            </CardContent>
                          </Card>
                        </Box>
                      </Grid>
                    </Grid>
                  </Box>
                )}
              </CardContent>
            </Card>
          </>
        )}

        {account && !activeTranche && (
          <Alert sx={{ mt: 2 }} severity="info">No active tranche at the moment.</Alert>
        )}

        {isAdmin && ( 
          <Tooltip title="Role IDs loaded from contract">
            <Box sx={{ mt: 2 }}>
              <Typography variant="caption">DEFAULT_ADMIN_ROLE: {adminRoles.def}</Typography><br/>
              <Typography variant="caption">SALE_MANAGER_ROLE: {adminRoles.mgr}</Typography>
            </Box>
          </Tooltip>
        )}
      </Container>

      <Snackbar
        open={snack.open}
        onClose={() => setSnack((s) => ({ ...s, open: false }))}
        autoHideDuration={6000}
        anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
      >
        <Alert onClose={() => setSnack((s) => ({ ...s, open: false }))} severity={snack.sev} sx={{ width: "100%" }}>
          {snack.msg}
        </Alert>
      </Snackbar>
    </Box>
  );
}
