import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type React from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { motion } from "framer-motion";
import { Wallet, BarChart3, AlertCircle, RefreshCcw, PlugZap } from "lucide-react";
import BrokerConnectDialog from "./BrokerConnectDialog";
import LoginRequiredDialog from "./LoginRequiredDialog";
import { getQueryFn, apiRequest } from "@/lib/queryClient";
import { getStrategyStatus, startStrategy, stopStrategy } from "@/api/strategy";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import StrategyTimeline from "@/components/StrategyTimeline";
import { toast } from "@/hooks/use-toast";
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
} from "@/components/ui/chart";
import {
  Area,
  AreaChart,
  CartesianGrid,
  XAxis,
  YAxis,
} from "recharts";
import type { User } from "@shared/schema";

type BrokerStatusResponse = {
  connected: boolean;
  broker?: string;
  connected_at?: string;
  userName?: string;
  brokerUserId?: string;
};

type SystemArmResponse = {
  armed_runs: Array<{ run_id: string; status: string; next_run?: string; already_running?: boolean }>;
  failed_runs: Array<{ run_id: string; status: string; reason: string }>;
  next_execution?: string | null;
  broker_state?: {
    connected?: boolean;
    auth_state?: string | null;
    broker?: string | null;
    user_name?: string | null;
  };
};

type SystemStatusRun = {
  run_id: string;
  status: string;
  strategy?: string | null;
  mode?: string | null;
  broker?: string | null;
  next_run?: string | null;
  lifecycle?: string | null;
};

type SystemStatusResponse = {
  runs: SystemStatusRun[];
  broker_state?: {
    connected?: boolean;
    auth_state?: string | null;
    broker?: string | null;
    user_name?: string | null;
  };
};

type HoldingsResponse = {
  holdings: any[];
};

type MarketStatusResponse = {
  status?: "OPEN" | "CLOSED";
  checked_at?: string;
};

type FundsResponse = {
  funds?: {
    net?: number;
    cash?: number;
    withdrawable?: number;
    utilized?: number;
    balance?: number;
  };
};

type EquityCurveResponse = {
  startDate: string;
  endDate: string;
  accountOpenDate?: string;
  points: { date: string; value: number }[];
};

type EngineStatus = {
  state?: string;
  run_id?: string | null;
  last_heartbeat_ts?: string | null;
  last_execution_ts?: string | null;
  next_eligible_ts?: string | null;
};

type SessionUser = Pick<User, "id" | "username">;

const MotionButton = motion(Button);

function formatCurrency(amount: number, options?: { decimals?: number }) {
  const decimals = options?.decimals ?? 2;
  return new Intl.NumberFormat("en-IN", {
    style: "currency",
    currency: "INR",
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(amount || 0);
}

function formatDateInput(date: Date) {
  return date.toISOString().slice(0, 10);
}

function formatMinuteTimestamp(date: Date) {
  return date.toLocaleString(undefined, {
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
  });
}

function formatRelativeSeconds(seconds: number) {
  if (!Number.isFinite(seconds)) return "";
  if (seconds <= 0) return "now";
  const total = Math.round(seconds);
  const days = Math.floor(total / 86400);
  const hours = Math.floor((total % 86400) / 3600);
  const minutes = Math.floor((total % 3600) / 60);
  const parts = [];
  if (days) parts.push(`${days}d`);
  if (hours) parts.push(`${hours}h`);
  if (!days && minutes) parts.push(`${minutes}m`);
  if (parts.length === 0) parts.push("less than 1m");
  return `in ${parts.join(" ")}`;
}

function usePrefersReducedMotion() {
  const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);

  useEffect(() => {
    const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
    const update = () => setPrefersReducedMotion(mediaQuery.matches);
    update();

    if (mediaQuery.addEventListener) {
      mediaQuery.addEventListener("change", update);
      return () => mediaQuery.removeEventListener("change", update);
    }

    mediaQuery.addListener(update);
    return () => mediaQuery.removeListener(update);
  }, []);

  return prefersReducedMotion;
}

export default function PortfolioSection() {
  const sectionRef = useRef<HTMLElement | null>(null);
  const [isVisible, setIsVisible] = useState(false);
  const [scrollY, setScrollY] = useState(0);
  const prefersReducedMotion = usePrefersReducedMotion();
  const [loginPromptOpen, setLoginPromptOpen] = useState(false);
  const [connectPromptOpen, setConnectPromptOpen] = useState(false);
  const [brokerDialogOpen, setBrokerDialogOpen] = useState(false);
  const [sessionExpired, setSessionExpired] = useState(false);
  const [reconnectAttempted, setReconnectAttempted] = useState(false);
  const [cachedHoldings, setCachedHoldings] = useState<any[]>([]);
  const [cachedFunds, setCachedFunds] = useState<FundsResponse["funds"] | null>(null);
  const [cachedEquityCurve, setCachedEquityCurve] = useState<EquityCurveResponse | null>(null);
  const [armSummary, setArmSummary] = useState<SystemArmResponse | null>(null);
  const {
    data: brokerStatus,
    isFetching: brokerStatusLoading,
    refetch: refetchBrokerStatus,
  } = useQuery<BrokerStatusResponse | null>({
    queryKey: ["/broker/status"],
    queryFn: getQueryFn<BrokerStatusResponse>({ on401: "returnNull" }),
    staleTime: 0,
    refetchOnMount: "always",
  });
  const { data: sessionUser } = useQuery<SessionUser | null>({
    queryKey: ["/me"],
    queryFn: getQueryFn<SessionUser | null>({ on401: "returnNull" }),
  });
  const systemStatusQuery = useQuery<SystemStatusResponse>({
    queryKey: ["/system/status"],
    queryFn: getQueryFn<SystemStatusResponse>({ on401: "throw" }),
    refetchInterval: 15000,
  });
  const armMutation = useMutation({
    mutationFn: async () => {
      const res = await fetch("/system/arm", {
        method: "POST",
        credentials: "include",
      });
      if (res.status === 401) {
        let payload: any = {};
        try {
          payload = await res.json();
        } catch {}
        const redirect =
          payload?.detail?.redirect_url ||
          payload?.redirect_url ||
          "/broker/login";
        window.location.assign(redirect);
        return null;
      }
      if (!res.ok) {
        const text = await res.text();
        throw new Error(text || res.statusText);
      }
      return (await res.json()) as SystemArmResponse;
    },
    onSuccess: (data) => {
      if (!data) return;
      setArmSummary(data);
      toast({
        title: "System armed",
        description: data.next_execution
          ? `Next execution at ${new Date(data.next_execution).toLocaleString()}`
          : "All strategies are armed.",
      });
      systemStatusQuery.refetch();
      refetchBrokerStatus();
    },
    onError: (err: any) =>
      toast({
        title: "Arm failed",
        description: err?.message || "Unable to arm system.",
      }),
  });

  const holdingsQuery = useQuery<HoldingsResponse>({
    queryKey: ["/zerodha/holdings"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/zerodha/holdings");
      return res.json();
    },
    enabled: !!brokerStatus?.connected,
    retry: 1,
    retryDelay: 600,
    onSuccess: (data) => {
      setCachedHoldings(data?.holdings || []);
      setSessionExpired(false);
      setReconnectAttempted(false);
    },
    onError: () => {
      if (brokerStatus?.connected) {
        setSessionExpired(true);
      }
    },
  });

  const fundsQuery = useQuery<FundsResponse>({
    queryKey: ["/zerodha/funds"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/zerodha/funds");
      return res.json();
    },
    enabled: !!brokerStatus?.connected,
    retry: 1,
    retryDelay: 600,
    onSuccess: (data) => {
      setCachedFunds(data?.funds ?? null);
      setSessionExpired(false);
      setReconnectAttempted(false);
    },
    onError: () => {
      if (brokerStatus?.connected) {
        setSessionExpired(true);
      }
    },
  });

  const [startDate, setStartDate] = useState(() =>
    formatDateInput(new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)),
  );
  const [sipAmount, setSipAmount] = useState(5000);
  const [frequencyDays, setFrequencyDays] = useState(30);
  const [strategyStatus, setStrategyStatus] = useState("STOPPED");
  const [isStarting, setIsStarting] = useState(false);
  const [isStopping, setIsStopping] = useState(false);
  const [engineStatus, setEngineStatus] = useState<EngineStatus | null>(null);
  const [marketStatus, setMarketStatus] = useState<MarketStatusResponse | null>(null);

  const linkedAtDate = brokerStatus?.connected_at
    ? new Date(brokerStatus.connected_at)
    : null;
  const linkedAtInput =
    linkedAtDate && !isNaN(linkedAtDate.getTime())
      ? formatDateInput(linkedAtDate)
      : undefined;

  useEffect(() => {
    if (linkedAtInput) {
      setStartDate((prev) => (prev === linkedAtInput ? prev : linkedAtInput));
    }
  }, [linkedAtInput]);

  const refreshStatus = useCallback(async () => {
    try {
      const status = await getStrategyStatus();
      setStrategyStatus(status?.status ?? "STOPPED");
    } catch (error) {
      setStrategyStatus("STOPPED");
    }
  }, []);

  useEffect(() => {
    refreshStatus();
    const interval = window.setInterval(refreshStatus, 15000);
    return () => window.clearInterval(interval);
  }, [refreshStatus]);

  useEffect(() => {
    const fetchStatus = async () => {
      try {
        const res = await fetch("/engine/status");
        const data = await res.json();
        setEngineStatus(data);
      } catch {
        setEngineStatus(null);
      }
    };

    fetchStatus();
    const id = window.setInterval(fetchStatus, 5000);
    return () => window.clearInterval(id);
  }, []);

  useEffect(() => {
    const fetchMarketStatus = async () => {
      try {
        const res = await fetch("/market/status");
        const data = await res.json();
        setMarketStatus(data);
      } catch {
        setMarketStatus(null);
      }
    };

    fetchMarketStatus();
    const id = window.setInterval(fetchMarketStatus, 5000);
    return () => window.clearInterval(id);
  }, []);

  useEffect(() => {
    if (prefersReducedMotion) {
      setIsVisible(true);
      return;
    }

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsVisible(true);
        }
      },
      { threshold: 0.2 },
    );

    if (sectionRef.current) {
      observer.observe(sectionRef.current);
    }

    return () => observer.disconnect();
  }, [prefersReducedMotion]);

  useEffect(() => {
    if (prefersReducedMotion) {
      setScrollY(0);
      return;
    }

    let rafId: number | null = null;
    const handleScroll = () => {
      if (rafId !== null) return;
      rafId = window.requestAnimationFrame(() => {
        setScrollY(window.scrollY);
        rafId = null;
      });
    };

    window.addEventListener("scroll", handleScroll, { passive: true });
    handleScroll();

    return () => {
      window.removeEventListener("scroll", handleScroll);
      if (rafId !== null) {
        window.cancelAnimationFrame(rafId);
      }
    };
  }, [prefersReducedMotion]);

  const equityCurveQuery = useQuery<EquityCurveResponse>({
    queryKey: ["/zerodha/equity-curve", startDate],
    queryFn: async () => {
      const res = await apiRequest(
        "GET",
        `/zerodha/equity-curve${startDate ? `?from=${startDate}` : ""}`,
      );
      return res.json();
    },
    enabled: !!brokerStatus?.connected,
    retry: 1,
    retryDelay: 600,
    onSuccess: (data) => {
      setCachedEquityCurve(data ?? null);
      setSessionExpired(false);
      setReconnectAttempted(false);
    },
    onError: () => {
      if (brokerStatus?.connected) {
        setSessionExpired(true);
      }
    },
  });

  const isConnected = !!brokerStatus?.connected;
  const isAuthed = brokerStatus !== null;
  const holdings = holdingsQuery.data ? holdingsQuery.data.holdings : cachedHoldings;
  const fundsSnapshot = fundsQuery.data?.funds ?? cachedFunds;
  const noHoldings = holdings.length === 0;
  const systemRuns = systemStatusQuery.data?.runs ?? [];
  const armedCount = systemRuns.filter(
    (run) => (run.status || "").toUpperCase() === "RUNNING",
  ).length;
  const nextExecution = useMemo(() => {
    const nextDates = systemRuns
      .map((run) => (run.next_run ? new Date(run.next_run) : null))
      .filter((value): value is Date => !!value && !Number.isNaN(value.getTime()));
    if (!nextDates.length) return null;
    nextDates.sort((a, b) => a.getTime() - b.getTime());
    return nextDates[0];
  }, [systemRuns]);
  useEffect(() => {
    if (!isConnected) {
      setSessionExpired(false);
      setReconnectAttempted(false);
    }
  }, [isConnected]);

  useEffect(() => {
    if (!sessionExpired || reconnectAttempted || !isConnected) {
      return;
    }
    setReconnectAttempted(true);
    (async () => {
      try {
        await refetchBrokerStatus();
        await Promise.all([
          holdingsQuery.refetch(),
          fundsQuery.refetch(),
          equityCurveQuery.refetch(),
        ]);
      } catch {
        return;
      }
    })();
  }, [
    sessionExpired,
    reconnectAttempted,
    isConnected,
    refetchBrokerStatus,
    holdingsQuery,
    fundsQuery,
    equityCurveQuery,
  ]);
  const availableFunds =
    fundsSnapshot?.balance ??
    fundsSnapshot?.net ??
    fundsSnapshot?.withdrawable ??
    fundsSnapshot?.cash ??
    fundsSnapshot?.raw?.net ??
    fundsSnapshot?.raw?.available?.live_balance ??
    fundsSnapshot?.raw?.available?.opening_balance ??
    0;

  const { totalValue, totalPnl } = useMemo(() => {
    return holdings.reduce(
      (acc, item) => {
        const qty = Number(item.quantity ?? item.qty ?? 0);
        const last = Number(item.last_price ?? item.average_price ?? 0);
        const pnl = Number(item.pnl ?? 0);
        return {
          totalValue: acc.totalValue + qty * last,
          totalPnl: acc.totalPnl + pnl,
        };
      },
      { totalValue: 0, totalPnl: 0 },
    );
  }, [holdings]);

  const equityCurve = equityCurveQuery.data ?? cachedEquityCurve;
  const equityCurvePoints = equityCurve?.points ?? [];
  const showSessionExpired = sessionExpired && isConnected;

  const normalizedStrategyStatus =
    strategyStatus === "RUNNING" ? "RUNNING" : "STOPPED";
  const isStrategyRunning = normalizedStrategyStatus === "RUNNING";

  const heartbeatAgeSec = engineStatus?.last_heartbeat_ts
    ? (Date.now() - new Date(engineStatus.last_heartbeat_ts).getTime()) / 1000
    : Infinity;

  let liveness: "ACTIVE" | "STALLED" | "DEAD" | "STOPPED";
  if (!engineStatus) {
    liveness = "DEAD";
  } else if (engineStatus.state !== "RUNNING") {
    liveness = "STOPPED";
  } else if (heartbeatAgeSec < 10) {
    liveness = "ACTIVE";
  } else if (heartbeatAgeSec < 30) {
    liveness = "STALLED";
  } else {
    liveness = "DEAD";
  }

  const livenessBadgeClass =
    liveness === "ACTIVE"
      ? "border-emerald-500/50 bg-emerald-500/15 text-emerald-300"
      : liveness === "STALLED"
        ? "border-amber-400/50 bg-amber-400/15 text-amber-200"
        : liveness === "DEAD"
          ? "border-red-500/50 bg-red-500/15 text-red-300"
        : "border-slate-400/40 bg-slate-400/15 text-slate-200";

  const marketState = marketStatus?.status ?? "UNKNOWN";
  const executionAllowed =
    marketState === "OPEN" && (liveness === "ACTIVE" || liveness === "STOPPED");

  const nextEligibleTs = engineStatus?.next_eligible_ts
    ? new Date(engineStatus.next_eligible_ts)
    : null;
  const nextEligibleValid = nextEligibleTs && !Number.isNaN(nextEligibleTs.getTime());
  const eligibleSeconds = nextEligibleValid
    ? (nextEligibleTs.getTime() - Date.now()) / 1000
    : Infinity;
  const isEligible = eligibleSeconds <= 0;
  const relativeEligible = formatRelativeSeconds(eligibleSeconds);

  let nextEligibleLine = "—";
  let eligibilityStatus: string | null = "First execution pending";
  let eligibilityClass = "text-muted-foreground";

  if (nextEligibleValid) {
    eligibilityStatus = null;
    if (isEligible && marketState === "OPEN") {
      nextEligibleLine = "Now";
      eligibilityStatus = "Eligible — execution imminent";
      eligibilityClass = "text-emerald-400";
    } else if (isEligible && marketState === "CLOSED") {
      nextEligibleLine = `${formatMinuteTimestamp(nextEligibleTs)} (eligible)`;
      eligibilityStatus = "Eligible — waiting for market open";
      eligibilityClass = "text-amber-300";
    } else {
      nextEligibleLine = `${formatMinuteTimestamp(nextEligibleTs)} (${relativeEligible})`;
      eligibilityStatus = "Not eligible yet";
      eligibilityClass = "text-muted-foreground";
    }
  }

  const requireLogin = useCallback(() => {
    if (!sessionUser) {
      setLoginPromptOpen(true);
      return false;
    }
    return true;
  }, [sessionUser]);

  const handleReconnectClick = useCallback(() => {
    if (!requireLogin()) {
      return;
    }
    setBrokerDialogOpen(true);
  }, [requireLogin]);

  const handleStart = async () => {
    if (!requireLogin()) {
      return;
    }
    if (!isConnected) {
      setConnectPromptOpen(true);
      return;
    }
    setIsStarting(true);
    try {
      const result = await startStrategy({
        strategy_name: "Golden Nifty",
        initial_cash: availableFunds,
        sip_amount: sipAmount,
        sip_frequency: {
          value: frequencyDays,
          unit: "days",
        },
        mode: "PAPER",
      });
      if (result?.status === "already_running") {
        toast({
          title: "Strategy already running",
          description: "The engine is already active.",
        });
      }
    } finally {
      setIsStarting(false);
      await refreshStatus();
    }
  };

  const handleStop = async () => {
    setIsStopping(true);
    try {
      await stopStrategy();
    } finally {
      setIsStopping(false);
      await refreshStatus();
    }
  };

  const summaryCards = [
    {
      icon: <Wallet className="h-5 w-5" />,
      label: "Available funds",
      value: formatCurrency(isConnected ? availableFunds : 0, { decimals: 2 }),
      muted: !isConnected,
      subText:
        isConnected && fundsQuery.data?.funds?.utilized !== undefined
          ? `Utilized: ${formatCurrency(fundsQuery.data?.funds?.utilized || 0, { decimals: 2 })}`
          : undefined,
    },
    {
      icon: <Wallet className="h-5 w-5" />,
      label: "Portfolio value",
      value: formatCurrency(totalValue, { decimals: 2 }),
      muted: !isConnected,
    },
    {
      icon: <BarChart3 className="h-5 w-5" />,
      label: "Positions",
      value: holdings.length.toString(),
      muted: !isConnected,
    },
    {
      icon: <AlertCircle className="h-5 w-5" />,
      label: "Unrealized P&L",
      value: formatCurrency(totalPnl, { decimals: 2 }),
      muted: !isConnected,
    },
  ];

  const revealTransition = prefersReducedMotion ? "" : "transition-all duration-700";
  const sectionRevealClass = prefersReducedMotion
    ? "opacity-100"
    : isVisible
      ? "opacity-100 translate-y-0"
      : "opacity-0 translate-y-6";
  const cardRevealClass = prefersReducedMotion
    ? "opacity-100"
    : isVisible
      ? "opacity-100 translate-y-0"
      : "opacity-0 translate-y-4";
  const hoverLift = prefersReducedMotion
    ? ""
    : "transition-all duration-300 hover:-translate-y-1 hover:shadow-2xl hover:shadow-primary/10";
  const parallaxOffset = prefersReducedMotion ? 0 : Math.min(scrollY * 0.3, 220);

  const cardContainer = {
    hidden: {},
    show: {
      transition: {
        staggerChildren: 0.12,
      },
    },
  };

  const cardItem = {
    hidden: { opacity: 0, y: 14 },
    show: { opacity: 1, y: 0 },
  };

  const summaryAnimate = prefersReducedMotion || isVisible ? "show" : "hidden";
  const ctaMotionProps = prefersReducedMotion
    ? {}
    : {
        whileHover: { scale: 1.02 },
        whileTap: { scale: 0.97 },
        transition: { type: "spring", stiffness: 400, damping: 25 },
      };

  return (
    <section
      ref={sectionRef}
      id="portfolio"
      className={`relative overflow-hidden py-32 px-6 pb-32 bg-gradient-to-b from-background to-background/80 ${revealTransition} ${sectionRevealClass}`}
    >
      <LoginRequiredDialog
        open={loginPromptOpen}
        onOpenChange={setLoginPromptOpen}
        context="start the strategy"
      />
      <LoginRequiredDialog
        open={connectPromptOpen}
        onOpenChange={setConnectPromptOpen}
        title="Connect broker"
        message="Connect your broker to start the strategy."
      />
      <div className="absolute inset-0 pointer-events-none">
        <div
          className="absolute -top-24 left-1/4 h-72 w-72 rounded-full bg-primary/10 blur-3xl"
          style={{ transform: `translate3d(0, ${parallaxOffset}px, 0)` }}
        />
        <div
          className="absolute top-6 right-[8%] h-80 w-80 rounded-full bg-chart-2/10 blur-3xl"
          style={{ transform: `translate3d(0, ${parallaxOffset}px, 0)` }}
        />
        <div
          className="absolute top-32 left-8 h-48 w-48 rounded-full bg-chart-3/10 blur-3xl"
          style={{ transform: `translate3d(0, ${parallaxOffset}px, 0)` }}
        />
      </div>

      <div className="relative z-10 max-w-6xl mx-auto space-y-10">
        <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
          <div className="space-y-2">
            <p className="text-sm uppercase tracking-[0.25em] text-muted-foreground">Portfolio</p>
            <h3 className="text-3xl md:text-4xl font-bold">Your holdings & live positions</h3>
            <p className="text-muted-foreground max-w-2xl">
              Connect your broker to sync holdings. When disconnected, values stay at zero and you will see a prompt to connect.
            </p>
            {isConnected && (brokerStatus?.userName || brokerStatus?.broker) ? (
              <div className="inline-flex items-center gap-2 rounded-full border border-primary/50 bg-primary/10 px-3 py-1 text-sm font-medium text-primary">
                <Wallet className="h-4 w-4" />
                {brokerStatus?.userName ? (
                  <>
                    Connected as <span className="font-semibold">{brokerStatus.userName}</span>
                  </>
                ) : (
                  <>
                    Connected to <span className="font-semibold">{brokerStatus?.broker}</span>
                  </>
                )}
              </div>
            ) : null}
          </div>
        <div className="flex flex-wrap gap-2">
          <BrokerConnectDialog open={brokerDialogOpen} onOpenChange={setBrokerDialogOpen} />
          <Button variant="secondary" asChild>
            <a href="/portfolio/paper" target="_blank" rel="noreferrer">
              Paper Trading Portfolio
            </a>
          </Button>
          {isConnected ? (
              <Button
                variant="outline"
                onClick={() => {
                  holdingsQuery.refetch();
                  fundsQuery.refetch();
                  equityCurveQuery.refetch();
                  refetchBrokerStatus();
                }}
                disabled={holdingsQuery.isFetching || equityCurveQuery.isFetching}
              >
                <RefreshCcw className="h-4 w-4" />
                {holdingsQuery.isFetching || equityCurveQuery.isFetching
                  ? "Refreshing..."
                  : "Refresh data"}
              </Button>
            ) : null}
          </div>
        </div>

        <motion.div
          className="grid gap-4 md:grid-cols-3"
          variants={cardContainer}
          initial="hidden"
          animate={summaryAnimate}
        >
          {summaryCards.map((card) => (
            <motion.div
              key={card.label}
              variants={cardItem}
              whileHover={{
                y: -6,
                boxShadow: "0 20px 40px rgba(0,0,0,0.18)",
              }}
              transition={{ type: "spring", stiffness: 300, damping: 24 }}
            >
              <SummaryCard {...card} prefersReducedMotion={prefersReducedMotion} />
            </motion.div>
          ))}
        </motion.div>

        <div
          className={`rounded-2xl border border-border/60 bg-card/70 shadow-xl overflow-hidden ${hoverLift} ${revealTransition} ${cardRevealClass}`}
          style={prefersReducedMotion ? undefined : { transitionDelay: "500ms" }}
        >
          <div className="flex items-center justify-between px-6 py-4 border-b border-border/50">
            <div className="space-y-1">
              <p className="text-sm font-semibold">Holdings</p>
              <p className="text-xs text-muted-foreground">
                Current positions pulled from your connected broker.
              </p>
            </div>
            <Badge variant={isConnected ? "secondary" : "outline"}>
              {isConnected ? "Broker connected" : "Not connected"}
            </Badge>
          </div>

          {!isAuthed ? (
            <ZeroState message="Log in and connect your broker to see your portfolio." />
          ) : brokerStatusLoading ? (
            <ZeroState message="Checking broker status..." />
          ) : !isConnected ? (
            <ZeroState message="Connect to broker to see your portfolio." />
          ) : holdingsQuery.isLoading ? (
            <ZeroState message="Fetching holdings..." />
          ) : holdingsQuery.isError && holdings.length === 0 ? (
            <ZeroState
              message={
                showSessionExpired
                  ? "Session expired. Reconnect to refresh holdings and funds."
                  : "Could not fetch holdings. Try refreshing."
              }
            />
          ) : noHoldings ? (
            <ZeroState message="No holdings yet. Refresh after connecting." />
          ) : (
            <div className="overflow-x-auto">
              {showSessionExpired ? (
                <div className="flex flex-wrap items-center justify-between gap-2 px-6 py-3 text-xs text-amber-200 bg-amber-500/10 border-b border-amber-400/20">
                  <span>Session expired. Showing the last known holdings. Reconnect to refresh.</span>
                  <Button size="sm" variant="secondary" onClick={handleReconnectClick}>
                    Reconnect broker
                  </Button>
                </div>
              ) : null}
              <table className="min-w-full text-sm">
                <thead className="bg-muted/40 text-muted-foreground">
                  <tr>
                    <th className="px-6 py-3 text-left font-medium">Symbol</th>
                    <th className="px-6 py-3 text-left font-medium">Qty</th>
                    <th className="px-6 py-3 text-left font-medium">Avg price</th>
                    <th className="px-6 py-3 text-left font-medium">LTP</th>
                    <th className="px-6 py-3 text-left font-medium">P&L</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-border/60">
                  {holdings.map((item, idx) => {
                    const qty = Number(item.quantity ?? item.qty ?? 0);
                    const avg = Number(item.average_price ?? item.avg_price ?? 0);
                    const ltp = Number(item.last_price ?? 0);
                    const pnl = Number(item.pnl ?? 0);
                    return (
                      <tr key={`${item.tradingsymbol || item.instrument_token || idx}`}>
                        <td className="px-6 py-3">
                          <div className="flex items-center gap-2">
                            <span className="font-semibold">
                              {item.tradingsymbol || item.symbol || "Instrument"}
                            </span>
                            <Badge variant="outline">{item.exchange || item.exchange_type || "N/A"}</Badge>
                          </div>
                        </td>
                        <td className="px-6 py-3">{qty}</td>
                        <td className="px-6 py-3">{formatCurrency(avg, { decimals: 2 })}</td>
                        <td className="px-6 py-3">{ltp ? formatCurrency(ltp, { decimals: 2 }) : "-"}</td>
                        <td className="px-6 py-3">
                          <span className={pnl >= 0 ? "text-emerald-500" : "text-red-500"}>
                            {formatCurrency(pnl, { decimals: 2 })}
                          </span>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
        </div>

        <div
          className={`rounded-2xl border border-border/60 bg-card/70 shadow-xl overflow-hidden ${hoverLift} ${revealTransition} ${cardRevealClass}`}
          style={prefersReducedMotion ? undefined : { transitionDelay: "560ms" }}
        >
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-3 px-6 py-4 border-b border-border/50">
            <div className="space-y-1">
              <p className="text-sm font-semibold">System arm</p>
              <p className="text-xs text-muted-foreground">
                Re-arm all active strategies after broker login.
              </p>
            </div>
            <Button
              className="shimmer"
              onClick={() => armMutation.mutate()}
              disabled={armMutation.isPending || !isConnected}
            >
              <PlugZap className="h-4 w-4" />
              {armMutation.isPending ? "Arming..." : "Arm All Strategies"}
            </Button>
          </div>
          <div className="grid gap-4 md:grid-cols-5 px-6 py-4 text-sm">
            <div className="space-y-1">
              <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Broker</p>
              <p className="font-semibold">
                {isConnected ? "Connected" : "Not connected"}
              </p>
            </div>
            <div className="space-y-1">
              <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Armed</p>
              <p className="font-semibold">{armedCount}</p>
            </div>
            <div className="space-y-1">
              <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Market</p>
              <p className="font-semibold">{marketState}</p>
            </div>
            <div className="space-y-1">
              <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Next execution</p>
              <p className="font-semibold">
                {nextExecution ? formatMinuteTimestamp(nextExecution) : "Unknown"}
              </p>
            </div>
            <div className="space-y-1">
              <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Engine</p>
              <p className="font-semibold">{liveness}</p>
            </div>
          </div>
          {armSummary ? (
            <div className="px-6 pb-4 text-xs text-muted-foreground">
              System armed. {armSummary.failed_runs?.length ? "Some runs failed to arm." : "All runs armed."}
            </div>
          ) : null}
        </div>

        <div
          className={`rounded-2xl border border-border/60 bg-card/70 shadow-xl overflow-hidden ${hoverLift} ${revealTransition} ${cardRevealClass}`}
          style={prefersReducedMotion ? undefined : { transitionDelay: "580ms" }}
        >
          <div className="flex items-center justify-between px-6 py-4 border-b border-border/50">
            <div className="space-y-1">
              <p className="text-sm font-semibold">Strategy status</p>
              <p className="text-xs text-muted-foreground">
                Live status for every configured strategy run.
              </p>
            </div>
            <Badge variant="outline">{systemRuns.length} total</Badge>
          </div>
          {systemStatusQuery.isLoading ? (
            <ZeroState message="Loading strategy status..." />
          ) : systemRuns.length === 0 ? (
            <ZeroState message="No strategies configured yet." />
          ) : (
            <div className="overflow-x-auto">
              <table className="min-w-full text-sm">
                <thead className="bg-muted/40 text-muted-foreground">
                  <tr>
                    <th className="px-6 py-3 text-left font-medium">Strategy</th>
                    <th className="px-6 py-3 text-left font-medium">Mode</th>
                    <th className="px-6 py-3 text-left font-medium">Status</th>
                    <th className="px-6 py-3 text-left font-medium">Next run</th>
                    <th className="px-6 py-3 text-left font-medium">Broker</th>
                    <th className="px-6 py-3 text-left font-medium">Lifecycle</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-border/60">
                  {systemRuns.map((run) => (
                    <tr key={run.run_id}>
                      <td className="px-6 py-3">
                        {run.strategy || "Strategy"}
                      </td>
                      <td className="px-6 py-3">{run.mode || "-"}</td>
                      <td className="px-6 py-3">{run.status}</td>
                      <td className="px-6 py-3">
                        {run.next_run ? new Date(run.next_run).toLocaleString() : "-"}
                      </td>
                      <td className="px-6 py-3">{run.broker || "-"}</td>
                      <td className="px-6 py-3">{run.lifecycle || run.status}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>

        <div
          className={`rounded-2xl border border-border/60 bg-card/70 shadow-xl overflow-hidden ${hoverLift} ${revealTransition} ${cardRevealClass}`}
          style={prefersReducedMotion ? undefined : { transitionDelay: "600ms" }}
        >
          <div className="flex items-center justify-between px-6 py-4 border-b border-border/50">
            <div className="space-y-1">
              <p className="text-sm font-semibold">Strategy control</p>
              <p className="text-xs text-muted-foreground">
                Start or stop the Golden Nifty SIP engine from the dashboard.
              </p>
            </div>
            <div className="flex items-center gap-2">
              <Badge variant="outline" className={livenessBadgeClass}>
                {liveness}
              </Badge>
              <Badge
                variant="outline"
                className={
                  normalizedStrategyStatus === "RUNNING"
                    ? "border-emerald-500/50 bg-emerald-500/10 text-emerald-400"
                    : "border-red-500/40 bg-red-500/10 text-red-400"
                }
              >
                {normalizedStrategyStatus}
              </Badge>
            </div>
          </div>
          <div className="p-6 space-y-4">
            <div className="rounded-lg border border-border/60 bg-background/40 px-4 py-3">
              <div className="text-xs uppercase tracking-[0.18em] text-muted-foreground">
                Next eligible SIP
              </div>
              <div className="text-sm font-semibold text-foreground">{nextEligibleLine}</div>
              {eligibilityStatus ? (
                <div className={`text-xs ${eligibilityClass}`}>{eligibilityStatus}</div>
              ) : null}
            </div>
            <div className="grid gap-4 md:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="strategy-sip">SIP Amount</Label>
                <Input
                  id="strategy-sip"
                  type="number"
                  min={0}
                  step={100}
                  value={sipAmount}
                  onChange={(event) => {
                    const value = Number(event.target.value);
                    setSipAmount(Number.isNaN(value) ? 0 : value);
                  }}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="strategy-frequency">Frequency (days)</Label>
                <Input
                  id="strategy-frequency"
                  type="number"
                  min={1}
                  step={1}
                  value={frequencyDays}
                  onChange={(event) => {
                    const value = Number(event.target.value);
                    setFrequencyDays(Number.isNaN(value) ? 1 : value);
                  }}
                />
              </div>
            </div>
            <div className="flex flex-wrap gap-2">
              <MotionButton
                {...ctaMotionProps}
                onClick={handleStart}
                disabled={isStarting || !executionAllowed || isStrategyRunning}
                className="shimmer"
              >
                {isStarting ? "Starting..." : "Start Strategy"}
              </MotionButton>
              <Button variant="outline" onClick={handleStop} disabled={isStopping}>
                {isStopping ? "Stopping..." : "Stop Strategy"}
              </Button>
            </div>
            {marketState === "CLOSED" ? (
              <p className="text-xs text-muted-foreground">
                Market closed — execution will resume at next session
              </p>
            ) : null}
            {isStrategyRunning ? (
              <p className="text-xs text-muted-foreground">
                Strategy running — next SIP will execute when eligible
              </p>
            ) : null}
          </div>
        </div>

        <StrategyTimeline />

        <div
          className={`rounded-2xl border border-border/60 bg-card/70 shadow-xl p-6 space-y-4 ${hoverLift} ${revealTransition} ${cardRevealClass}`}
          style={prefersReducedMotion ? undefined : { transitionDelay: "700ms" }}
        >
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-3">
            <div>
              <p className="text-sm font-semibold">Equity curve</p>
              <p className="text-xs text-muted-foreground">
                Track your account value over time from your demat open date.
              </p>
            </div>
            <div className="flex items-center gap-2">
              <Label htmlFor="equity-start" className="text-xs text-muted-foreground">
                From
              </Label>
              <Input
                id="equity-start"
                type="date"
                value={startDate}
                max={formatDateInput(new Date())}
                min={linkedAtInput}
                onChange={(e) => setStartDate(e.target.value)}
                className="w-[180px]"
                disabled={!isConnected}
              />
            </div>
          </div>

          {!isConnected ? (
            <ZeroState message="Connect to broker to see your equity curve." />
          ) : equityCurveQuery.isLoading && equityCurvePoints.length === 0 ? (
            <ZeroState message="Loading equity curve..." />
          ) : equityCurveQuery.isError && equityCurvePoints.length === 0 ? (
            <ZeroState message="Could not load equity curve." />
          ) : equityCurvePoints.length === 0 ? (
            <ZeroState message="Could not load equity curve." />
          ) : (
            <div className="h-80">
              <ChartContainer
                config={{
                  equity: { label: "Equity", color: "hsl(var(--chart-1))" },
                }}
                className="rounded-xl bg-background/60"
              >
                <AreaChart data={equityCurvePoints}>
                  <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
                  <XAxis
                    dataKey="date"
                    tickFormatter={(value) => new Date(value).toLocaleDateString("en-IN", { month: "short", day: "numeric" })}
                    tickLine={false}
                    axisLine={false}
                    minTickGap={24}
                  />
                  <YAxis
                    tickFormatter={(v) =>
                      new Intl.NumberFormat("en-IN", { maximumFractionDigits: 0, notation: "compact" }).format(v as number)
                    }
                    width={80}
                  />
                  <ChartTooltip
                    content={
                      <ChartTooltipContent
                        labelFormatter={(value) =>
                          new Date(value as string).toLocaleDateString("en-IN", {
                            year: "numeric",
                            month: "short",
                            day: "numeric",
                          })
                        }
                        formatter={(val) => formatCurrency(Number(val))}
                      />
                    }
                  />
                  <Area
                    type="monotone"
                    dataKey="value"
                    stroke="var(--color-equity)"
                    fill="var(--color-equity)"
                    fillOpacity={0.15}
                    strokeWidth={2}
                  />
                </AreaChart>
              </ChartContainer>
              <p className="text-xs text-muted-foreground mt-2">
                Account open date: {equityCurve?.accountOpenDate
                  ? new Date(equityCurve.accountOpenDate).toLocaleDateString("en-IN")
                  : "unknown"}
              </p>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

function SummaryCard({
  icon,
  label,
  value,
  muted,
  subText,
  prefersReducedMotion,
}: {
  icon: React.ReactNode;
  label: string;
  value: string;
  muted?: boolean;
  subText?: string;
  prefersReducedMotion: boolean;
}) {
  const cardRef = useRef<HTMLDivElement | null>(null);
  const [transform, setTransform] = useState({ rotateX: 0, rotateY: 0, scale: 1 });
  const hoverClass = prefersReducedMotion
    ? ""
    : "transition-all duration-300";

  const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
    if (prefersReducedMotion || !cardRef.current) return;
    const rect = cardRef.current.getBoundingClientRect();
    const x = (event.clientX - rect.left) / rect.width - 0.5;
    const y = (event.clientY - rect.top) / rect.height - 0.5;
    setTransform({
      rotateX: y * -8,
      rotateY: x * 8,
      scale: 1.02,
    });
  };

  const handleMouseLeave = () => {
    if (prefersReducedMotion) return;
    setTransform({ rotateX: 0, rotateY: 0, scale: 1 });
  };

  const tiltStyle = prefersReducedMotion
    ? undefined
    : {
        transform: `perspective(900px) rotateX(${transform.rotateX}deg) rotateY(${transform.rotateY}deg) scale(${transform.scale})`,
        transition: "transform 0.12s ease-out",
      };

  return (
    <div
      ref={cardRef}
      className={`rounded-xl border border-border/70 bg-card/80 p-4 shadow-sm ${hoverClass}`}
      style={prefersReducedMotion ? undefined : { perspective: "900px" }}
      onMouseMove={handleMouseMove}
      onMouseLeave={handleMouseLeave}
    >
      <div className="will-change-transform" style={tiltStyle}>
        <div className="flex items-center gap-3">
          <div className="rounded-full bg-primary/10 p-2 text-primary">{icon}</div>
          <div>
            <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">{label}</p>
            <p className={`text-xl font-semibold ${muted ? "text-muted-foreground" : "text-foreground"}`}>
              <motion.span
                key={value}
                initial={{ opacity: 0.6, y: 3 }}
                animate={{ opacity: 1, y: 0 }}
                transition={{ duration: 0.25, ease: "easeOut" }}
              >
                {value}
              </motion.span>
            </p>
            {subText ? <p className="text-xs text-muted-foreground">{subText}</p> : null}
          </div>
        </div>
      </div>
    </div>
  );
}

function ZeroState({ message }: { message: string }) {
  return (
    <div className="flex flex-col items-center justify-center gap-3 px-6 py-12 text-center">
      <div className="rounded-full bg-muted/70 p-3 text-muted-foreground">
        <Wallet className="h-6 w-6" />
      </div>
      <p className="text-sm font-medium">{message}</p>
      <p className="text-xs text-muted-foreground max-w-md">
        Once connected, we will pull your latest holdings and live positions securely from your broker.
      </p>
    </div>
  );
}
