import React, {
  useState,
  useEffect,
  useRef,
  useCallback,
  ChangeEvent,
  useMemo,
} from "react";
import {
  ethers,
  BrowserProvider,
  JsonRpcSigner,
  Contract,
  MaxUint256,
  ZeroAddress,
  Eip1193Provider,
} from "ethers";
import type { TransactionRequest, TransactionReceipt } 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,
  Tooltip,
  FormHelperText,
  Divider,
  Checkbox,
  FormControlLabel,
} from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { Logout as LogoutIcon } from "@mui/icons-material";
import { PRODUCTS, IUSD_TOKEN_ADDRESS, IUSD_ABI } from "../../../const";
import TaskAltIcon from "@mui/icons-material/TaskAlt";
import { useQuery } from "@apollo/client";
import { GET_CUSTOMER_ID } from "../../../graphql/query";
import { Slider } from "@mui/material";
import ConfirmCloseDialog from "../../../components/ConfirmCloseDialog";


const ADDRESS_ZERO = ethers.ZeroAddress;

// Constants from the script
const RFQ_CONTRACT_ADDRESS = PRODUCTS.SILVER.RFQ_CONTRACT_ADDRESS;
const ISILV_TOKEN_ADDRESS = PRODUCTS.SILVER.TOKEN_ADDRESS;
const RFQ_ABI = PRODUCTS.SILVER.RFQ_ABI;
const ISILV_TOKEN_ABI = PRODUCTS.SILVER.TOKEN_ABI;
const CLOSE_POSITION_INSUFFICIENT_FUNDS_SELECTOR = "0xe450d38c";

// Interfaces for types
interface Leg {
  maturity: string;
  amountISILV: 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;
  useSlTp: boolean;
  paymentToken: string;
  maxCost: string;
  slippagePercent: string;
}

interface SpreadLeg {
  maturity: string;
  amountISILV: 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";
  const formatted = Math.abs(value).toLocaleString("en-GB", {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  });
  return `${value < 0 ? "-" : ""}$${formatted}`;
};

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 toBigInt = (value: any): bigint => {
  if (typeof value === "bigint") return value;
  if (typeof value === "number") return BigInt(Math.trunc(value));
  if (typeof value === "string") return BigInt(value);
  if (value?.toString) return BigInt(value.toString());
  return BigInt(0);
};

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 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.";
};

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

// Error helpers (align with IntelliTradeGold)
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.";
  }
};

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) as string[];
          haystacks.push(...nested);
        } catch (_) {
          haystacks.push(body);
        }
      }
    }
  } catch {}
  return haystacks.some((s) => typeof s === "string" && s.toLowerCase().includes("execution reverted"));
};

const extractRevertHex = (err: any): string | null => {
  const candidates = [
    err?.data?.data,
    err?.data,
    err?.error?.data?.data,
    err?.error?.data,
    err?.info?.error?.data?.data,
    err?.info?.error?.data,
  ];

  for (const value of candidates) {
    if (typeof value === "string" && value.startsWith("0x") && value.length > 10) {
      return value;
    }
  }

  const bodies = [err?.body, err?.error?.body, err?.info?.body].filter(Boolean);
  for (const body of bodies) {
    if (typeof body !== "string") continue;
    try {
      const parsed = JSON.parse(body);
      const nested = [parsed?.error?.data?.data, parsed?.error?.data];
      for (const value of nested) {
        if (typeof value === "string" && value.startsWith("0x") && value.length > 10) {
          return value;
        }
      }
    } catch {
      // ignore malformed JSON bodies
    }
  }

  return null;
};

const interpretClosePositionLiquidityError = (err: any): string | null => {
  const hexData = extractRevertHex(err);
  if (
    !hexData ||
    !hexData.startsWith(CLOSE_POSITION_INSUFFICIENT_FUNDS_SELECTOR)
  ) {
    return null;
  }

  try {
    const abi = ethers.AbiCoder.defaultAbiCoder();
    const decoded = abi.decode(
      ["address", "uint256", "uint256"],
      `0x${hexData.slice(10)}`
    );
    const balanceWei = decoded[1] as bigint;
    const expectedWei = decoded[2] as bigint;

    const expected = ethers.formatUnits(expectedWei, 18);
    const shortfallWei =
      expectedWei > balanceWei ? expectedWei - balanceWei : BigInt(0);
    const shortfall = ethers.formatUnits(shortfallWei, 18);

    if (shortfallWei > BigInt(0)) {
      return `Close failed: the RFQ treasury needs ${shortfall} more IUSD (payout requires ${expected} IUSD). Please contact support.`;
    }
    return `Close failed: the RFQ treasury lacks sufficient IUSD liquidity (required payout ${expected} IUSD).`;
  } catch {
    return "Close failed: the RFQ treasury lacks sufficient IUSD liquidity.";
  }
};

// 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 safeSendClosePosition = async (
  contract: Contract,
  positionId: bigint,
  payoutToken: string,
  signer: JsonRpcSigner
): Promise<TransactionReceipt> => {
  const populated = await (contract as any).closePosition.populateTransaction(
    positionId,
    payoutToken
  );

  const from = await signer.getAddress();
  const to: string =
    (populated.to as string | undefined) ??
    ((contract as unknown as { target?: string }).target || "");
  const data: string = populated.data as string;
  const value: bigint = (populated.value as bigint | undefined) ?? BigInt(0);

  if (!to || !data) {
    throw new Error("closePosition populateTransaction failed: missing to/data");
  }

  try {
    await (contract as any).closePosition.staticCall(positionId, payoutToken, {
      value,
    });
  } catch (err: any) {
    const liquidityMsg = interpretClosePositionLiquidityError(err);
    if (liquidityMsg) {
      throw new Error(liquidityMsg);
    }
    const msg = extractErrorMessage(err);
    throw new Error(`closePosition simulation failed: ${msg}`);
  }

  const unsignedTx: TransactionRequest = { to, data, value, from };
  const gas = await signer.estimateGas(unsignedTx);
  const gasLimit = (gas * BigInt(115)) / BigInt(100);

  const tx = await signer.sendTransaction({ ...unsignedTx, gasLimit });
  const receipt = await tx.wait();
  if (!receipt) {
    throw new Error("Transaction was dropped or replaced before confirmation.");
  }

  return receipt;
};

const IntelliTradeSilverWithoutSLTP = () => {
  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: "",
      useSlTp: false,
      paymentToken: IUSD_TOKEN_ADDRESS,
      maxCost: "0.00",
      slippagePercent: "0.5",
    },
    spread: {
      legs: [
        { maturity: "", amountISILV: "", isLong: true },
        { maturity: "", amountISILV: "", 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 [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);

  // Error handling
  const handleError = useCallback(
    (e: Error, context: string = "General") => {
      console.error(`${context} error:`, e);
      const message = extractErrorMessage(e);

      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 concise maturity error across variants (e.g., IGLDOTC / RFQ-S2)
      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:
              "Transaction failed: execution reverted: RFQ-S2: Maturity too soon",
            type: "error",
          });
          setTimeout(() => setToast((prev) => ({ ...prev, visible: false })), 8000);
          return;
        }
        if (/slippage[\s\S]*exceeds\s*max\s*cost/i.test(hay)) {
          setToast({
            visible: true,
            message:
              "Transaction failed: execution reverted: RFQ-S2: Slippage: Final cost exceeds maxCost",
            type: "error",
          });
          setTimeout(() => setToast((prev) => ({ ...prev, visible: false })), 8000);
          return;
        }
      } catch {}

      const lower = (message || "").toLowerCase();
      const conciseMsg = lower.includes("no matching fragment")
        ? "Error: Net short positions are not supported. Total long amount must be >= total short amount."
        : containsExecutionReverted(e, message)
        ? "Transaction error: execution reverted"
        : `${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();

        if (Number(network.chainId) !== 42161) {
          showToast("Please switch to Arbitrum One.", "error", 5000);
          setStatus({
            type: "error",
            message: "Please switch to Arbitrum One",
          });
          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);
        setBalance(ethBalance);
        setStatus({
          type: "connected",
          message: `Connected: ${shortenAddress(connectedAccount)}`,
        });

        const oracleOK = await checkOracleStatus();
        await reloadData();
        setIsLoading(false);
        return;
      }

      await new Promise((resolve) => setTimeout(resolve, 500));
      const accounts = await provider.send("eth_requestAccounts", []);
      if (accounts.length === 0) {
        showToast("No accounts found. Please unlock MetaMask.", "error", 5000);
        setStatus({ type: "error", message: "No accounts found" });
        setIsLoading(false);
        return;
      }

      const network = await provider.getNetwork();
      if (Number(network.chainId) !== 42161) {
        showToast("Please switch to Arbitrum One.", "error", 5000);
        setStatus({ type: "error", message: "Please switch to Arbitrum One" });
        setIsLoading(false);
        return;
      }

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

      setProvider(provider);
      setSigner(signer);
      setUserAddress(userAddress);
      setContract(contract);
      setBalance(ethBalance);
      setStatus({
        type: "connected",
        message: `Connected: ${shortenAddress(userAddress)}`,
      });

      const oracleOK = await checkOracleStatus();
      await reloadData();
      setIsLoading(false);
    } catch (e: unknown) {
      if ((e as any).code === -32002) {
        showToast(
          "MetaMask is processing another request. Please complete or cancel it in MetaMask and try again.",
          "error",
          8000
        );
        setStatus({ type: "error", message: "MetaMask request pending" });
      } else {
        handleError(e as Error, "Connection");
      }
      setIsLoading(false);
    }
  }, [handleError, showToast]);

  // Disconnect wallet function
  const disconnectWallet = useCallback(() => {
    setStatus({ type: "disconnected", message: "Not Connected" });
    setUserAddress("");
    setProvider(null);
    setSigner(null);
    setContract(null);
    setBalance(null);
    setPortfolio({
      positions: [],
      totalValue: 0,
      pnl: 0,
      activePositions: 0,
      spotPrice: 0,
      isLoading: false,
    });
    setIsAdmin(false);
    showToast("Wallet disconnected.", "info", 4000);
  }, [showToast]);

  // Effect for wallet connection and event listeners
  useEffect(() => {
    const ethAny = (window as any).ethereum as CustomEthereumProvider | undefined;
    if (!ethAny) {
      showToast("Please install a web3 wallet like MetaMask.", "error", 5000);
      return;
    }

    const customEthereum = ethAny;

    const handleAccountsChanged = (accounts: string[]) => {
      if (accounts.length > 0) {
        setUserAddress(accounts[0]);
        const provider = new BrowserProvider(customEthereum);
        provider.getBalance(accounts[0]).then((balance: bigint) => {
          setBalance(ethers.formatEther(balance));
        });
        setStatus({
          type: "connected",
          message: `Connected: ${shortenAddress(accounts[0])}`,
        });
        reloadData();
      } else {
        disconnectWallet();
      }
    };

    const handleChainChanged = () => {
      window.location.reload();
    };

    customEthereum.on("accountsChanged", handleAccountsChanged);
    customEthereum.on("chainChanged", handleChainChanged);

    // Initial connection attempt
    connectWallet();

    return () => {
      customEthereum.removeListener("accountsChanged", handleAccountsChanged);
      customEthereum.removeListener("chainChanged", handleChainChanged);
    };
  }, [connectWallet, disconnectWallet, showToast]);

  // Effect to fetch data when userAddress changes
  useEffect(() => {
    if (userAddress && contract) {
      checkAdminStatus();
      reloadData();
    }
  }, [userAddress, contract]);

  // Check oracle status
  const checkOracleStatus = useCallback(async (): Promise<boolean> => {
    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);

        // Always compute IV-adjusted curve so legend toggle works
        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;
      // Do not force visibility here; respect user's legend toggle
      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 || (oracleIsStale && !isManualSource)) {
      setPortfolio((prev) => ({ ...prev, positions: [] }));
      console.log("Skipping portfolio fetch due to stale oracle");
      return;
    }

    setPortfolio((prev) => ({ ...prev, isLoading: true }));
    try {
      const positionCount = (await contract.nextPositionIdForUser(
        userAddress
      )) as bigint;
      const count = Number(positionCount);
      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);
      const pricePromises: { [key: string]: Promise<bigint> } = {};
      const activePositions = allPositions.filter((p: any) => p.isActive);

      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 }
      );

      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 currentPriceRaw = priceMap[leg.maturity.toString()];
            if (currentPriceRaw === undefined) return;
            const currentPrice = toBigInt(currentPriceRaw);
            const entryPrice = toBigInt(leg.entryPrice);
            const amountRaw = leg.amountISLV ?? leg.amountISILV;
            const amountISILV = toBigInt(amountRaw);
            const pnlForLeg =
              ((currentPrice - entryPrice) * amountISILV) /
              ethers.parseUnits("1", 18);

            if (leg.isLong) {
              posPnl += pnlForLeg;
              longAmount += amountISILV;
            } else {
              posPnl -= pnlForLeg;
            }
          });

          totalPnl += posPnl;

          const derivedType = p.positionType === 0 || (p.legs?.length === 1)
            ? "Outright"
            : "Spread";

          return {
            positionId: p.positionId.toString(),
            positionType: derivedType,
            legs: p.legs.map((leg: any) => ({
              maturity: new Date(
                Number(leg.maturity) * 1000
              ).toLocaleDateString(),
              amountISILV: parseFloat(
                ethers.formatUnits(leg.amountISLV ?? leg.amountISILV, 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();

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

  // Reload data
  const reloadData = useCallback(async () => {
    if (!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: unknown) {
      console.error("Reload data error:", e);
      handleError(e as Error, "Data Reload");
    } finally {
      setPortfolio((prev) => ({ ...prev, isLoading: false }));
    }
  }, [
    contract,
    oracleIsStale,
    isManualSource,
    activeTab,
    isAdmin,
    fetchLiveSpotPrice,
    fetchPortfolioData,
    fetchChartData,
    fetchAdminSettings,
    handleError,
  ]);

  // Handle transaction lifecycle with fresh reload callback
  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: unknown) {
        handleError(e as Error, "Transaction");
        throw e;
      }
    },
    [showToast, handleError, reloadData]
  );

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

  // Check admin status
  const checkAdminStatus = useCallback(async () => {
    if (!contract || !userAddress) return;
    const contractAdmin = (await contract.admin()) as string;
    setIsAdmin(contractAdmin.toLowerCase() === userAddress.toLowerCase());
  }, [contract, userAddress]);

  // Get outright quote
  const getOutrightQuote = useCallback(async () => {
    const { maturity, amount, paymentToken, slippagePercent } = trade.outright;
    const allInputsValid = maturity && amount && parseFloat(amount) > 0;

    if (!allInputsValid || !contract) return;

    try {
      const maturityTs = Math.floor(new Date(maturity).getTime() / 1000);
      const amount18 = ethers.parseUnits(amount, 18);

      const price = (await contract.priceFor(maturityTs)) as bigint;
      const principal = (amount18 * price) / ethers.parseUnits("1", 18);

      const feeBPS = (await contract.treasuryFeeBPS()) as bigint;
      const fee = (principal * feeBPS) / BigInt(10000);
      const totalCost = principal + fee;

      const slippagePercentVal = parseFloat(slippagePercent);
      if (isNaN(slippagePercentVal) || slippagePercentVal < 0) return;

      const slippageBPS = BigInt(Math.round(slippagePercentVal * 100));
      const maxCostWei =
        (totalCost * (BigInt(10000) + slippageBPS)) / BigInt(10000);
      setTrade((prev) => ({
        ...prev,
        outright: {
          ...prev.outright,
          maxCost: parseFloat(ethers.formatUnits(maxCostWei, 18)).toFixed(2),
        },
      }));
    } catch (e: unknown) {
      console.error("Outright quote failed:", e);
    }
  }, [contract, trade.outright.maturity, trade.outright.amount, trade.outright.slippagePercent, trade.outright.paymentToken]);

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

  // Get spread quote
  const getSpreadQuote = useCallback(async () => {
    const { legs, paymentToken, slippagePercent, ivEnabled, impliedVolatility } = trade.spread;
    const allInputsValid = legs.every(
      (leg) => leg.maturity && leg.amountISILV && parseFloat(leg.amountISILV) > 0
    );

    if (!allInputsValid || !contract) {
      setSpreadQuote({
        isCalculating: false,
        netCost: null,
        displayCost: "$0.00",
        error: "Please fill all leg fields correctly.",
      });
      return;
    }

    setSpreadQuote((prev) => ({ ...prev, isCalculating: true, error: null }));
    try {
      const maturityTs = legs.map((leg) =>
        Math.floor(new Date(leg.maturity).getTime() / 1000)
      );
      const amounts = legs.map((leg) => ethers.parseUnits(leg.amountISILV, 18));
      const isLongs = legs.map((leg) => leg.isLong);

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

      // Optionally adjust prices using IV for front-end estimation, matching chart logic
      let prices: bigint[] = basePrices;
      if (ivEnabled) {
        try {
          const annualRate = Number((await contract.annualRateBPS()) as bigint) / 10000;
          const vol = parseFloat(impliedVolatility) / 100;
          prices = basePrices.map((priceWei, i) => {
            const basePriceNum = parseFloat(ethers.formatUnits(priceWei, 18));
            const tYears = Math.max(
              (maturityTs[i] - Math.floor(Date.now() / 1000)) / (365 * 24 * 60 * 60),
              0
            );
            const premium = blackScholes("call", basePriceNum, basePriceNum, tYears, annualRate, vol);
            const adjusted = basePriceNum + premium;
            return ethers.parseUnits(adjusted.toFixed(18), 18);
          });
        } catch (e) {
          console.warn("IV adjustment failed, falling back to base prices:", e);
          prices = basePrices;
        }
      }

      let netCost = BigInt(0);
      prices.forEach((price, i) => {
        const principal = (amounts[i] * price) / ethers.parseUnits("1", 18);
        netCost += isLongs[i] ? principal : -principal;
      });
      // Match silver.html: estimates exclude protocol fee
      const principalNet = netCost;

      const slippagePercentVal = parseFloat(slippagePercent);
      if (isNaN(slippagePercentVal) || slippagePercentVal < 0) {
        throw new Error("Invalid slippage percentage");
      }

      const slippageBPS = BigInt(Math.round(slippagePercentVal * 100));
      const adjustedCost =
        principalNet >= 0
          ? (principalNet * (BigInt(10000) + slippageBPS)) / BigInt(10000)
          : (principalNet * (BigInt(10000) - slippageBPS)) / BigInt(10000);

      // For the on-screen estimate, match silver.html by excluding fee and slippage
      const estimateCost = principalNet;
      const displayStr = formatCurrency(parseFloat(ethers.formatUnits(estimateCost, 18)));
      setSpreadQuote((prev) => {
        if (
          prev &&
          prev.netCost !== null &&
          prev.netCost === estimateCost &&
          prev.displayCost === displayStr &&
          !prev.isCalculating
        ) {
          return prev; // avoid unnecessary re-render if unchanged
        }
        return {
          isCalculating: false,
          netCost: estimateCost,
          displayCost: displayStr,
          error: null,
        };
      });

      setTrade((prev) => ({
        ...prev,
        spread: {
          ...prev.spread,
          maxCost:
            adjustedCost > 0
              ? parseFloat(ethers.formatUnits(adjustedCost, 18)).toFixed(2)
              : "",
          minCredit:
            adjustedCost <= 0
              ? parseFloat(ethers.formatUnits(-adjustedCost, 18)).toFixed(2)
              : "",
        },
      }));
    } catch (e: unknown) {
      console.error("Spread quote failed:", e);
      setSpreadQuote({
        isCalculating: false,
        netCost: null,
        displayCost: "$0.00",
        error: "Failed to calculate spread quote.",
      });
    }
  }, [contract, trade.spread.legs, trade.spread.slippagePercent, trade.spread.ivEnabled, trade.spread.impliedVolatility, handleError]);

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

  // Execute outright trade
  const handleExecuteOutrightTrade = useCallback(async () => {
    const { maturity, amount, sl, tp, useSlTp, paymentToken, maxCost } =
      trade.outright;
    if (!maturity || !amount || !maxCost) {
      showToast("Maturity, Amount, and Max Cost are required.", "error");
      return;
    }

    setIsOutrightTrading(true);
    try {
      const maturityTs = Math.floor(new Date(maturity).getTime() / 1000);
      const amount18 = ethers.parseUnits(amount, 18);
      const maxCost18 = ethers.parseUnits(maxCost, 18);
      if (!contract) throw new Error("Contract not initialized");

      const entryPrice = (await contract.priceFor(maturityTs)) as bigint;
      let sl18 = BigInt(0);
      let tp18 = BigInt(0);
      if (useSlTp) {
        sl18 = ethers.parseUnits(sl || "0", 18);
        tp18 = ethers.parseUnits(tp || "0", 18);

        if (sl18 > BigInt(0) && sl18 >= entryPrice) {
          showToast("Stop Loss must be BELOW entry price", "error");
          setIsOutrightTrading(false);
          return;
        }
        if (tp18 > BigInt(0) && tp18 <= entryPrice) {
          showToast("Take Profit must be ABOVE entry price", "error");
          setIsOutrightTrading(false);
          return;
        }
      }

      if (paymentToken === IUSD_TOKEN_ADDRESS) {
        const iusdContract = new Contract(IUSD_TOKEN_ADDRESS, IUSD_ABI, signer);

        const allowance = await iusdContract.allowance(
          userAddress,
          RFQ_CONTRACT_ADDRESS
        );
        if (allowance < maxCost18) {
          await handleTx(
            iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
            "IUSD approved for spending."
          );
        }
      }

      if (!contract) {
        showToast("Contract not initialized.", "error");
        setIsOutrightTrading(false);
        return;
      }

      if (paymentToken === IUSD_TOKEN_ADDRESS) {
        const txPromise = contract.openPositionWithIUSD(
          maturityTs,
          amount18,
          sl18,
          tp18,
          maxCost18
        );
        await handleTx(txPromise, "Outright position opened successfully.");
      } else {
        // ETH path: compute principal + fee and send exact value like silver.html
        const principal = (amount18 * entryPrice) / ethers.parseUnits("1", 18);
        const feeBPS = (await contract.treasuryFeeBPS()) as bigint;
        const fee = (principal * feeBPS) / BigInt(10000);
        const totalValue = principal + fee;

        const txPromise = contract.openPositionWithEth(
          maturityTs,
          amount18,
          sl18,
          tp18,
          maxCost18,
          { value: totalValue }
        );
        await handleTx(txPromise, "Outright position opened successfully.");
      }
    } catch (e: unknown) {
      handleError(e as Error, "Outright Trade");
    } finally {
      setIsOutrightTrading(false);
    }
  }, [trade.outright, contract, signer, userAddress, handleTx, handleError, showToast]);

  // Execute spread trade
  const handleExecuteSpreadTrade = useCallback(async () => {
    const { legs, paymentToken, maxCost, minCredit, slippagePercent } = trade.spread;
    if (!legs.every((leg) => leg.maturity && leg.amountISILV)) {
      showToast("All leg fields must be filled.", "error");
      return;
    }

    setIsSpreadTrading(true);
    try {
      // Build tuple legs to strictly match ABI: (maturity, amountISILV, isLong)
      const inputLegs = legs.map((leg) => [
        BigInt(Math.floor(new Date(leg.maturity).getTime() / 1000)),
        ethers.parseUnits(leg.amountISILV, 18),
        Boolean(leg.isLong),
      ] as const);

      // Debug: verify ABI expects tuple[] (will print once per execution)
      try {
        // eslint-disable-next-line no-console
        console.debug(
          'openSpreadPosition signature:',
          (contract as any)?.interface?.getFunction?.('openSpreadPosition')?.format?.('full')
        );
      } catch (_) {}
      const costOrCredit = maxCost
        ? ethers.parseUnits(maxCost, 18)
        : ethers.parseUnits(minCredit, 18);

      if (paymentToken === IUSD_TOKEN_ADDRESS && maxCost) {
        const iusdContract = new Contract(IUSD_TOKEN_ADDRESS, IUSD_ABI, signer);
        if (!contract) throw new Error("Contract not initialized");

        const allowance = await iusdContract.allowance(
          userAddress,
          RFQ_CONTRACT_ADDRESS
        );
        if (allowance < costOrCredit) {
          await handleTx(
            iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
            "IUSD approved for spending."
          );
        }
      }

      if (!contract) {
        showToast("Contract not initialized.", "error");
        setIsSpreadTrading(false);
        return;
      }

      const txPromise = contract.openSpreadPosition(
        inputLegs,
        paymentToken,
        maxCost ? costOrCredit : BigInt(0),
        minCredit ? costOrCredit : BigInt(0),
        { value: paymentToken === ZeroAddress && maxCost ? costOrCredit : BigInt(0) }
      );

      await handleTx(txPromise, "Spread position opened successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Spread Trade");
    } finally {
      setIsSpreadTrading(false);
    }
  }, [trade.spread, contract, signer, userAddress, handleTx, handleError, showToast]);

  // Close position with pre-approvals (parity with silver.html)
  const closePositionOnChain = useCallback(
    async (position: Position) => {
      if (!contract || !signer || !userAddress) {
        showToast("Contract not initialized.", "error");
        throw new Error("Contract not initialized");
      }

      try {
        const pid = BigInt(position.positionId);

        // Fetch position details
        const pos = await contract.getPositionById(userAddress, pid);
        const legs: Array<{
          maturity: bigint;
          entryPrice: bigint;
          amountISLV?: bigint;
          amountISILV?: bigint;
          isLong: boolean;
        }> = pos.legs as any;

        // Pre-calc PnL and total long amount to burn (ISILV)
        let totalLongAmountToBurn = BigInt(0);
        let pnlValue = BigInt(0);
        const pricePromises = legs.map((leg) => contract.priceFor(leg.maturity));
        const currentPrices: bigint[] = (await Promise.all(pricePromises)) as bigint[];

        legs.forEach((leg, index) => {
          const currentPrice = currentPrices[index];
          const amountRaw = leg.amountISLV ?? leg.amountISILV;
          const amount = toBigInt(amountRaw);
          const pnlForLeg =
            ((currentPrice - leg.entryPrice) * amount) /
            ethers.parseUnits("1", 18);
          if (leg.isLong) {
            pnlValue += pnlForLeg;
            totalLongAmountToBurn += amount;
          } else {
            pnlValue -= pnlForLeg;
          }
        });

        // If loss, ensure IUSD allowance for the loss amount
        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);
          if (allowance < lossAmount) {
            await handleTx(
              iusdContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
              "IUSD approval for loss successful."
            );
          }
        }

        // Ensure ISILV allowance for burning long amounts
        if (totalLongAmountToBurn > BigInt(0)) {
          const isilvContract = new Contract(ISILV_TOKEN_ADDRESS, ISILV_TOKEN_ABI, signer);
          const allowance = await isilvContract.allowance(userAddress, RFQ_CONTRACT_ADDRESS);
          if (allowance < totalLongAmountToBurn) {
            await handleTx(
              isilvContract.approve(RFQ_CONTRACT_ADDRESS, MaxUint256),
              "ISILV approval successful."
            );
          }
        }

        const receipt = await safeSendClosePosition(
          contract,
          pid,
          IUSD_TOKEN_ADDRESS,
          signer
        );
        console.log("Close position transaction receipt:", receipt);
        showToast(`Position ${position.positionId} closed successfully.`, "success");
        await reloadData();
      } catch (e: unknown) {
        if (!isUserRejectedError(e)) {
          handleError(e as Error, "Close Position");
        }
        throw e;
      }
    },
    [contract, signer, userAddress, handleTx, handleError, showToast, reloadData]
  );

  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,
    showToast,
    isUserRejectedError,
    getUserRejectedMessage,
  ]);

  // Set manual spot price
  const handleSetManualSpotPrice = useCallback(async () => {
    if (!contract || !isAdmin || !admin.manualSpotPrice) {
      showToast("Invalid price or not authorized.", "error");
      return;
    }

    try {
      const price18 = ethers.parseUnits(admin.manualSpotPrice, 18);
      const txPromise = contract.setManualPrice(price18);
      await handleTx(txPromise, "Manual spot price set successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Set Manual Spot Price");
    }
  }, [contract, isAdmin, admin.manualSpotPrice, handleTx, handleError, showToast]);

  // Set oracle max age
  const handleSetOracleMaxAge = useCallback(async () => {
    if (!contract || !isAdmin || !admin.oracleMaxAge) {
      showToast("Invalid max age or not authorized.", "error");
      return;
    }

    try {
      const maxAge = BigInt(admin.oracleMaxAge);
      const txPromise = contract.setOracleMaxAge(maxAge);
      await handleTx(txPromise, "Oracle max age set successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Set Oracle Max Age");
    }
  }, [contract, isAdmin, admin.oracleMaxAge, handleTx, handleError, showToast]);

  // Set annual rate
  const handleSetAnnualRateBPS = useCallback(async () => {
    if (!contract || !isAdmin || !admin.annualRate) {
      showToast("Invalid rate or not authorized.", "error");
      return;
    }

    try {
      const rateBPS = BigInt(admin.annualRate);
      const txPromise = contract.setAnnualRateBPS(rateBPS);
      await handleTx(txPromise, "Annual rate set successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Set Annual Rate");
    }
  }, [contract, isAdmin, admin.annualRate, handleTx, handleError, showToast]);

  // Price source control with optimistic UI update
  const handleSetPriceSource = useCallback(
    async (source: "Manual" | "Chainlink") => {
      if (!contract || !isAdmin) return;
      try {
        const tx = contract.setPriceSource(source === "Manual" ? 1 : 0);
        await handleTx(tx, "Price source updated.");
        setIsManualSource(source === "Manual");
      } catch (e: unknown) {
        handleError(e as Error, "Set Price Source");
      }
    },
    [contract, isAdmin, handleTx, handleError]
  );

  // Add keeper
  const handleAddKeeper = useCallback(async () => {
    if (!contract || !isAdmin || !admin.keeperAddress) {
      showToast("Invalid address or not authorized.", "error");
      return;
    }

    try {
      const txPromise = contract.setKeeper(admin.keeperAddress, true);
      await handleTx(txPromise, "Keeper added successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Add Keeper");
    }
  }, [contract, isAdmin, admin.keeperAddress, handleTx, handleError, showToast]);

  // Remove keeper
  const handleRemoveKeeper = useCallback(async () => {
    if (!contract || !isAdmin || !admin.keeperAddress) {
      showToast("Invalid address or not authorized.", "error");
      return;
    }

    try {
      const txPromise = contract.setKeeper(admin.keeperAddress, false);
      await handleTx(txPromise, "Keeper removed successfully.");
    } catch (e: unknown) {
      handleError(e as Error, "Remove Keeper");
    }
  }, [contract, isAdmin, admin.keeperAddress, handleTx, handleError, showToast]);

  // Analyze carry
  const handleAnalyzeCarry = useCallback(async () => {
    if (!contract || !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 startTs = Math.floor(d1.getTime() / 1000);
      const endTs = Math.floor(d2.getTime() / 1000);

      const [startPrice, endPrice] = await Promise.all([
        contract.priceFor(startTs),
        contract.priceFor(endTs),
      ]);

      const startPriceNum = parseFloat(ethers.formatUnits(startPrice, 18));
      const endPriceNum = parseFloat(ethers.formatUnits(endPrice, 18));
      const priceSpread = endPriceNum - startPriceNum;
      const basisPoints = (priceSpread / startPriceNum) * 10000;
      const days = (endTs - startTs) / (24 * 60 * 60);
      // Store percent value, not basis points, for Annualized Yield
      const annualizedYield = (priceSpread / startPriceNum) * (365 / days) * 100;

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

  // Effect to initialize chart
  useEffect(() => {
    if (activeTab === "trade") {
      initChart();
      fetchChartData();
    }
  }, [activeTab, initChart, fetchChartData]);

  // Effect to fetch quotes on trade input changes
  useEffect(() => {
    const cleanup = debouncedGetOutrightQuote();
    return cleanup;
  }, [trade.outright.amount, trade.outright.maturity, trade.outright.slippagePercent, debouncedGetOutrightQuote]);

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

  return (
    <Box sx={{ minHeight: "100vh", backgroundColor: "#F7FAFC" ,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 }}
        >
          IntelliTrade Silver 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
                        ? theme.palette.text.primary
                        : getPnlColor(portfolio.pnl),
                    }}
                  >
                    {portfolio.isLoading
                      ? "Loading..."
                      : 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 Silver Price
                  </Typography>
                  <Typography variant="h5" sx={{ fontWeight: "bold" }}>
                    {portfolio.isLoading
                      ? "Loading..."
                      : 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>Action</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {portfolio.isLoading && (
                      <TableRow>
                        <TableCell colSpan={6} align="center">
                          Loading portfolio...
                        </TableCell>
                      </TableRow>
                    )}
                    {!portfolio.isLoading && portfolio.positions.length === 0 && (
                      <TableRow>
                        <TableCell colSpan={6} 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, index) => (
                              <Typography
                                key={index}
                                variant="body2"
                                sx={{ whiteSpace: "nowrap", color: "#374151" }}
                              >
                                <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" }}
                                >
                                  {`${Number(leg.amountISILV).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.longAmount} ISILV</TableCell>
                        <TableCell
                          sx={{
                            color:
                              position.pnl > 0
                                ? "#10B981"
                                : position.pnl < 0
                                ? "#EF4444"
                                : "#6B7280",
                            fontWeight: 600,
                          }}
                        >
                          {formatPnlWithSign(position.pnl)}
                        </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 sx={{ p: 1 }}>
              <Box>
                <Typography variant="h6" 
                 sx={{
                  fontWeight: "bold",
                  mb: 3,
                  color: theme.palette.text.primary,
                }}
                >
                  Silver Futures Curve
                </Typography>
                <Paper
                  sx={{
                    p: 4,
                    height: 400,
                    border: "1px solid #D4DBE3",
                    boxShadow: "none",
                  }}
                >
                  <canvas ref={chartRef} aria-label="Silver futures curve chart" />
                </Paper>
              </Box>
              <Box sx={{ mb: 4, mt: 4 }}>
                
                              <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>
              </Box>
              <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 (ISILV)"
                    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>
                  <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}>ETH</MenuItem>
                    </Select>
                  </FormControl>
                  <Button
                    variant="contained"
                    onClick={handleExecuteOutrightTrade}
                    disabled={(oracleIsStale && !isManualSource) || isOutrightTrading}
                    sx={{
                      py: 1.5,
                      bgcolor: "#0b3d91",
                      textTransform: "none",
                      fontWeight: "bold",
                      fontSize: "14px",
                      "&: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, flexWrap: "wrap" }}>
      <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 sx={{ flex: 1, minWidth: 240 }}>
        <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>
    </Box>
  </Tooltip>

  <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 silver tokens (ISILV) for this leg">
                        <TextField
                          label="Amount (ISILV)"
                          type="number"
                          value={leg.amountISILV}
                          onChange={(e: ChangeEvent<HTMLInputElement>) => {
                            const newLegs = [...trade.spread.legs];
                            newLegs[index].amountISILV = 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: "", amountISILV: "", 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}>ETH</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.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 ${trade.spread.ivEnabled ? "(with IV)" : "(no 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:" : "Credit:"}{" "}
                              {spreadQuote.displayCost}
                            </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 silver 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 silver"
                        />
                      </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={toast.type === "error" ? 8000 : 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 IntelliTradeSilverWithoutSLTP;
