import React, {
  useState,
  useEffect,
  useRef,
  useCallback,
  ChangeEvent,
  useMemo,
} from "react";
import {
  ethers,
  BrowserProvider,
  JsonRpcSigner,
  Contract,
  MaxUint256,
  ZeroAddress,
  Eip1193Provider,
} from "ethers";
import Chart from "chart.js/auto";
import { SelectChangeEvent } from "@mui/material/Select";
import {
  Box,
  Typography,
  Paper,
  Button,
  CircularProgress,
  Snackbar,
  Alert,
  TextField,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Chip,
  Tabs,
  Tab,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  Collapse,
  IconButton,
  Tooltip,
  FormHelperText,
  Divider,
  Checkbox,
  FormControlLabel,
} from "@mui/material";
import Slider from "@mui/material/Slider";
import { useTheme } from "@mui/material/styles";
import {
  Logout as LogoutIcon,
  ExpandMore as ExpandMoreIcon,
} from "@mui/icons-material";
import TaskAltIcon from "@mui/icons-material/TaskAlt";
import { useQuery } from "@apollo/client";
import { GET_CUSTOMER_ID } from "../../../graphql/query";
import ConfirmCloseDialog from "../../../components/ConfirmCloseDialog";

const ADDRESS_ZERO = ethers.ZeroAddress;

// Gnosis network constants
const RFQ_CONTRACT_ADDRESS = "0x40102552c03013A4bbF89354b873BcFC4320F26e";
const IGLD_TOKEN_ADDRESS = "0x0B55a55781312C8048324b1f1a3D910c09e07bb8";
const IUSD_TOKEN_ADDRESS = "0x3C93E9d400A4b4527524D9d8f0e6924ad58048CB";
const RFQ_ABI = [{"inputs":[{"internalType":"address","name":"_igld","type":"address"},{"internalType":"address","name":"_iusd","type":"address"},{"internalType":"address","name":"_spotAggregator","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_treasuryFeeBPS","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"string","name":"setting","type":"string"},{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"AdminAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"string","name":"setting","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"AdminSettingsChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":false,"internalType":"bool","name":"isNowKeeper","type":"bool"}],"name":"KeeperUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"pnlValue","type":"int256"},{"indexed":false,"internalType":"address","name":"payoutToken","type":"address"}],"name":"PositionClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"positionId","type":"uint256"},{"indexed":false,"internalType":"enum IntelliTraderGoldFuturesProRFQ_V4.PositionType","name":"pType","type":"uint8"},{"components":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"entryPrice","type":"uint256"},{"internalType":"uint256","name":"amountIGLD","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"indexed":false,"internalType":"struct IntelliTraderGoldFuturesProRFQ_V4.Leg[]","name":"legs","type":"tuple[]"}],"name":"PositionOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"IGLD_TOKEN","outputs":[{"internalType":"contract IIntelliGoldToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IUSD_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"annualRateBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"address","name":"payoutToken","type":"address"}],"name":"closePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"positionId","type":"uint256"}],"name":"getPositionById","outputs":[{"components":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"purchaseTimestamp","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint256","name":"closeTimestamp","type":"uint256"},{"internalType":"enum IntelliTraderGoldFuturesProRFQ_V4.PositionType","name":"positionType","type":"uint8"},{"internalType":"uint256","name":"stopLossPrice","type":"uint256"},{"internalType":"uint256","name":"takeProfitPrice","type":"uint256"},{"components":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"entryPrice","type":"uint256"},{"internalType":"uint256","name":"amountIGLD","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"internalType":"struct IntelliTraderGoldFuturesProRFQ_V4.Leg[]","name":"legs","type":"tuple[]"}],"internalType":"struct IntelliTraderGoldFuturesProRFQ_V4.Position","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isKeeper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manualSpotPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMaturityOffset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minMaturityOffset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nextPositionIdForUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"maxCost","type":"uint256"}],"name":"openPositionWithIUSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"sl","type":"uint256"},{"internalType":"uint256","name":"tp","type":"uint256"},{"internalType":"uint256","name":"maxCost","type":"uint256"}],"name":"openPositionWithXDAI","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"maturity","type":"uint256"},{"internalType":"uint256","name":"amountIGLD","type":"uint256"},{"internalType":"bool","name":"isLong","type":"bool"}],"internalType":"struct IntelliTraderGoldFuturesProRFQ_V4.InputLeg[]","name":"inputLegs","type":"tuple[]"},{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"uint256","name":"maxCost","type":"uint256"},{"internalType":"uint256","name":"minCredit","type":"uint256"}],"name":"openSpreadPosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"oracleMaxAge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maturity","type":"uint256"}],"name":"priceFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"a","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"r","type":"uint256"}],"name":"setAnnualRateBPS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"k","type":"address"},{"internalType":"bool","name":"s","type":"bool"}],"name":"setKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"p","type":"uint256"}],"name":"setManualPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"setMaturityOffsets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"}],"name":"setOracleMaxAge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IntelliTraderGoldFuturesProRFQ_V4.PriceSource","name":"s","type":"uint8"}],"name":"setPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"t","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"f","type":"uint256"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spotAggregator","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"spotSource","outputs":[{"internalType":"enum IntelliTraderGoldFuturesProRFQ_V4.PriceSource","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFeeBPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"posId","type":"uint256"},{"internalType":"address","name":"payoutToken","type":"address"}],"name":"triggerCloseByKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userPositions","outputs":[{"internalType":"uint256","name":"positionId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"purchaseTimestamp","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"uint256","name":"closeTimestamp","type":"uint256"},{"internalType":"enum IntelliTraderGoldFuturesProRFQ_V4.PositionType","name":"positionType","type":"uint8"},{"internalType":"uint256","name":"stopLossPrice","type":"uint256"},{"internalType":"uint256","name":"takeProfitPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}];

const IGLD_ABI = [{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldMinter","type":"address"},{"indexed":true,"internalType":"address","name":"newMinter","type":"address"}],"name":"MinterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newMinter","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}];
const IUSD_ABI=  [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}];
interface Leg {
  maturity: string;
  amountIGLD: number;
  isLong: boolean;
  entryPrice: number;
}

interface Position {
  positionId: string;
  positionType: string;
  legs: Leg[];
  longAmount: number;
  stopLossPrice: number;
  takeProfitPrice: number;
  pnl: number;
}

interface PortfolioState {
  positions: Position[];
  totalValue: number;
  pnl: number;
  activePositions: number;
  spotPrice: number;
  isLoading: boolean;
}

interface OutrightTrade {
  maturity: string;
  amount: string;
  sl: string;
  tp: string;
  paymentToken: string;
  maxCost: string;
  slippagePercent: string;
}

interface SpreadLeg {
  maturity: string;
  amountIGLD: string;
  isLong: boolean;
}

interface SpreadTrade {
  legs: SpreadLeg[];
  paymentToken: string;
  maxCost: string;
  minCredit: string;
  slippagePercent: string;
  impliedVolatility: string;
  ivEnabled: boolean;
}

interface TradeState {
  outright: OutrightTrade;
  spread: SpreadTrade;
}

interface SpreadQuoteState {
  isCalculating: boolean;
  netCost: bigint | null;
  displayCost: string;
  error: string | null;
}

interface AdminState {
  manualSpotPrice: string;
  keeperAddress: string;
  annualRate: string;
  oracleMaxAge: string;
}

interface AnalysisState {
  startDate: string;
  endDate: string;
  results:
    | {
        priceSpread: number;
        basisPoints: number;
        annualizedYield: number;
        startEndPrice: string;
      }
    | null
    | "loading";
}

interface StatusState {
  type: "disconnected" | "error" | "connected";
  message: string;
}

interface ToastState {
  visible: boolean;
  message: string;
  type: "info" | "success" | "error" | "warning";
}

// Utility functions
const formatCurrency = (value: number, decimals: number = 2): string => {
  if (isNaN(value) || !isFinite(value)) return "$0.00";
  return `$${value.toFixed(decimals)}`;
};

const formatPnlWithSign = (pnl: number): string => {
  if (isNaN(pnl)) return "+$0.00";
  const sign = pnl >= 0 ? "+" : "-";
  const formatted = Math.abs(pnl).toLocaleString("en-GB", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
  return `${sign}$${formatted}`;
};

const getPnlColor = (value: number) =>
  value >= 0 ? "#10B981" : "#EF4444";

const formatSLTP = (price: number, type: string): string => {
  if (price > 0) return `${type}: ${formatCurrency(price)}`;
  return `${type}: --`;
};

const renderPositionTypeChip = (type: string) => {
  const label = type || "Unknown";
  const isOutright = label.toLowerCase() === "outright";
  return (
    <Chip
      label={label}
      size="small"
      aria-label={`Position type: ${label}`}
      sx={{
        borderRadius: "999px",
        fontWeight: 600,
        bgcolor: isOutright
          ? "rgba(96, 165, 250, 0.2)"
          : "rgba(196, 181, 253, 0.25)",
        color: isOutright ? "#1D4ED8" : "#7C3AED",
      }}
    />
  );
};

const shortenAddress = (address: string): string => {
  if (!address) return "";
  return `${address.slice(0, 8)}...${address.slice(-5)}`;
};

// Extract a concise error message (aligns with gold.html behavior)
const extractErrorMessage = (err: any): string => {
  try {
    if (!err) return "An unknown error occurred.";
    const msg =
      err?.reason ||
      err?.data?.message ||
      err?.data?.originalError?.message ||
      err?.error?.message ||
      err?.error?.data?.message ||
      err?.error?.data?.originalError?.message ||
      err?.info?.error?.message ||
      err?.info?.error?.data?.message ||
      err?.info?.error?.data?.originalError?.message ||
      err?.shortMessage ||
      err?.message ||
      String(err);
    return typeof msg === "string" ? msg : JSON.stringify(msg);
  } catch {
    return "An unknown error occurred.";
  }
};

// Search deeply for an "execution reverted" marker within common error shapes
const containsExecutionReverted = (err: any, fallbackMsg?: string): boolean => {
  const haystacks: string[] = [];
  try {
    if (fallbackMsg) haystacks.push(fallbackMsg);
    if (typeof err === "string") haystacks.push(err);
    if (err?.reason) haystacks.push(err.reason);
    if (err?.message) haystacks.push(err.message);
    if (err?.shortMessage) haystacks.push(err.shortMessage);
    if (err?.data?.message) haystacks.push(err.data.message);
    if (err?.data?.originalError?.message)
      haystacks.push(err.data.originalError.message);
    if (err?.error?.message) haystacks.push(err.error.message);
    if (err?.error?.data?.message) haystacks.push(err.error.data.message);
    if (err?.error?.data?.originalError?.message)
      haystacks.push(err.error.data.originalError.message);
    if (err?.info?.error?.message) haystacks.push(err.info.error.message);
    if (err?.info?.error?.data?.message)
      haystacks.push(err.info.error.data.message);
    if (err?.info?.error?.data?.originalError?.message)
      haystacks.push(err.info.error.data.originalError.message);

    const bodies = [err?.body, err?.error?.body, err?.info?.body].filter(
      Boolean
    );
    for (const body of bodies) {
      if (typeof body === "string") {
        try {
          const parsed = JSON.parse(body);
          const nested = [
            parsed?.error?.message,
            parsed?.error?.data?.message,
            parsed?.error?.data?.originalError?.message,
          ].filter(Boolean);
          haystacks.push(...(nested as string[]));
        } catch (_) {
          haystacks.push(body);
        }
      }
    }
  } catch {
    // ignore
  }
  return haystacks.some(
    (s) =>
      typeof s === "string" && s.toLowerCase().includes("execution reverted")
  );
};

// Black-Scholes implementation for IV simulation
const cdf = (x: number): number => {
  const a1 = 0.254829592;
  const a2 = -0.284496736;
  const a3 = 1.421413741;
  const a4 = -1.453152027;
  const a5 = 1.061405429;
  const p = 0.3275911;

  let sign = 1;
  if (x < 0) sign = -1;
  const absX = Math.abs(x) / Math.sqrt(2.0);

  const t = 1.0 / (1.0 + p * absX);
  const y =
    1.0 -
    ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-absX * absX);

  return 0.5 * (1.0 + sign * y);
};

const blackScholes = (
  callOrPut: "call" | "put",
  S: number,
  K: number,
  t: number,
  r: number,
  sigma: number
): number => {
  if (sigma <= 0 || t <= 0) {
    return 0;
  }

  const d1 =
    (Math.log(S / K) + (r + (sigma * sigma) / 2) * t) / (sigma * Math.sqrt(t));
  const d2 = d1 - sigma * Math.sqrt(t);

  if (callOrPut === "call") {
    return S * cdf(d1) - K * Math.exp(-r * t) * cdf(d2);
  } else if (callOrPut === "put") {
    return K * Math.exp(-r * t) * cdf(-d2) - S * cdf(-d1);
  }
  return 0;
};

const IntelliTradeGnosisGold = () => {
  const theme = useTheme();
  const [status, setStatus] = useState<StatusState>({
    type: "disconnected",
    message: "Not Connected",
  });
  const [activeTab, setActiveTab] = useState<"portfolio" | "trade" | "admin">(
    "portfolio"
  );
  const [userAddress, setUserAddress] = useState<string>("");
  const [isAdmin, setIsAdmin] = useState<boolean>(false);
  const [provider, setProvider] = useState<BrowserProvider | null>(null);
  const [signer, setSigner] = useState<JsonRpcSigner | null>(null);
  const [contract, setContract] = useState<Contract | null>(null);
  const storedUser = JSON.parse(localStorage.getItem("user") || "{}");
  const id = storedUser?.id || "";
  const { loading, error, data, refetch } = useQuery(GET_CUSTOMER_ID, {
    variables: { id },
  });
  const customerData = data?.getCustomer || {};
  const [toast, setToast] = useState<ToastState>({
    visible: false,
    message: "",
    type: "info",
  });
  const [oracleIsStale, setOracleIsStale] = useState<boolean>(false);
  const [isManualSource, setIsManualSource] = useState<boolean>(false);
  const [portfolio, setPortfolio] = useState<PortfolioState>({
    positions: [],
    totalValue: 0,
    pnl: 0,
    activePositions: 0,
    spotPrice: 0,
    isLoading: false,
  });
  const [trade, setTrade] = useState<TradeState>({
    outright: {
      maturity: "",
      amount: "",
      sl: "",
      tp: "",
      paymentToken: IUSD_TOKEN_ADDRESS,
      maxCost: "0.00",
      slippagePercent: "0.5",
    },
    spread: {
      legs: [
        { maturity: "", amountIGLD: "", isLong: true },
        { maturity: "", amountIGLD: "", isLong: false },
      ],
      paymentToken: IUSD_TOKEN_ADDRESS,
      maxCost: "",
      minCredit: "",
      slippagePercent: "0.5",
      impliedVolatility: "25.0",
      ivEnabled: true,
    },
  });
  const [spreadQuote, setSpreadQuote] = useState<SpreadQuoteState>({
    isCalculating: false,
    netCost: null,
    displayCost: "$0.00",
    error: null,
  });
  const [admin, setAdmin] = useState<AdminState>({
    manualSpotPrice: "",
    keeperAddress: "",
    annualRate: "",
    oracleMaxAge: "",
  });
  const [analysis, setAnalysis] = useState<AnalysisState>({
    startDate: "",
    endDate: "",
    results: null,
  });
  const [expanded, setExpanded] = useState<boolean>(false);
  const [isOutrightTrading, setIsOutrightTrading] = useState<boolean>(false);
  const [isSpreadTrading, setIsSpreadTrading] = useState<boolean>(false);
  const [pendingClosePosition, setPendingClosePosition] = useState<Position | null>(null);
  const [isCloseProcessing, setIsCloseProcessing] = useState(false);
  const [closeRefreshToken, setCloseRefreshToken] = useState(0);

  const chartRef = useRef<HTMLCanvasElement | null>(null);
  const chartInstance = useRef<Chart<"line", number[], string> | null>(null);
  const lastOutrightSigRef = useRef<string>("");
  const lastSpreadSigRef = useRef<string>("");
  const quoteNowRef = useRef<number>(0);
  const reloadRetryRef = useRef<boolean>(false);

  const isUserRejectedError = (err: any) => {
    const code = err?.code ?? err?.error?.code ?? err?.error?.error?.code;
    return code === 4001 || code === "ACTION_REJECTED";
  };

  const getUserRejectedMessage = (err: any) => {
    const detail =
      err?.error?.data?.message ||
      err?.data?.message ||
      err?.error?.message ||
      err?.message;

    if (typeof detail === "string") {
      const lower = detail.toLowerCase();
      if (lower.includes("user denied") || lower.includes("user rejected")) {
        return "Transaction cancelled in MetaMask (user denied signature).";
      }
      if (lower.includes("rejected")) {
        return "Transaction cancelled in MetaMask.";
      }
    }

    return "Transaction cancelled in MetaMask.";
  };

  // Error handling
  const handleError = useCallback(
    (e: Error, context: string = "General") => {
      console.error(`${context} error:`, e);
      let message = extractErrorMessage(e);
      try {
        const nestedCandidates: Array<string | undefined> = [
          (e as any)?.data?.message,
          (e as any)?.error?.data?.message,
          (e as any)?.error?.data?.originalError?.message,
          (e as any)?.info?.error?.data?.message,
          (e as any)?.info?.error?.data?.originalError?.message,
        ];
        const bestNested = nestedCandidates.find(
          (m) => typeof m === "string" && m.length > 0
        );
        if (bestNested) message = bestNested as string;
      } catch {}

      if (message.includes("Oracle price is stale")) {
        if (!oracleIsStale) {
          setToast({
            visible: true,
            message: "Oracle is stale. Functionality is limited.",
            type: "error",
          });
          setTimeout(
            () => setToast((prev) => ({ ...prev, visible: false })),
            10000
          );
        }
        setOracleIsStale(true);
        return;
      }

      // Special-case: show concise maturity error if present in nested data.message
      try {
        const compact = message
          .replace(/^["']|["']$/g, "")
          .replace(/.*execution reverted:\s*/i, "")
          .trim();
        const hay = `${message} ${compact} ${JSON.stringify((e as any) ?? {})}`;
        if (/maturity\s+too\s+soon/i.test(hay)) {
          setToast({ visible: true, message: "Maturity too soon", type: "error" });
          setTimeout(() => setToast((prev) => ({ ...prev, visible: false })), 8000);
          return;
        }
      } catch {}

      const lower = (message || "").toLowerCase();
      let conciseMsg: string;
      if (lower.includes("insufficient funds")) {
        // Trim noisy suffix like "(supplied gas ...)"
        let clean = message;
        const idxStart = clean.toLowerCase().indexOf("insufficient funds");
        if (idxStart >= 0) clean = clean.slice(idxStart);
        const idxParen = clean.indexOf("(");
        if (idxParen > 0) clean = clean.slice(0, idxParen).trim();
        conciseMsg = `transaction : ${clean}`;
      } else if ((e as any)?.code === 4001 || lower.includes("user denied") || lower.includes("user rejected")) {
        conciseMsg = "Transaction cancelled by user";
      } else if (lower.includes("no matching fragment")) {
        conciseMsg =
          "Error: Net short positions are not supported. Total long amount must be >= total short amount.";
      } else if (containsExecutionReverted(e, message)) {
        conciseMsg = "Transaction error: execution reverted";
      } else {
        conciseMsg = `${context} failed: ${message.substring(0, 100)}`;
      }

      setToast({ visible: true, message: conciseMsg, type: "error" });
      setTimeout(() => setToast((prev) => ({ ...prev, visible: false })), 8000);
    },
    [oracleIsStale]
  );

  // Toast notification
  const showToast = useCallback(
    (
      message: string,
      type: ToastState["type"] = "info",
      duration: number = 4000
    ) => {
      setToast({ visible: true, message, type });
      if (duration) {
        setTimeout(
          () => setToast((prev) => ({ ...prev, visible: false })),
          duration
        );
      }
    },
    []
  );

  const [isLoading, setIsLoading] = useState(false);

  const [balance, setBalance] = useState<string | null>(null);
  interface CustomEthereumProvider extends Eip1193Provider {
    on(
      event: "accountsChanged" | "chainChanged",
      listener: (...args: any[]) => void
    ): void;
    removeListener(
      event: "accountsChanged" | "chainChanged",
      listener: (...args: any[]) => void
    ): void;
  }

  const checkIfWalletIsConnected = async (
    provider: BrowserProvider
  ): Promise<string | null> => {
    try {
      const accounts = await provider.send("eth_accounts", []);
      return accounts.length > 0 ? accounts[0] : null;
    } catch (e) {
      console.error("Error checking wallet connection:", e);
      return null;
    }
  };

  const connectWallet = useCallback(async () => {
    setIsLoading(true);
    try {
      const eth = (window as any).ethereum as Eip1193Provider | undefined;
      if (!eth) {
        showToast("Please install a web3 wallet like MetaMask.", "error", 5000);
        setStatus({ type: "error", message: "No wallet detected" });
        return;
      }

      const provider = new BrowserProvider(
        eth as Eip1193Provider,
        "any"
      );

      const connectedAccount = await checkIfWalletIsConnected(provider);
      if (connectedAccount) {
        const signer = await provider.getSigner();
        const network = await provider.getNetwork();
        console.log("[Connect] network(chainId):", Number(network.chainId));

        if (Number(network.chainId) !== 100) {
          showToast("Please switch to Gnosis Network.", "error", 5000);
          setStatus({
            type: "error",
            message: "Please switch to Gnosis Network",
          });
          setIsLoading(false);
          return;
        }

        const contract = new Contract(RFQ_CONTRACT_ADDRESS, RFQ_ABI, signer);
        const balance = await provider.getBalance(connectedAccount);
        const ethBalance = ethers.formatEther(balance);

        setProvider(provider);
        setSigner(signer);
        setUserAddress(connectedAccount);
        setContract(contract);
        setStatus({
          type: "connected",
          message: `Connected: ${shortenAddress(connectedAccount)}`,
        });
        setBalance(`${parseFloat(ethBalance).toFixed(4)} xDAI`);
        console.log("[Connect] connected account:", connectedAccount);

        const oracleOK = await checkOracleStatus();
        await checkAdminStatus();
        // reloadData will run from the effect once contract + userAddress are set
      }

      const accounts = await provider.send("eth_requestAccounts", []);
      if (accounts.length > 0) {
        const signer = await provider.getSigner();
        const network = await provider.getNetwork();
        console.log("[Connect] requestAccounts network(chainId):", Number(network.chainId));
        if (Number(network.chainId) !== 100) {
          showToast("Please switch to Gnosis Network.", "error", 5000);
          setStatus({
            type: "error",
            message: "Please switch to Gnosis Network",
          });
          setIsLoading(false);
          return;
        }

        const contract = new Contract(RFQ_CONTRACT_ADDRESS, RFQ_ABI, signer);
        const balance = await provider.getBalance(accounts[0]);
        const ethBalance = ethers.formatEther(balance);

        setProvider(provider);
        setSigner(signer);
        setUserAddress(accounts[0]);
        setContract(contract);
        setStatus({
          type: "connected",
          message: `Connected: ${shortenAddress(accounts[0])}`,
        });
        setBalance(`${parseFloat(ethBalance).toFixed(4)} xDAI`);
        console.log("[Connect] connected account:", accounts[0]);

        const oracleOK = await checkOracleStatus();
        await checkAdminStatus();
        // reloadData will run from the effect once contract + userAddress are set
      }
    } catch (e) {
      handleError(e as Error, "Connection");
    } finally {
      setIsLoading(false);
    }
  }, []);

  const disconnectWallet = useCallback(async () => {
    setProvider(null);
    setSigner(null);
    setUserAddress("");
    setContract(null);
    setStatus({ type: "disconnected", message: "Not Connected" });
  }, []);

  const reloadData = useCallback(async () => {
    console.log("[Reload] start", {
      hasContract: !!contract,
      userAddress,
      oracleIsStale,
      isManualSource,
    });
    if (!contract) {
      console.log("[Reload] skipped: no contract");
      return;
    }
    try {
      setPortfolio((prev) => ({ ...prev, isLoading: true }));
      await fetchLiveSpotPrice();
      await fetchPortfolioData();
      if (activeTab === "trade" && chartInstance.current) {
        await fetchChartData();
      }
      if (isAdmin) {
        await fetchAdminSettings();
      }
    } catch (e) {
      const msg = extractErrorMessage(e);
      console.error("Critical error during reload sequence:", msg);
      if (
        typeof msg === "string" &&
        msg.toLowerCase().includes("no state available for block") &&
        !reloadRetryRef.current
      ) {
        // Transient RPC state issue (common on Gnosis); retry once after a short delay
        reloadRetryRef.current = true;
        showToast("Network is catching up. Retrying...", "warning", 2500);
        setTimeout(() => {
          reloadRetryRef.current = false;
          void reloadData();
        }, 1200);
      } else {
        handleError(e as Error, "Data Reload");
      }
    } finally {
      setPortfolio((prev) => ({ ...prev, isLoading: false }));
      console.log("[Reload] done");
    }
  }, [contract, oracleIsStale, isManualSource, activeTab, isAdmin]);

  const handleTx = useCallback(
    async (
      txPromise: Promise<ethers.TransactionResponse>,
      successMessage: string
    ) => {
      showToast("Sending transaction...", "info", 60000);
      try {
        const tx = await txPromise;
        showToast(
          "Transaction submitted, awaiting confirmation...",
          "info",
          60000
        );
        const receipt = await tx.wait();
        showToast(successMessage, "success");
        await reloadData();
        return receipt;
      } catch (e) {
        handleError(e as Error, "Transaction");
        throw e;
      }
    },
    [showToast, handleError, reloadData]
  );

  const checkAdminStatus = useCallback(async () => {
    if (!contract || !userAddress) return;
    try {
      const admin = (await contract.admin()) as string;
      setIsAdmin(admin.toLowerCase() === userAddress.toLowerCase());
    } catch (e: unknown) {
      console.error("Admin check failed:", e);
    }
  }, [contract, userAddress]);

  const checkOracleStatus = useCallback(async () => {
    if (!contract) return false;
    try {
      const source = (await contract.spotSource()) as bigint;
      setIsManualSource(source === BigInt(1));

      if (source === BigInt(1)) {
        setOracleIsStale(false);
        console.log("Oracle status: Manual source active");
        return true;
      }

      await contract.priceFor(Math.floor(Date.now() / 1000) + 86400);
      setOracleIsStale(false);
      console.log("Oracle status: Chainlink active and up-to-date");
      return true;
    } catch (e: unknown) {
      console.error("Oracle check failed:", e);
      handleError(e as Error, "Oracle Status Check");
      return false;
    }
  }, [contract, handleError]);

  // Fetch live spot price
  const fetchLiveSpotPrice = useCallback(async () => {
    if (!contract || (oracleIsStale && !isManualSource)) {
      console.log("Skipping spot price fetch due to stale oracle");
      return;
    }
    try {
      const price = (await contract.priceFor(
        Math.floor(Date.now() / 1000)
      )) as bigint;
      setPortfolio((prev) => ({
        ...prev,
        spotPrice: parseFloat(ethers.formatUnits(price, 18)),
      }));
    } catch (e: unknown) {
      console.error("Spot price fetch error:", e);
      handleError(e as Error, "Live Spot Price");
      throw e;
    }
  }, [contract, oracleIsStale, isManualSource, handleError]);

  // Fetch admin settings
  const fetchAdminSettings = useCallback(async () => {
    if (!contract || !isAdmin) return;
    try {
      const [maxAge, annualRate, priceSrc] = await Promise.all([
        contract.oracleMaxAge() as Promise<bigint>,
        contract.annualRateBPS() as Promise<bigint>,
        contract.spotSource() as Promise<bigint>,
      ]);
      setAdmin((prev) => ({
        ...prev,
        oracleMaxAge: maxAge.toString(),
        annualRate: annualRate.toString(),
      }));
      setIsManualSource(priceSrc === BigInt(1));
      console.log("Admin settings fetched successfully");
    } catch (e: unknown) {
      console.error("Admin settings fetch error:", e);
      handleError(e as Error, "Admin Settings");
      throw e;
    }
  }, [contract, isAdmin, handleError]);

  // Initialize chart
  const initChart = useCallback(() => {
    if (!chartRef.current) return;

    if (chartInstance.current) {
      chartInstance.current.destroy();
      chartInstance.current = null;
    }

    const ctx = chartRef.current.getContext("2d");
    if (!ctx) return;

    chartInstance.current = new Chart<"line", number[], string>(ctx, {
      type: "line",
      data: {
        labels: [],
        datasets: [
          {
            label: "Base Futures Curve",
            data: [],
            borderColor: "#1e40af",
            backgroundColor: "rgba(30, 64, 175, 0.1)",
            fill: true,
            tension: 0.2,
          },
          {
            label: "IV Adjusted Curve",
            data: [],
            borderColor: "#c026d3",
            backgroundColor: "rgba(192, 38, 211, 0.1)",
            borderDash: [5, 5],
            fill: true,
            tension: 0.2,
          },
        ],
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: { legend: { display: true } },
        scales: {
          x: {
            title: { display: true, text: "Maturity" },
            grid: { display: false },
          },
          y: { title: { display: true, text: "Price (IUSD)" } },
        },
      },
    });
  }, []);

  // Fetch chart data
  const fetchChartData = useCallback(async () => {
    if (
      !contract ||
      (oracleIsStale && !isManualSource) ||
      !chartInstance.current
    ) {
      console.log("Skipping chart data fetch due to stale oracle");
      return;
    }

    try {
      const labels: string[] = [];
      const baseCurveData: number[] = [];
      const ivAdjustedCurveData: number[] = [];
      const today = new Date();
      const maturityTimestamps: number[] = [];

      for (let i = 0; i < 12; i++) {
        const futureDate = new Date();
        futureDate.setMonth(today.getMonth() + i, 15);
        futureDate.setUTCHours(0, 0, 0, 0);
        labels.push(
          futureDate.toLocaleString("default", {
            month: "short",
            year: "2-digit",
          })
        );
        maturityTimestamps.push(Math.floor(futureDate.getTime() / 1000));
      }

      const pricePromises = maturityTimestamps.map((ts) =>
        contract.priceFor(ts)
      );
      const basePricesWei = (await Promise.all(pricePromises)) as bigint[];

      const annualRate =
        Number((await contract.annualRateBPS()) as bigint) / 10000;
      const volatility = parseFloat(trade.spread.impliedVolatility) / 100;

      basePricesWei.forEach((priceWei: bigint, index: number) => {
        const basePrice = parseFloat(ethers.formatUnits(priceWei, 18));
        baseCurveData.push(basePrice);

        if (trade.spread.ivEnabled) {
          const maturityTs = maturityTimestamps[index];
          const timeToMaturityYears =
            (maturityTs - Date.now() / 1000) / (365 * 24 * 60 * 60);
          const volatilityPremium = blackScholes(
            "call",
            basePrice,
            basePrice,
            timeToMaturityYears,
            annualRate,
            volatility
          );
          ivAdjustedCurveData.push(basePrice + volatilityPremium);
        }
      });

      chartInstance.current.data.labels = labels;
      chartInstance.current.data.datasets[0].data = baseCurveData;
      chartInstance.current.data.datasets[1].data = ivAdjustedCurveData;
      chartInstance.current.setDatasetVisibility(1, trade.spread.ivEnabled);
      chartInstance.current.update("none");
      console.log("Chart data fetched successfully");
    } catch (e: unknown) {
      console.error("Chart data fetch error:", e);
      handleError(e as Error, "Chart Data");
    }
  }, [
    contract,
    oracleIsStale,
    isManualSource,
    trade.spread.impliedVolatility,
    trade.spread.ivEnabled,
    handleError,
  ]);

  // Fetch portfolio data
  const fetchPortfolioData = useCallback(async () => {
    if (!contract || !userAddress) {
      setPortfolio((prev) => ({ ...prev, positions: [] }));
      return;
    }

    setPortfolio((prev) => ({ ...prev, isLoading: true }));
    try {
      const positionCount = (await contract.nextPositionIdForUser(
        userAddress
      )) as bigint;
      const count = Number(positionCount);
      console.log(
        "[Portfolio] nextPositionIdForUser:",
        positionCount.toString(),
        "(count:",
        count,
        ") for",
        userAddress
      );
      const positionPromises: Promise<any>[] = [];

      if (count > 0) {
        for (let i = 0; i < count; i++) {
          positionPromises.push(
            contract.getPositionById(userAddress, BigInt(i))
          );
        }
      }

      const allPositions = await Promise.all(positionPromises);
      console.log("[Portfolio] allPositions length:", allPositions.length);
      if (allPositions.length > 0) {
        try {
          console.log("[Portfolio] first raw position sample:", allPositions[0]);
        } catch {}
      }
      const pricePromises: { [key: string]: Promise<bigint> } = {};
      const activePositions = allPositions.filter((p: any) => p.isActive);
      console.log("[Portfolio] activePositions length:", activePositions.length);
      // Only fetch live prices when oracle is not stale or manual mode is active
      if (!(oracleIsStale && !isManualSource)) {
        for (const p of activePositions) {
          for (const leg of p.legs) {
            const maturityStr = leg.maturity.toString();
            if (!pricePromises[maturityStr]) {
              pricePromises[maturityStr] = contract.priceFor(
                leg.maturity
              ) as Promise<bigint>;
            }
          }
        }
      }

      const prices = await Promise.all(Object.values(pricePromises));
      const priceMap = Object.keys(pricePromises).reduce(
        (acc, maturity, index) => {
          acc[maturity] = prices[index];
          return acc;
        },
        {} as { [key: string]: bigint }
      );
      console.log("[Portfolio] maturities priced:", Object.keys(priceMap));

      let totalPnl = BigInt(0);
      const positions: Position[] = activePositions
        .map((p: any) => {
          let posPnl = BigInt(0);
          let longAmount = BigInt(0);

          p.legs.forEach((leg: any) => {
            const maturityKey = leg.maturity.toString();
            const currentPrice = priceMap[maturityKey] as bigint | undefined;
            if (currentPrice !== undefined) {
              const entryPrice = leg.entryPrice as bigint;
              const amountIGLD = leg.amountIGLD as bigint;
              const pnlForLeg =
                ((currentPrice - entryPrice) * amountIGLD) /
                (ethers.parseUnits("1", 18) as bigint);
              if (leg.isLong) {
                posPnl += pnlForLeg;
                longAmount += leg.amountIGLD;
              } else {
                posPnl -= pnlForLeg;
              }
            } else {
              // No live price (stale oracle): still accumulate long amount for display
              if (leg.isLong) longAmount += leg.amountIGLD as bigint;
            }
          });

          totalPnl += posPnl;

          return {
            positionId: p.positionId.toString(),
            positionType: p.positionType === 0 ? "Outright" : "Spread",
            legs: p.legs.map((leg: any) => ({
              maturity: new Date(
                Number(leg.maturity) * 1000
              ).toLocaleDateString(),
              amountIGLD: parseFloat(ethers.formatUnits(leg.amountIGLD, 18)),
              isLong: leg.isLong,
              entryPrice: parseFloat(ethers.formatUnits(leg.entryPrice, 18)),
            })),
            longAmount: parseFloat(ethers.formatUnits(longAmount, 18)),
            stopLossPrice: parseFloat(ethers.formatUnits(p.stopLossPrice, 18)),
            takeProfitPrice: parseFloat(
              ethers.formatUnits(p.takeProfitPrice, 18)
            ),
            pnl: parseFloat(ethers.formatUnits(posPnl, 18)),
          };
        })
        .reverse();
      console.log(
        "[Portfolio] computed positions:",
        positions.length,
        "totalPnl:",
        parseFloat(ethers.formatUnits(totalPnl, 18))
      );

      setPortfolio((prev) => ({
        ...prev,
        positions,
        pnl: parseFloat(ethers.formatUnits(totalPnl, 18)),
        activePositions: positions.length,
      }));
    } catch (e: unknown) {
      console.error("Portfolio fetch error:", e);
      handleError(e as Error, "Portfolio");
    } finally {
      setPortfolio((prev) => ({ ...prev, isLoading: false }));
    }
  }, [contract, userAddress, oracleIsStale, isManualSource, handleError]);

  useEffect(() => {
    if (closeRefreshToken > 0) {
      fetchPortfolioData();
    }
  }, [closeRefreshToken, fetchPortfolioData]);

  // Quote functions - Outright
  const getOutrightQuote = useCallback(async () => {
    const { maturity, amount, slippagePercent } = trade.outright;
    if (!maturity || !amount || isNaN(parseFloat(amount))) return;
    try {
      if (!contract) return;
      // Normalize to 00:00:00 UTC to match contract expectations
      const d = new Date(maturity);
      d.setUTCHours(0, 0, 0, 0);
      const maturityTs = Math.floor(d.getTime() / 1000);
      const price = (await contract.priceFor(maturityTs)) as bigint;
      const amount18 = ethers.parseUnits(amount, 18);
      const principal =
        (amount18 * price) / (ethers.parseUnits("1", 18) as bigint);
      const fee =
        (principal * ((await contract.treasuryFeeBPS()) as bigint)) /
        BigInt(10000);
      const totalCost = principal + fee;

      const slip = parseFloat(slippagePercent);
      if (!isNaN(slip) && slip >= 0) {
        const slippageBPS = BigInt(Math.round(slip * 100));
        const maxCostWei =
          (totalCost * (BigInt(10000) + slippageBPS)) / BigInt(10000);
        setTrade((prev) => ({
          ...prev,
          outright: {
            ...prev.outright,
            maxCost: parseFloat(ethers.formatUnits(maxCostWei, 18)).toFixed(2),
          },
        }));
      } else {
        setTrade((prev) => ({
          ...prev,
          outright: { ...prev.outright, maxCost: "0.00" },
        }));
      }
    } catch (e: unknown) {
      console.error("Outright quote error:", e);
      showToast(
        "Could not get quote. Pick a valid maturity (UTC midnight; listed maturities are typically on the 15th).",
        "error",
        5000
      );
    }
  }, [trade.outright, contract]);

  const debouncedGetOutrightQuote = useCallback(() => {
    const timer = setTimeout(() => getOutrightQuote(), 500);
    return () => clearTimeout(timer);
  }, [getOutrightQuote]);

  // Execute outright trade
  const handleExecuteOutrightTrade = useCallback(async () => {
    const { maturity, amount, sl, tp, paymentToken, maxCost } = trade.outright;
    if (!maturity || !amount) {
      showToast("Please enter maturity and amount.", "error");
      return;
    }
    setIsOutrightTrading(true);
    try {
      // Normalize to 00:00:00 UTC to match contract expectations
      const d = new Date(maturity);
      d.setUTCHours(0, 0, 0, 0);
      const maturityTs = Math.floor(d.getTime() / 1000);
      const amount18 = ethers.parseUnits(amount, 18);
      const sl18 = sl ? ethers.parseUnits(sl, 18) : BigInt(0);
      const tp18 = tp ? ethers.parseUnits(tp, 18) : BigInt(0);
      const maxCost18 = ethers.parseUnits(maxCost, 18);

      if (paymentToken === IUSD_TOKEN_ADDRESS) {
        const iusdContract = new Contract(IUSD_TOKEN_ADDRESS, IUSD_ABI, signer);
        if (!contract) throw new Error("Contract not initialized");
        const price = (await contract.priceFor(maturityTs)) as bigint;
        const principal =
          (amount18 * price) / (ethers.parseUnits("1", 18) as bigint);
        const fee =
          (principal * ((await contract.treasuryFeeBPS()) as bigint)) /
          BigInt(10000);
        const totalCost = principal + fee;

        const allowance = (await iusdContract.allowance(
          userAddress,
          RFQ_CONTRACT_ADDRESS
        )) as bigint;

        if (allowance < totalCost) {
          await handleTx(
            iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
            "IUSD Approval Successful"
          );
        }

        await handleTx(
          contract.openPositionWithIUSD(
            maturityTs,
            amount18,
            sl18,
            tp18,
            maxCost18
          ),
          "Outright position opened!"
        );
      } else {
        if (!contract) throw new Error("Contract not initialized");
        const price = (await contract.priceFor(maturityTs)) as bigint;
        const principal =
          (amount18 * price) / (ethers.parseUnits("1", 18) as bigint);
        const fee =
          (principal * ((await contract.treasuryFeeBPS()) as bigint)) /
          BigInt(10000);
        const overrides = { value: principal + fee };

        await handleTx(
          contract.openPositionWithXDAI(
            maturityTs,
            amount18,
            sl18,
            tp18,
            maxCost18,
            overrides
          ),
          "Outright position opened!"
        );
      }
    } catch (e: unknown) {
      // handled in handleTx
    } finally {
      setIsOutrightTrading(false);
    }
  }, [trade.outright, contract, signer, userAddress, handleTx, showToast]);

  // Get spread quote
  const getSpreadQuote = useCallback(async () => {
    const legs = trade.spread.legs;
    const allInputsValid = legs.every(
      (leg) => leg.maturity && leg.amountIGLD && parseFloat(leg.amountIGLD) > 0
    );

    if (!allInputsValid || !contract) {
      setSpreadQuote({
        isCalculating: false,
        netCost: null,
        displayCost: "$0.00",
        error: null,
      });
      return;
    }

    const sig = JSON.stringify({
      legs: legs.map((l) => ({
        m: l.maturity,
        a: l.amountIGLD,
        g: !!l.isLong,
      })),
      ivEnabled: trade.spread.ivEnabled,
      iv: trade.spread.impliedVolatility,
      slip: trade.spread.slippagePercent,
    });
    if (lastSpreadSigRef.current === sig) return;
    lastSpreadSigRef.current = sig;
    quoteNowRef.current = Math.floor(Date.now() / 1000);

    setSpreadQuote((prev) => ({ ...prev, isCalculating: true, error: null }));

    try {
      let netCostWei = BigInt(0);
      const annualRate =
        Number((await contract.annualRateBPS()) as bigint) / 10000;
      const volatility = parseFloat(trade.spread.impliedVolatility) / 100;
      const includeIV = trade.spread.ivEnabled;

      for (const leg of legs) {
        const mat_ts = Math.floor(new Date(leg.maturity).getTime() / 1000);
        const amt_18 = ethers.parseUnits(leg.amountIGLD, 18);

        let finalPriceWei = (await contract.priceFor(mat_ts)) as bigint;

        if (includeIV) {
          const basePrice = parseFloat(ethers.formatUnits(finalPriceWei, 18));
          const timeToMaturityYears =
            (mat_ts - quoteNowRef.current) / (365 * 24 * 60 * 60);
          const volatilityPremium = blackScholes(
            "call",
            basePrice,
            basePrice,
            timeToMaturityYears,
            annualRate,
            volatility
          );
          const simulatedPrice = basePrice + volatilityPremium;
          finalPriceWei = ethers.parseUnits(simulatedPrice.toFixed(18), 18);
        }

        const legValue = (finalPriceWei * amt_18) / ethers.parseUnits("1", 18);

        if (leg.isLong) {
          netCostWei += legValue;
        } else {
          netCostWei -= legValue;
        }
      }

      const formattedCost = parseFloat(
        ethers.formatUnits(
          netCostWei < BigInt(0) ? -netCostWei : netCostWei,
          18
        )
      );
      const slippagePercent = parseFloat(trade.spread.slippagePercent);

      if (isNaN(slippagePercent) || slippagePercent < 0) {
        setSpreadQuote((prev) => ({
          ...prev,
          isCalculating: false,
          error: "Invalid slippage percentage.",
        }));
        return;
      }

      const slippageBPS = BigInt(Math.round(slippagePercent * 100));

      if (netCostWei > BigInt(0)) {
        setSpreadQuote((prev) => ({
          ...prev,
          netCost: netCostWei,
          displayCost: `Debit: ${formatCurrency(formattedCost)}`,
        }));
        const maxCostWei =
          (netCostWei * (BigInt(10000) + slippageBPS)) / BigInt(10000);
        setTrade((prev) => ({
          ...prev,
          spread: {
            ...prev.spread,
            maxCost: parseFloat(ethers.formatUnits(maxCostWei, 18)).toFixed(2),
            minCredit: "",
          },
        }));
      } else if (netCostWei < BigInt(0)) {
        setSpreadQuote((prev) => ({
          ...prev,
          netCost: netCostWei,
          displayCost: `Credit: ${formatCurrency(formattedCost)}`,
        }));
        const creditWei = -netCostWei;
        const minCreditWei =
          (creditWei * (BigInt(10000) - slippageBPS)) / BigInt(10000);
        setTrade((prev) => ({
          ...prev,
          spread: {
            ...prev.spread,
            minCredit: parseFloat(ethers.formatUnits(minCreditWei, 18)).toFixed(
              2
            ),
            maxCost: "",
          },
        }));
      } else {
        setSpreadQuote((prev) => ({
          ...prev,
          netCost: netCostWei,
          displayCost: "$0.00",
        }));
        setTrade((prev) => ({
          ...prev,
          spread: { ...prev.spread, maxCost: "0.00", minCredit: "0.00" },
        }));
      }
    } catch (e: unknown) {
      setSpreadQuote((prev) => ({
        ...prev,
        isCalculating: false,
        error: "Could not calculate price. Invalid inputs.",
        netCost: null,
        displayCost: "$0.00",
      }));
      console.error("Spread quote failed:", e);
    } finally {
      setSpreadQuote((prev) => ({ ...prev, isCalculating: false }));
    }
  }, [contract, trade.spread, handleError]);

  // Debounced spread quote
  const debouncedGetSpreadQuote = useCallback(() => {
    const timer = setTimeout(() => getSpreadQuote(), 500);
    return () => clearTimeout(timer);
  }, [getSpreadQuote]);

  const memoizedLegs = useMemo(() => trade.spread.legs, [trade.spread.legs]);
  // Open spread position
  const handleExecuteSpreadTrade = useCallback(async () => {
    const { legs, paymentToken, slippagePercent } = trade.spread;
    const allInputsValid = legs.every(
      (leg) => leg.maturity && leg.amountIGLD && parseFloat(leg.amountIGLD) > 0
    );

    if (!allInputsValid) {
      showToast(
        "All spread legs must have a valid maturity and amount.",
        "error"
      );
      return;
    }

    let netIGLDAmount = BigInt(0);
    legs.forEach((leg) => {
      const amount = ethers.parseUnits(leg.amountIGLD || "0", 18);
      if (leg.isLong) {
        netIGLDAmount += amount;
      } else {
        netIGLDAmount -= amount;
      }
    });

    if (netIGLDAmount < BigInt(0)) {
      showToast(
        "Error: Net short positions are not supported. Total long amount must be >= total short amount.",
        "error",
        6000
      );
      return;
    }

    setIsSpreadTrading(true);
    try {
      const inputLegs = legs.map((leg) => ({
        maturity: Math.floor(new Date(leg.maturity).getTime() / 1000),
        amountIGLD: ethers.parseUnits(leg.amountIGLD, 18),
        isLong: leg.isLong,
      }));

      let actualNetCostWei = BigInt(0);
      for (const leg of inputLegs) {
        const priceWei = (await contract!.priceFor(leg.maturity)) as bigint;
        const legValue =
          (priceWei * leg.amountIGLD) / (ethers.parseUnits("1", 18) as bigint);
        if (leg.isLong) {
          actualNetCostWei += legValue;
        } else {
          actualNetCostWei -= legValue;
        }
      }

      let finalMaxCost18 = BigInt(0);
      let finalMinCredit18 = BigInt(0);
      let overrides: any = {};

      const slippageBPS = BigInt(Math.round(parseFloat(slippagePercent) * 100));
      if (isNaN(Number(slippageBPS)) || slippageBPS < BigInt(0)) {
        showToast("Invalid slippage percentage.", "error");
        return;
      }

      const feeBPS = (await contract!.treasuryFeeBPS()) as bigint;

      if (actualNetCostWei > BigInt(0)) {
        const fee = (actualNetCostWei * feeBPS) / BigInt(10000);
        const totalCost = actualNetCostWei + fee;
        finalMaxCost18 =
          (totalCost * (BigInt(10000) + slippageBPS)) / BigInt(10000);

        if (paymentToken === IUSD_TOKEN_ADDRESS) {
          const iusdContract = new Contract(
            IUSD_TOKEN_ADDRESS,
            IUSD_ABI,
            signer
          );
          const allowance = (await iusdContract.allowance(
            userAddress,
            RFQ_CONTRACT_ADDRESS
          )) as bigint;
          if (allowance < totalCost) {
            await handleTx(
              iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
              "IUSD Approval Successful"
            );
          }
        } else {
          overrides = { value: totalCost };
        }
      } else if (actualNetCostWei < BigInt(0)) {
        const totalCredit = -actualNetCostWei;
        finalMinCredit18 =
          (totalCredit * (BigInt(10000) - slippageBPS)) / BigInt(10000);
      }

      await handleTx(
        contract!.openSpreadPosition(
          inputLegs,
          paymentToken,
          finalMaxCost18,
          finalMinCredit18,
          overrides
        ),
        "Spread position opened!"
      );
    } catch (e: unknown) {
      // handled in handleTx
    } finally {
      setIsSpreadTrading(false);
    }
  }, [trade.spread, contract, signer, userAddress, handleTx, showToast]);

  // Close position
  const closePositionOnChain = useCallback(
    async (position: Position) => {
      if (!contract) throw new Error("Contract not initialized");
      try {
        const posData = await contract.getPositionById(
          userAddress,
          BigInt(position.positionId)
        );

        let totalLongAmountToBurn = BigInt(0);
        let pnlValue = BigInt(0);

        const pricePromises = posData.legs.map((leg: any) =>
          contract.priceFor(leg.maturity)
        );
        const currentPrices = await Promise.all(pricePromises);

        posData.legs.forEach((leg: any, index: number) => {
          const currentPrice = currentPrices[index] as bigint;
          const entryPrice = leg.entryPrice as bigint;
          const amountIGLD = leg.amountIGLD as bigint;
          const pnlForLeg =
            ((currentPrice - entryPrice) * amountIGLD) /
            (ethers.parseUnits("1", 18) as bigint);
          if (leg.isLong) {
            pnlValue += pnlForLeg;
            totalLongAmountToBurn += leg.amountIGLD;
          } else {
            pnlValue -= pnlForLeg;
          }
        });

        if (pnlValue < BigInt(0)) {
          const lossAmount = -pnlValue;
          const iusdContract = new Contract(
            IUSD_TOKEN_ADDRESS,
            IUSD_ABI,
            signer
          );
          const allowance = (await iusdContract.allowance(
            userAddress,
            RFQ_CONTRACT_ADDRESS
          )) as bigint;
          if (allowance < lossAmount) {
            await handleTx(
              iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
              "IUSD Approval for Loss Successful"
            );
          }
        }

        if (totalLongAmountToBurn > BigInt(0)) {
          const igldContract = new Contract(
            IGLD_TOKEN_ADDRESS,
            IGLD_ABI,
            signer
          );
          const allowance = (await igldContract.allowance(
            userAddress,
            RFQ_CONTRACT_ADDRESS
          )) as bigint;
          if (allowance < totalLongAmountToBurn) {
            await handleTx(
              igldContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
              "IGLD Approval Successful"
            );
          }
        }

        await handleTx(
          contract.closePosition(
            BigInt(position.positionId),
            IUSD_TOKEN_ADDRESS
          ),
          `Position #${position.positionId} closed.`
        );
      } catch (e: unknown) {
        if (!isUserRejectedError(e)) {
          console.error("Close position error:", e);
        }
        throw e;
      }
    },
    [contract, userAddress, signer, handleTx, isUserRejectedError]
  );

  const handleRequestClosePosition = useCallback((position: Position) => {
    setPendingClosePosition(position);
  }, []);

  const handleCancelClosePosition = useCallback(() => {
    if (isCloseProcessing) return;
    setPendingClosePosition(null);
  }, [isCloseProcessing]);

  const handleConfirmClosePosition = useCallback(async () => {
    if (!pendingClosePosition) return;
    setIsCloseProcessing(true);
    try {
      await closePositionOnChain(pendingClosePosition);
      setPendingClosePosition(null);
      setCloseRefreshToken((prev) => prev + 1);
    } catch (err) {
      if (isUserRejectedError(err)) {
        setPendingClosePosition(null);
        showToast(getUserRejectedMessage(err), "warning");
      }
    } finally {
      setIsCloseProcessing(false);
    }
  }, [
    pendingClosePosition,
    closePositionOnChain,
    isUserRejectedError,
    showToast,
    getUserRejectedMessage,
  ]);

  // Admin functions
  const handleSetManualSpotPrice = useCallback(async () => {
    const price = admin.manualSpotPrice;
    if (!price) {
      showToast("Manual price cannot be empty.", "error");
      return;
    }
    if (!contract) return;
    await handleTx(
      contract.setManualPrice(ethers.parseUnits(price, 18)),
      "Manual price set."
    );
  }, [admin.manualSpotPrice, contract, handleTx, showToast]);

  const handleAddKeeper = useCallback(async () => {
    if (!admin.keeperAddress || !ethers.isAddress(admin.keeperAddress)) {
      showToast("Keeper address is invalid.", "error");
      return;
    }
    if (!contract) return;
    await handleTx(
      contract.setKeeper(admin.keeperAddress, true),
      "Keeper added."
    );
  }, [admin.keeperAddress, contract, handleTx, showToast]);

  const handleRemoveKeeper = useCallback(async () => {
    if (!admin.keeperAddress || !ethers.isAddress(admin.keeperAddress)) {
      showToast("Keeper address is invalid.", "error");
      return;
    }
    if (!contract) return;
    await handleTx(
      contract.setKeeper(admin.keeperAddress, false),
      "Keeper removed."
    );
  }, [admin.keeperAddress, contract, handleTx, showToast]);

  const handleSetAnnualRateBPS = useCallback(async () => {
    if (!admin.annualRate) {
      showToast("Annual Rate BPS cannot be empty.", "error");
      return;
    }
    if (!contract) return;
    await handleTx(
      contract.setAnnualRateBPS(BigInt(admin.annualRate)),
      "Annual rate updated."
    );
  }, [admin.annualRate, contract, handleTx, showToast]);

  const handleSetOracleMaxAge = useCallback(async () => {
    if (!admin.oracleMaxAge) {
      showToast("Oracle Max Age cannot be empty.", "error");
      return;
    }
    if (!contract) return;
    await handleTx(
      contract.setOracleMaxAge(BigInt(admin.oracleMaxAge)),
      "Oracle max age updated."
    );
  }, [admin.oracleMaxAge, contract, handleTx, showToast]);

  // Set price source (optimistic UI update)
  const handleSetPriceSource = useCallback(
    async (source: "Manual" | "Chainlink") => {
      if (!contract) return;
      await handleTx(
        contract.setPriceSource(source === "Manual" ? 1 : 0),
        "Price source updated."
      );
      setIsManualSource(source === "Manual");
    },
    [contract, handleTx]
  );

  // Analyze carry
  const handleAnalyzeCarry = useCallback(async () => {
    if (!analysis.startDate || !analysis.endDate) {
      showToast("Please select both a start and end date.", "error");
      return;
    }
    if (oracleIsStale && !isManualSource) return;

    const d1 = new Date(analysis.startDate);
    const d2 = new Date(analysis.endDate);

    if (d1 >= d2) {
      showToast("Start date must be before end date.", "error");
      return;
    }

    setAnalysis((prev) => ({ ...prev, results: "loading" }));
    try {
      const ts1 = Math.floor(d1.getTime() / 1000);
      const ts2 = Math.floor(d2.getTime() / 1000);
      if (!contract) throw new Error("Contract not initialized");
      const [price1, price2] = await Promise.all([
        contract.priceFor(ts1) as Promise<bigint>,
        contract.priceFor(ts2) as Promise<bigint>,
      ]);

      const p1 = parseFloat(ethers.formatUnits(price1, 18));
      const p2 = parseFloat(ethers.formatUnits(price2, 18));
      const priceSpread = p2 - p1;
      const basisPoints = p1 > 0 ? (priceSpread / p1) * 10000 : 0;
      const daysBetween = (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24);
      const annualizedYield =
        p1 > 0 && daysBetween > 0
          ? (priceSpread / p1) * (365 / daysBetween) * 100
          : 0;

      setAnalysis((prev) => ({
        ...prev,
        results: {
          priceSpread,
          basisPoints,
          annualizedYield,
          startEndPrice: `${formatCurrency(p1)} / ${formatCurrency(p2)}`,
        },
      }));
    } catch (e: unknown) {
      console.error("Carry analysis error:", e);
      handleError(e as Error, "Analysis");
      setAnalysis((prev) => ({ ...prev, results: null }));
    }
  }, [
    analysis.startDate,
    analysis.endDate,
    oracleIsStale,
    isManualSource,
    contract,
    showToast,
    handleError,
  ]);

  // Effects for initialization and updates
  useEffect(() => {
    const eth = (window as any).ethereum;
    if (eth) {
      connectWallet();
      (eth as any).on("accountsChanged", () =>
        window.location.reload()
      );
      (eth as any).on("chainChanged", () =>
        window.location.reload()
      );
      return () => {
        const ethCleanup = (window as any).ethereum;
        if (ethCleanup) {
          (ethCleanup as any).removeListener("accountsChanged", () =>
            window.location.reload()
          );
          (ethCleanup as any).removeListener("chainChanged", () =>
            window.location.reload()
          );
        }
      };
    } else {
      showToast("Please install a web3 wallet like MetaMask.", "error", 5000);
    }
  }, [connectWallet, showToast]);

  useEffect(() => {
    if (contract && userAddress) {
      console.log("[Effect] contract & userAddress ready");
      checkAdminStatus();
      // Trigger initial data load once both are ready
      void reloadData();
    }
  }, [contract, userAddress, checkAdminStatus, reloadData]);

  useEffect(() => {
    if (activeTab === "trade" && !chartInstance.current) {
      initChart();
      fetchChartData();
    }
    if (activeTab === "admin" && isAdmin) {
      fetchAdminSettings();
    }
    console.log("[Effect] activeTab:", activeTab);
  }, [activeTab, isAdmin, initChart, fetchChartData, fetchAdminSettings]);

  useEffect(() => {
    if (activeTab === "trade") {
      if (!chartInstance.current && chartRef.current) {
        initChart();
      }
      if (chartInstance.current && !oracleIsStale) {
        fetchChartData();
      }
    } else {
      if (chartInstance.current) {
        chartInstance.current.destroy();
        chartInstance.current = null;
      }
    }

    return () => {
      if (chartInstance.current) {
        chartInstance.current.destroy();
        chartInstance.current = null;
      }
    };
  }, [activeTab, initChart, fetchChartData, oracleIsStale]);

  useEffect(() => {
    if (activeTab === "trade" && chartInstance.current && !oracleIsStale) {
      fetchChartData();
    }
  }, [
    trade.spread.impliedVolatility,
    trade.spread.ivEnabled,
    fetchChartData,
    activeTab,
    oracleIsStale,
  ]);

  useEffect(() => {
    debouncedGetOutrightQuote();
  }, [
    trade.outright.maturity,
    trade.outright.amount,
    trade.outright.slippagePercent,
    debouncedGetOutrightQuote,
  ]);

  useEffect(() => {
    debouncedGetSpreadQuote();
  }, [
    trade.spread.legs,
    trade.spread.impliedVolatility,
    trade.spread.ivEnabled,
    trade.spread.slippagePercent,
    debouncedGetSpreadQuote,
  ]);

  return (
    <Box sx={{ p: { xs: 2, md: 4 } }}>
      <Box
        sx={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          mb: 4,
        }}
      >
        <Typography
          variant="h4"
          sx={{ fontWeight: "bold", color: theme.palette.text.primary }}
        >
          IntelliGold Futures OTC RFQ
        </Typography>
        <Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
          <Chip
            label={status.message}
            color={status.type === "connected" ? "success" : "default"}
            icon={status.type === "connected" ? <TaskAltIcon /> : undefined}
            sx={{ fontWeight: "medium" }}
            aria-label={`Connection status: ${status.message}`}
          />
          {status.type !== "connected" && (
            <Button
              variant="contained"
              onClick={connectWallet}
              disabled={isLoading}
              aria-label="Connect wallet"
              sx={{
                bgcolor: "#0b3d91",
                textTransform: "none",
                fontSize: 14,
                color: "#FFFFFF",
                "&:hover": { bgcolor: "#083475" },
              }}
            >
              {isLoading ? (
                <CircularProgress size={24} color="inherit" />
              ) : (
                "Connect Wallet"
              )}
            </Button>
          )}
          {status.type === "connected" && (
            <Button
              variant="outlined"
              startIcon={<LogoutIcon />}
              onClick={disconnectWallet}
              aria-label="Disconnect wallet"
               sx={{
                bgcolor: "#0b3d91",
                textTransform: "none",
                fontSize: 14,
                color: "#FFFFFF",
                "&:hover": { bgcolor: "#083475" },
              }}
            >
              Disconnect
            </Button>
          )}
        </Box>
      </Box>

      {oracleIsStale && !isManualSource && (
        <Paper
          sx={{
            p: 2,
            mb: 4,
            bgcolor: theme.palette.error.light,
            color: theme.palette.error.contrastText,
            border: "1px solid #D4DBE3",
            boxShadow: "none",
          }}
          role="alert"
          aria-label="Oracle warning"
        >
          <Typography variant="body1" sx={{ fontWeight: "medium" }}>
            Oracle Warning
          </Typography>
          <Typography variant="body2">
            The Chainlink price feed is stale. Trading and analysis are disabled
            until the oracle updates or an admin switches to a manual price
            source in the Admin Panel.
          </Typography>
        </Paper>
      )}

      {userAddress && (
        <main>
          <Tabs
  value={activeTab}
  onChange={(_, newValue: "portfolio" | "trade" | "admin") =>
    setActiveTab(newValue)
  }
            sx={{
               mb: 4 , 
               "& .MuiTab-root": {
                    textTransform: "none",  
                    fontSize: 16,
                  },
                 }}
  aria-label="Navigation tabs"
>
  <Tab
    label="Portfolio"
    value="portfolio"
    aria-label="Portfolio tab"
  />
  <Tab label="Trade" value="trade" aria-label="Trade tab" />
  {isAdmin && (
    <Tab
      label="Admin Panel"
      value="admin"
      aria-label="Admin panel tab"
    />
  )}
</Tabs>

          {activeTab === "portfolio" && (
            <Box>
              <Box
                sx={{
                  display: "grid",
                  gap: 2,
                  gridTemplateColumns: {
                    xs: "1fr",
                    sm: "1fr 1fr",
                    md: "1fr 1fr 1fr",
                  },
                  mb: 4,
                }}
              >
                <Paper
                  elevation={0}
                  sx={{
                    p: 2,
                    textAlign: "center",
                    bgcolor: "#FFFFFF",
                    color: theme.palette.text.primary,
                    border: "1px solid #E0E0E0",
                    boxShadow: "none",
                  }}
                >
                  <Typography variant="body2" sx={{ fontWeight: "medium" }}>
                    Unrealized P/L
                  </Typography>
                  <Typography
                    variant="h5"
                    sx={{
                      fontWeight: "bold",
                      color:
                        portfolio.isLoading || (oracleIsStale && !isManualSource)
                          ? theme.palette.text.primary
                          : getPnlColor(portfolio.pnl),
                    }}
                  >
                    {portfolio.isLoading
                      ? "Loading..."
                      : oracleIsStale && !isManualSource
                      ? "N/A"
                      : formatPnlWithSign(portfolio.pnl)}
                  </Typography>
                </Paper>
                <Paper
                  elevation={0}
                  sx={{
                    p: 2,
                    textAlign: "center",
                    bgcolor: "#FFFFFF",
                    color: theme.palette.text.primary,
                    border: "1px solid #E0E0E0",
                    boxShadow: "none",
                  }}
                >
                  <Typography variant="body2" sx={{ fontWeight: "medium" }}>
                    Active Positions
                  </Typography>
                  <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                    {portfolio.isLoading
                      ? "Loading..."
                      : portfolio.activePositions}
                  </Typography>
                </Paper>
                <Paper
                  elevation={0}
                  sx={{
                    p: 2,
                    textAlign: "center",
                    bgcolor: "#FFFFFF",
                    color: theme.palette.text.primary,
                    border: "1px solid #E0E0E0",
                    boxShadow: "none",
                  }}
                >
                  <Typography variant="body2" sx={{ fontWeight: "medium" }}>
                    Spot Gold Price
                  </Typography>
                  <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                    {portfolio.isLoading
                      ? "Loading..."
                      : oracleIsStale && !isManualSource
                      ? "Stale"
                      : formatCurrency(portfolio.spotPrice, 2)}
                  </Typography>
                </Paper>
              </Box>

              <TableContainer
                component={Paper}
                sx={{ border: "1px solid #D4DBE3", boxShadow: "none" }}
              >
                <Table aria-label="Portfolio positions table">
                  <TableHead>
                    <TableRow>
                      <TableCell>ID</TableCell>
                      <TableCell>Type</TableCell>
                      <TableCell>Legs</TableCell>
                      <TableCell>Long Amount</TableCell>
                      <TableCell>Current P/L</TableCell>
                      <TableCell>SL / TP</TableCell>
                      <TableCell>Action</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {portfolio.isLoading ? (
                      <TableRow>
                        <TableCell colSpan={7} align="center">
                          Loading portfolio...
                        </TableCell>
                      </TableRow>
                    ) : oracleIsStale && !isManualSource ? (
                      <TableRow>
                        <TableCell colSpan={7} align="center">
                          Portfolio data unavailable due to stale oracle. If you
                          are admin, switch to manual source in Admin Panel.
                        </TableCell>
                      </TableRow>
                    ) : portfolio.positions.length === 0 ? (
                      <TableRow>
                        <TableCell colSpan={7} align="center">
                          No active positions.
                        </TableCell>
                      </TableRow>
                    ) : (
                      portfolio.positions.map((position) => (
                        <TableRow key={position.positionId}>
                          <TableCell>{position.positionId}</TableCell>
                        <TableCell>
                          {renderPositionTypeChip(position.positionType)}
                        </TableCell>
                          <TableCell>
                            <Box sx={{ display: "flex", flexDirection: "column", gap: 0.5 }}>
                              {position.legs.map((leg, idx) => (
                                <Typography
                                  key={idx}
                                  variant="body2"
                                  sx={{
                                    fontWeight: 600,
                                    color: leg.isLong ? "#10B981" : "#EF4444",
                                  }}
                                >
                              <Typography
                                component="span"
                                variant="body2"
                                sx={{
                                  color: leg.isLong ? "#10B981" : "#EF4444",
                                  fontWeight: 700,
                                  mr: 0.5,
                                }}
                              >
                                {leg.isLong ? "Long" : "Short"}
                              </Typography>
                              <Typography
                                component="span"
                                variant="body2"
                                sx={{ fontWeight: 500, color: "#374151" }}
                              >
                                {`${leg.amountIGLD.toFixed(2)} @ ${leg.maturity}`}
                              </Typography>{" "}
                              <Typography
                                component="span"
                                variant="body2"
                                sx={{ color: "text.secondary", fontWeight: 500 }}
                              >
                                (Entry: {formatCurrency(leg.entryPrice)})
                              </Typography>
                                </Typography>
                              ))}
                            </Box>
                          </TableCell>
                          <TableCell>
                            {position.legs
                              .reduce(
                                (sum, leg) =>
                                  sum +
                                  (leg.isLong
                                    ? leg.amountIGLD
                                    : -leg.amountIGLD),
                                0
                              )
                              .toFixed(2)}{" "}
                            IGLD
                          </TableCell>
                          <TableCell>
                            {oracleIsStale && !isManualSource ? (
                              "N/A"
                            ) : (
                              <Typography
                                component="span"
                                sx={{
                                  color:
                                    position.pnl > 0
                                      ? theme.palette.success.main
                                      : position.pnl < 0
                                      ? theme.palette.error.main
                                      : "#6B7280",
                                  fontWeight: 600,
                                  fontFamily: "monospace",
                                }}
                              >
                                {formatPnlWithSign(position.pnl)}
                              </Typography>
                            )}
                          </TableCell>
                          <TableCell>
                            {formatSLTP(position.stopLossPrice, "SL")},{" "}
                            {formatSLTP(position.takeProfitPrice, "TP")}
                          </TableCell>
                          <TableCell>
                            <Button
                              variant="contained"
                              size="small"
                              disableElevation
                              onClick={() => handleRequestClosePosition(position)}
                              disabled={
                                (oracleIsStale && !isManualSource) ||
                                (isCloseProcessing &&
                                  pendingClosePosition?.positionId === position.positionId)
                              }
                              aria-label={`Close position ${position.positionId}`}
                              sx={{
                                borderRadius: "8px",
                                px: 2.5,
                                fontWeight: 600,
                                textTransform: "none",
                                color: "#B91C1C",
                                backgroundImage:
                                  "linear-gradient(180deg, rgba(254, 236, 236, 0.96) 0%, rgba(252, 219, 219, 0.96) 100%)",
                                border: "1px solid rgba(248, 113, 113, 0.35)",
                                boxShadow: "0px 3px 8px rgba(190, 49, 68, 0.16)",
                                '&:hover': {
                                  backgroundImage:
                                    "linear-gradient(180deg, rgba(253, 222, 222, 1) 0%, rgba(251, 209, 209, 1) 100%)",
                                  borderColor: "rgba(220, 38, 38, 0.4)",
                                  boxShadow: "0px 4px 12px rgba(190, 49, 68, 0.18)",
                                },
                                '&:active': {
                                  backgroundImage:
                                    "linear-gradient(180deg, rgba(252, 210, 210, 1) 0%, rgba(249, 196, 196, 1) 100%)",
                                  boxShadow: "0px 2px 6px rgba(190, 49, 68, 0.2)",
                                },
                                '&:focus-visible': {
                                  outline: "2px solid rgba(244, 63, 94, 0.45)",
                                  outlineOffset: "2px",
                                },
                              }}
                            >
                              {isCloseProcessing &&
                              pendingClosePosition?.positionId === position.positionId
                                ? "Closing..."
                                : "Close"}
                            </Button>
                          </TableCell>
                        </TableRow>
                      ))
                    )}
                  </TableBody>
                </Table>
              </TableContainer>
            </Box>
          )}

          {activeTab === "trade" && (
            <Box>
              <Typography
                variant="h5"
                sx={{
                  fontWeight: "bold",
                  mb: 3,
                  color: theme.palette.text.primary,
                }}
              >
                Gold Futures Curve
              </Typography>
              <Paper
                sx={{
                  p: 4,
                  mb: 4,
                  height: 400,
                  border: "1px solid #D4DBE3",
                  boxShadow: "none",
                }}
              >
                {oracleIsStale && !isManualSource ? (
                  <Typography variant="body1" color="error" align="center">
                    Graph data unavailable due to stale oracle. If you are
                    admin, switch to manual source in Admin Panel.
                  </Typography>
                ) : (
                  <canvas
                    ref={chartRef}
                    aria-label="Gold futures curve chart"
                  />
                )}
              </Paper>

              <Typography
                variant="h5"
                sx={{
                  fontWeight: "bold",
                  mb: 3,
                  color: theme.palette.text.primary,
                }}
              >
                Interactive Carry Analysis
              </Typography>
              <Paper
                sx={{
                  p: 4,
                  mb: 4,
                  border: "1px solid #D4DBE3",
                  boxShadow: "none",
                }}
              >
                <Box
                  sx={{
                    display: "flex",
                    flexDirection: { xs: "column", sm: "row" },
                    gap: 2,
                    mb: 4,
                  }}
                >
                  <TextField
                    label="Start Date"
                    type="date"
                    value={analysis.startDate}
                    onChange={(e: ChangeEvent<HTMLInputElement>) =>
                      setAnalysis({ ...analysis, startDate: e.target.value })
                    }
                    InputLabelProps={{ shrink: true }}
                    sx={{ flex: 1 }}
                    aria-label="Start date for carry analysis"
                  />
                  <TextField
                    label="End Date"
                    type="date"
                    value={analysis.endDate}
                    onChange={(e: ChangeEvent<HTMLInputElement>) =>
                      setAnalysis({ ...analysis, endDate: e.target.value })
                    }
                    InputLabelProps={{ shrink: true }}
                    sx={{ flex: 1 }}
                    aria-label="End date for carry analysis"
                  />
                  <Button
                    variant="contained"
                    onClick={handleAnalyzeCarry}
                    disabled={oracleIsStale && !isManualSource}
                    // sx={{ alignSelf: { xs: "stretch", sm: "flex-start" } }}
                    aria-label="Analyze carry"
                    sx={{
                bgcolor: "#0b3d91",
                textTransform: "none",
                fontSize: 14,fontWeight:"bold",
                color: "#FFFFFF",
                "&:hover": { bgcolor: "#083475" },
              }}
                  >
                    Analyze Carry
                  </Button>
                </Box>
                {analysis.results === "loading" ? (
                  <Typography variant="body1">Loading analysis...</Typography>
                ) : (
                  analysis.results && (
                    <Box
                      sx={{
                        display: "grid",
                        gap: 2,
                        gridTemplateColumns: {
                          xs: "1fr",
                          sm: "1fr 1fr",
                          md: "repeat(4, 1fr)",
                        },
                      }}
                    >
                      <Paper
                        elevation={0}
                        sx={{
                          p: 2,
                          textAlign: "center",
                          bgcolor: "#e3f2fd",
                          color: "#0d47a1",
                        }}
                      >
                        <Typography
                          variant="body2"
                          sx={{ fontWeight: "medium" }}
                        >
                          Price Spread
                        </Typography>
                        <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                          {formatCurrency(analysis.results.priceSpread, 2)}
                        </Typography>
                      </Paper>
                      <Paper
                        elevation={0}
                        sx={{
                          p: 2,
                          textAlign: "center",
                          bgcolor: "#e8f5e9",
                          color: "#1b5e20",
                        }}
                      >
                        <Typography
                          variant="body2"
                          sx={{ fontWeight: "medium" }}
                        >
                          Basis Points
                        </Typography>
                        <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                          {`${analysis.results.basisPoints.toFixed(2)} bps`}
                        </Typography>
                      </Paper>
                      <Paper
                        elevation={0}
                        sx={{
                          p: 2,
                          textAlign: "center",
                          bgcolor: "#ede7f6",
                          color: "#311b92",
                        }}
                      >
                        <Typography
                          variant="body2"
                          sx={{ fontWeight: "medium" }}
                        >
                          Annualized Yield
                        </Typography>
                        <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                          {`${analysis.results.annualizedYield.toFixed(2)}%`}
                        </Typography>
                      </Paper>
                      <Paper
                        elevation={0}
                        sx={{
                          p: 2,
                          textAlign: "center",
                          bgcolor: theme.palette.grey[200],
                          color: "text.primary",
                        }}
                      >
                        <Typography
                          variant="body2"
                          sx={{ fontWeight: "medium" }}
                        >
                          Start / End Price
                        </Typography>
                        <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                          {analysis.results.startEndPrice}
                        </Typography>
                      </Paper>
                    </Box>
                  )
                )}
              </Paper>
              <Divider sx={{ my: 4 }} />
              <Box
                sx={{
                  display: "flex",
                  flexDirection: { xs: "column", md: "row" },
                  gap: 4,
                }}
              >
                <Paper
                  sx={{
                    p: 4,
                    flex: 1,
                    border: "1px solid #D4DBE3",
                    boxShadow: "none",
                  }}
                >
                  <Typography
                    variant="h6"
                    sx={{ mb: 2, color: theme.palette.text.primary }}
                  >
                    Outright Trade (Long Only)
                  </Typography>
                  <TextField
                    label="Maturity Date"
                    type="date"
                    value={trade.outright.maturity}
                    onChange={(e: ChangeEvent<HTMLInputElement>) =>
                      setTrade({
                        ...trade,
                        outright: {
                          ...trade.outright,
                          maturity: e.target.value,
                        },
                      })
                    }
                    InputLabelProps={{ shrink: true }}
                    fullWidth
                    sx={{ mb: 2 }}
                    aria-label="Maturity date for outright trade"
                  />
                  <TextField
                    label="Amount (IGLD)"
                    type="number"
                    value={trade.outright.amount}
                    onChange={(e: ChangeEvent<HTMLInputElement>) =>
                      setTrade({
                        ...trade,
                        outright: { ...trade.outright, amount: e.target.value },
                      })
                    }
                    placeholder="e.g., 1.0"
                    fullWidth
                    sx={{ mb: 2 }}
                    inputProps={{ min: 0, step: 0.1 }}
                    aria-label="Amount for outright trade"
                  />
                  <Box sx={{ mb: 2 }}>
                    <Typography variant="body2" sx={{ mb: 1 }}>
                      Max Cost (with slippage)
                    </Typography>
                    <Box sx={{ display: "flex", gap: 2 }}>
                      <TextField
                        value={trade.outright.maxCost}
                        InputProps={{ readOnly: true }}
                        placeholder="e.g., 1000"
                        fullWidth
                        aria-label="Max cost for outright trade (calculated)"
                      />
                      <Tooltip title="Percentage allowance for price changes during transaction">
                        <TextField
                          type="number"
                          value={trade.outright.slippagePercent}
                          onChange={(e: ChangeEvent<HTMLInputElement>) =>
                            setTrade({
                              ...trade,
                              outright: {
                                ...trade.outright,
                                slippagePercent: e.target.value,
                              },
                            })
                          }
                          InputProps={{
                            endAdornment: "%",
                            inputProps: { min: 0, max: 10, step: 0.1 },
                          }}
                          sx={{ width: 120 }}
                          aria-label="Slippage percentage for outright trade"
                        />
                      </Tooltip>
                    </Box>
                    <FormHelperText>
                      Max cost is automatically calculated based on the amount
                      and futures price, including slippage.
                    </FormHelperText>
                  </Box>
                  <Box sx={{ mb: 2 }}>
                    <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                      <IconButton
                        onClick={() => setExpanded(!expanded)}
                        aria-label={
                          expanded
                            ? "Collapse advanced options"
                            : "Expand advanced options"
                        }
                      >
                        <ExpandMoreIcon
                          sx={{
                            transform: expanded
                              ? "rotate(180deg)"
                              : "rotate(0deg)",
                          }}
                        />
                      </IconButton>
                      <Typography variant="body2">Advanced Options</Typography>
                    </Box>
                    <Collapse in={expanded}>
                      <Box
                        sx={{
                          display: "flex",
                          flexDirection: { xs: "column", sm: "row" },
                          gap: 2,
                          mt: 2,
                        }}
                      >
                        <Tooltip title="Price at which to automatically sell to limit losses">
                          <TextField
                            label="Stop-Loss"
                            type="number"
                            value={trade.outright.sl}
                            onChange={(e: ChangeEvent<HTMLInputElement>) =>
                              setTrade({
                                ...trade,
                                outright: {
                                  ...trade.outright,
                                  sl: e.target.value,
                                },
                              })
                            }
                            placeholder="e.g., 1800"
                            fullWidth
                            aria-label="Stop-loss price for outright trade"
                          />
                        </Tooltip>
                        <Tooltip title="Price at which to automatically sell to lock in profits">
                          <TextField
                            label="Take-Profit"
                            type="number"
                            value={trade.outright.tp}
                            onChange={(e: ChangeEvent<HTMLInputElement>) =>
                              setTrade({
                                ...trade,
                                outright: {
                                  ...trade.outright,
                                  tp: e.target.value,
                                },
                              })
                            }
                            placeholder="e.g., 2000"
                            fullWidth
                            aria-label="Take-profit price for outright trade"
                          />
                        </Tooltip>
                      </Box>
                    </Collapse>
                  </Box>
                  <FormControl fullWidth sx={{ mb: 2 }}>
                    <InputLabel id="outright-payment-token-label">
                      Pay With
                    </InputLabel>
                    <Select
                      labelId="outright-payment-token-label"
                      value={trade.outright.paymentToken}
                      onChange={(e: SelectChangeEvent) =>
                        setTrade({
                          ...trade,
                          outright: {
                            ...trade.outright,
                            paymentToken: e.target.value,
                          },
                        })
                      }
                      label="Pay With"
                      aria-label="Payment token for outright trade"
                    >
                      <MenuItem value={IUSD_TOKEN_ADDRESS}>IUSD</MenuItem>
                      <MenuItem value={ADDRESS_ZERO}>xDAI</MenuItem>
                    </Select>
                  </FormControl>
                  <Button
                    variant="contained"
                    onClick={handleExecuteOutrightTrade}
                    disabled={
                      (oracleIsStale && !isManualSource) || isOutrightTrading
                    }
                     sx={{
                      py: 1.5,
                      bgcolor: "#0b3d91",
                      textTransform: "none",
                      fontWeight: "bold",
                      fontSize: 14,
                      "&:hover": { bgcolor: "#083475" },
                    }}
                    aria-label="Execute outright trade"
                  >
                      Execute Outright Trade
                  </Button>
                </Paper>
                <Paper
                  sx={{
                    p: 4,
                    flex: 1,
                    border: "1px solid #D4DBE3",
                    boxShadow: "none",
                  }}
                >
                  <Typography
                    variant="h6"
                    sx={{ mb: 2, color: theme.palette.text.primary }}
                  >
                    Multi-Leg Spread Trade
                  </Typography>
                  <Box sx={{ mb: 2 }}>
                    <Tooltip title="Simulate implied volatility for frontend analysis (not used on-chain)">
                      <Box
                        sx={{ display: "flex", alignItems: "center", gap: 2 }}
                      >
                        <FormControlLabel
                          control={
                            <Checkbox
                              checked={trade.spread.ivEnabled}
                              onChange={(e: ChangeEvent<HTMLInputElement>) =>
                                setTrade({
                                  ...trade,
                                  spread: {
                                    ...trade.spread,
                                    ivEnabled: e.target.checked,
                                  },
                                })
                              }
                              aria-label="Enable implied volatility simulation"
                            />
                          }
                          label="Implied Volatility (IV) Simulation"
                        />
                        <TextField
                          type="number"
                          value={trade.spread.impliedVolatility}
                          onChange={(e: ChangeEvent<HTMLInputElement>) =>
                            setTrade({
                              ...trade,
                              spread: {
                                ...trade.spread,
                                impliedVolatility: e.target.value,
                              },
                            })
                          }
                          disabled={!trade.spread.ivEnabled}
                          InputProps={{
                            endAdornment: "%",
                            inputProps: { min: 0, step: 0.1 },
                          }}
                          sx={{ width: 120 }}
                          aria-label="Implied volatility for spread trade"
                        />
                         
                            </Box>
                            </Tooltip>
                          <Box sx={{ flex: 1, minWidth: 240, mt: 1 }}>
                          <Slider
                            aria-label="Implied volatility slider"
                            disabled={!trade.spread.ivEnabled}
                            value={Number(trade.spread.impliedVolatility || 0)}
                            onChange={(_, val) => {
                              const iv = Array.isArray(val) ? val[0] : val;
                              const nextIv =
                                typeof trade.spread.impliedVolatility === "number"
                                  ? iv
                                  : String(iv);
                              setTrade({
                                ...trade,
                                spread: { ...trade.spread, impliedVolatility: nextIv },
                              });
                            }}
                            step={0.1}
                            min={0}
                            max={200}
                            valueLabelDisplay="auto"
                          />
                        </Box>
                   
                    <FormHelperText>
                      Note: IV is for frontend analysis only. The final on-chain
                      transaction price is determined by the contract's fixed
                      cost-of-carry model.
                    </FormHelperText>
                  </Box>
                  {trade.spread.legs.map((leg, index) => (
                    <Box
                      key={index}
                      sx={{
                        display: "flex",
                        flexDirection: { xs: "column", sm: "row" },
                        gap: 2,
                        alignItems: { sm: "center" },
                        mb: 2,
                      }}
                    >
                      <FormControl sx={{ width: { xs: "100%", sm: 120 } }}>
                        <InputLabel id={`leg-direction-${index}`}>
                          Direction
                        </InputLabel>
                        <Select
                          labelId={`leg-direction-${index}`}
                          value={leg.isLong ? "true" : "false"}
                          onChange={(e: SelectChangeEvent) => {
                            const newLegs = [...trade.spread.legs];
                            newLegs[index].isLong = e.target.value === "true";
                            setTrade({
                              ...trade,
                              spread: { ...trade.spread, legs: newLegs },
                            });
                          }}
                          label="Direction"
                          aria-label={`Direction for leg ${index + 1}`}
                        >
                          <MenuItem value="true">Long</MenuItem>
                          <MenuItem value="false">Short</MenuItem>
                        </Select>
                      </FormControl>
                      <Tooltip title="Select the maturity date for this leg">
                        <TextField
                          label="Maturity"
                          type="date"
                          value={leg.maturity}
                          onChange={(e: ChangeEvent<HTMLInputElement>) => {
                            const newLegs = [...trade.spread.legs];
                            newLegs[index].maturity = e.target.value;
                            setTrade({
                              ...trade,
                              spread: { ...trade.spread, legs: newLegs },
                            });
                          }}
                          InputLabelProps={{ shrink: true }}
                          sx={{ flex: 1 }}
                          aria-label={`Maturity date for leg ${index + 1}`}
                        />
                      </Tooltip>
                      <Tooltip title="Enter the amount of gold tokens (IGLD) for this leg">
                        <TextField
                          label="Amount (IGLD)"
                          type="number"
                          value={leg.amountIGLD}
                          onChange={(e: ChangeEvent<HTMLInputElement>) => {
                            const newLegs = [...trade.spread.legs];
                            newLegs[index].amountIGLD = e.target.value;
                            setTrade({
                              ...trade,
                              spread: { ...trade.spread, legs: newLegs },
                            });
                          }}
                          placeholder="e.g., 1.0"
                          sx={{ flex: 1 }}
                          inputProps={{ min: 0, step: 0.1 }}
                          aria-label={`Amount for leg ${index + 1}`}
                        />
                      </Tooltip>
                      {index > 1 && (
                        <Button
                          variant="outlined"
                          color="error"
                          onClick={() => {
                            const newLegs = trade.spread.legs.filter(
                              (_, i) => i !== index
                            );
                            setTrade({
                              ...trade,
                              spread: { ...trade.spread, legs: newLegs },
                            });
                          }}
                          aria-label={`Remove leg ${index + 1}`}
                        >
                          ×
                        </Button>
                      )}
                    </Box>
                  ))}
                  <Button
                    variant="outlined"
                    onClick={() =>
                      setTrade({
                        ...trade,
                        spread: {
                          ...trade.spread,
                          legs: [
                            ...trade.spread.legs,
                            { maturity: "", amountIGLD: "", isLong: true },
                          ],
                        },
                      })
                    }
                    sx={{ alignSelf: "flex-start", mb: 2 }}
                    aria-label="Add new leg to spread trade"
                  >
                    Add Leg
                  </Button>
                  <FormControl fullWidth sx={{ mb: 2 }}>
                    <InputLabel id="spread-payment-token-label">
                      Pay With / Receive In
                    </InputLabel>
                    <Select
                      labelId="spread-payment-token-label"
                      value={trade.spread.paymentToken}
                      onChange={(e: SelectChangeEvent) =>
                        setTrade({
                          ...trade,
                          spread: {
                            ...trade.spread,
                            paymentToken: e.target.value,
                          },
                        })
                      }
                      label="Pay With / Receive In"
                      aria-label="Payment token for spread trade"
                    >
                      <MenuItem value={IUSD_TOKEN_ADDRESS}>IUSD</MenuItem>
                      <MenuItem value={ADDRESS_ZERO}>xDAI</MenuItem>
                    </Select>
                  </FormControl>
                  <Box sx={{ mb: 2 }}>
                    <Typography variant="body2" sx={{ mb: 1 }}>
                      Max Cost / Min Credit (with slippage)
                    </Typography>
                    <Box
                      sx={{
                        display: "flex",
                        flexDirection: { xs: "column", sm: "row" },
                        gap: 2,
                        alignItems: { sm: "center" },
                      }}
                    >
                      <Tooltip title="Maximum cost or minimum credit for the spread trade">
                        <TextField
                          value={trade.spread.maxCost || trade.spread.minCredit}
                          InputProps={{ readOnly: true }}
                          placeholder="e.g., 1000"
                          fullWidth
                          aria-label="Max cost or min credit for spread trade"
                        />
                      </Tooltip>
                      <Tooltip title="Percentage allowance for price changes during transaction">
                        <TextField
                          type="number"
                          value={trade.spread.slippagePercent}
                          onChange={(e: ChangeEvent<HTMLInputElement>) =>
                            setTrade({
                              ...trade,
                              spread: {
                                ...trade.spread,
                                slippagePercent: e.target.value,
                              },
                            })
                          }
                          InputProps={{
                            endAdornment: "%",
                            inputProps: { min: 0, max: 10, step: 0.1 },
                          }}
                          sx={{ width: { xs: "100%", sm: 120 } }}
                          aria-label="Slippage percentage for spread trade"
                        />
                      </Tooltip>
                    </Box>
                    <FormHelperText>
                      Transaction will fail if the cost exceeds this amount due
                      to price changes.
                    </FormHelperText>
                    <Box sx={{ mb: 0 }}>
                      {!spreadQuote.isCalculating && spreadQuote.error && (
                        <Typography
                          variant="body2"
                          sx={{
                            color: theme.palette.error.main,
                            textAlign: "center",
                          }}
                        >
                          {spreadQuote.error}
                        </Typography>
                      )}
                      {!spreadQuote.error && spreadQuote.netCost !== null && (
                        <Paper
                          elevation={0}
                          sx={{
                            p: 2,
                            border: "1px solid #D4DBE3",
                            borderRadius: 1,
                            textAlign: "center",
                            backgroundColor: "#F7FAFC",
                          }}
                        >
                          <Typography
                            variant="body2"
                            sx={{
                              color: theme.palette.text.secondary,
                              textAlign: "center",
                              mb: 1,
                            }}
                          >
                            Estimated Net Cost/Credit (with IV)
                          </Typography>

                          {spreadQuote.isCalculating ? (
                            <Typography variant="body2">
                              Calculating...
                            </Typography>
                          ) : (
                            <Typography
                              variant="body1"
                              sx={{
                                fontWeight: "bold",
                                color: theme.palette.text.primary,
                                textAlign: "center",
                              }}
                            >
                              {spreadQuote.netCost > BigInt(0)
                                ? "Debit:"
                                : "Debit:"}{" "}
                              $
                              {parseFloat(
                                spreadQuote.displayCost.replace(/[^0-9.]/g, "")
                              ).toFixed(2)}
                            </Typography>
                          )}
                        </Paper>
                      )}
                    </Box>
                  </Box>
                  <Button
                    variant="contained"
                    onClick={handleExecuteSpreadTrade}
                    disabled={
                      (oracleIsStale && !isManualSource) || isSpreadTrading
                    }
                    sx={{
                      py: 1.5,
                      bgcolor: "#0b3d91",
                      textTransform: "none",
                      fontWeight: "bold",
                      fontSize: "14px",
                      "&:hover": { bgcolor: "#083475" },
                    }}
                    aria-label="Execute spread trade"
                  >
                      Execute Spread Trade
                  </Button>
                </Paper>
              </Box>
            </Box>
          )}

          {activeTab === "admin" && isAdmin && (
            <Box>
              <Typography
                variant="h5"
                sx={{
                  fontWeight: "bold",
                  mb: 3,
                  color: theme.palette.text.primary,
                }}
              >
                Admin Controls
              </Typography>
              <Paper
                sx={{
                  p: 4,
                  mb: 4,
                  border: "1px solid #D4DBE3",
                  boxShadow: "none",
                }}
              >
                <Typography
                  variant="h6"
                  sx={{ mb: 2, color: theme.palette.text.primary }}
                >
                  Pricing Controls
                </Typography>
                <Box sx={{ display: "flex", flexDirection: "column", gap: 3 }}>
                  <FormControl fullWidth>
                    <InputLabel id="spot-price-source-label">
                      Spot Price Source
                    </InputLabel>
                    <Select
                      labelId="spot-price-source-label"
                      value={isManualSource ? "Manual" : "Chainlink"}
                      onChange={(e: SelectChangeEvent) => {
                        void handleSetPriceSource(
                          (e.target.value as "Manual" | "Chainlink")
                        );
                      }}
                      label="Spot Price Source"
                      aria-label="Select spot price source"
                    >
                      <MenuItem value="Chainlink">Chainlink</MenuItem>
                      <MenuItem value="Manual">Manual</MenuItem>
                    </Select>
                  </FormControl>
                  {isManualSource && (
                    <>
                      <Tooltip title="Set the manual spot price for gold in USD">
                        <TextField
                          label="Manual Spot Price (USD)"
                          type="number"
                          value={admin.manualSpotPrice}
                          onChange={(e: ChangeEvent<HTMLInputElement>) =>
                            setAdmin({
                              ...admin,
                              manualSpotPrice: e.target.value,
                            })
                          }
                          placeholder="e.g., 2000"
                          fullWidth
                          inputProps={{ min: 0, step: 0.01 }}
                          aria-label="Manual spot price for gold"
                        />
                      </Tooltip>
                      <Button
                        variant="contained"
                        onClick={handleSetManualSpotPrice}
                        disabled={!admin.manualSpotPrice || Number(admin.manualSpotPrice) <= 0}
                        sx={{ alignSelf: "flex-start", mt: 1 }}
                        aria-label="Set manual spot price"
                      >
                        Set Price
                      </Button>
                    </>
                  )}
                </Box>
              </Paper>
              <Paper
                sx={{ p: 4, border: "1px solid #D4DBE3", boxShadow: "none" }}
              >
                <Typography
                  variant="h6"
                  sx={{ mb: 2, color: theme.palette.text.primary }}
                >
                  System Settings
                </Typography>
                <Box sx={{ display: "flex", flexDirection: "column", gap: 3 }}>
                  <Tooltip title="Maximum age of oracle data in seconds before it's considered stale">
                    <TextField
                      label="Oracle Max Age (seconds)"
                      type="number"
                      value={admin.oracleMaxAge}
                      onChange={(e: ChangeEvent<HTMLInputElement>) =>
                        setAdmin({ ...admin, oracleMaxAge: e.target.value })
                      }
                      placeholder="e.g., 3600"
                      fullWidth
                      inputProps={{ min: 0 }}
                      aria-label="Oracle max age in seconds"
                    />
                  </Tooltip>
                  <Button
                    variant="contained"
                    onClick={handleSetOracleMaxAge}
                    sx={{ alignSelf: "flex-start" }}
                    aria-label="Set oracle max age"
                  >
                    Set Max Age
                  </Button>
                  <Tooltip title="Annual interest rate in basis points (1 BPS = 0.01%)">
                    <TextField
                      label="Annual Rate (BPS)"
                      type="number"
                      value={admin.annualRate}
                      onChange={(e: ChangeEvent<HTMLInputElement>) =>
                        setAdmin({ ...admin, annualRate: e.target.value })
                      }
                      placeholder="e.g., 500"
                      fullWidth
                      inputProps={{ min: 0 }}
                      aria-label="Annual rate in basis points"
                    />
                  </Tooltip>
                  <Button
                    variant="contained"
                    onClick={handleSetAnnualRateBPS}
                    sx={{ alignSelf: "flex-start" }}
                    aria-label="Set annual rate"
                  >
                    Set Rate
                  </Button>
                  <Tooltip title="Ethereum address of the keeper to manage the contract">
                    <TextField
                      label="Keeper Address"
                      value={admin.keeperAddress}
                      onChange={(e: ChangeEvent<HTMLInputElement>) =>
                        setAdmin({ ...admin, keeperAddress: e.target.value })
                      }
                      placeholder="e.g., 0x1234...abcd"
                      fullWidth
                      aria-label="Keeper address"
                    />
                  </Tooltip>
                  <Box
                    sx={{
                      display: "flex",
                      flexDirection: { xs: "column", sm: "row" },
                      gap: 2,
                    }}
                  >
                    <Button
                      variant="contained"
                      onClick={handleAddKeeper}
                      sx={{ flex: 1 }}
                      aria-label="Add keeper"
                    >
                      Add Keeper
                    </Button>
                    <Button
                      variant="contained"
                      color="secondary"
                      onClick={handleRemoveKeeper}
                      sx={{ flex: 1 }}
                      aria-label="Remove keeper"
                    >
                      Remove Keeper
                    </Button>
                  </Box>
                </Box>
              </Paper>
            </Box>
          )}
        </main>
      )}

      <ConfirmCloseDialog
        open={Boolean(pendingClosePosition)}
        title="Close position"
        description={
          pendingClosePosition
            ? `Are you sure you want to close position #${pendingClosePosition.positionId} (${pendingClosePosition.positionType})?\nCurrent P/L: ${formatPnlWithSign(pendingClosePosition.pnl)}`
            : ""
        }
        confirmLabel="Close position"
        cancelLabel="Keep open"
        onConfirm={handleConfirmClosePosition}
        onCancel={handleCancelClosePosition}
        loading={isCloseProcessing}
      />

      <Snackbar
        open={toast.visible}
        autoHideDuration={4000}
        onClose={() => setToast({ ...toast, visible: false })}
        anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
        aria-label="Notification"
      >
        <Alert
          severity={toast.type}
          sx={{ width: "100%", border: "1px solid #D4DBE3", boxShadow: "none" }}
          aria-label={`Notification: ${toast.message}`}
        >
          {toast.message}
        </Alert>
      </Snackbar>
    </Box>
  );
};

export default IntelliTradeGnosisGold;
