import { useEffect, useMemo, useState } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import {
  ArrowRight,
  ArrowUpRight,
  ChevronLeft,
  PlugZap,
  RefreshCcw,
  ShieldCheck,
  Sparkles,
} from "lucide-react";
import { AnimatePresence, motion } from "framer-motion";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { toast } from "@/hooks/use-toast";
import { apiRequest, getQueryFn } from "@/lib/queryClient";
import type { User } from "@shared/schema";
import LoginRequiredDialog from "./LoginRequiredDialog";

type BrokerConnectDialogProps = {
  layout?: "desktop" | "mobile";
  open?: boolean;
  onOpenChange?: (open: boolean) => void;
  triggerClassName?: string;
};

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

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

type HoldingsResponse = {
  broker?: string;
  holdings?: any[];
};

type BrokerKey = "ZERODHA" | "GROWW";

type BrokerChoice = {
  key: BrokerKey;
  title: string;
  subtitle: string;
  accentClass: string;
  glowClass: string;
  bulletOne: string;
  bulletTwo: string;
  connectLabel: string;
};

const CALLBACK_STORAGE_KEY = "zerodha:callback";
const CALLBACK_MAX_AGE_MS = 5 * 60 * 1000;

const brokerChoices: BrokerChoice[] = [
  {
    key: "ZERODHA",
    title: "Zerodha",
    subtitle: "Use the Kite login flow and finish the broker approval in a new tab.",
    accentClass: "border-cyan-400/40 bg-cyan-500/10 text-cyan-200",
    glowClass: "from-cyan-500/20 via-cyan-500/5 to-transparent",
    bulletOne: "Browser-based login approval",
    bulletTwo: "Saved credential reconnect after first setup",
    connectLabel: "Continue with Zerodha",
  },
  {
    key: "GROWW",
    title: "Groww",
    subtitle: "Use direct API approval and create a live broker session without a callback step.",
    accentClass: "border-emerald-400/40 bg-emerald-500/10 text-emerald-200",
    glowClass: "from-emerald-500/20 via-emerald-500/5 to-transparent",
    bulletOne: "Direct API key and secret approval",
    bulletTwo: "Server-side reconnect using saved approval",
    connectLabel: "Continue with Groww",
  },
];

function buildReconnectRedirectUrl() {
  const url = new URL(`${window.location.origin}/login`);
  url.searchParams.set("flow", "reconnect");
  return url.toString();
}

function formatBrokerName(broker?: string | null) {
  const normalized = (broker || "").trim().toUpperCase();
  if (normalized === "GROWW") return "Groww";
  if (normalized === "ZERODHA") return "Zerodha";
  return normalized || "broker";
}

function BrokerChoiceCard({
  choice,
  onSelect,
}: {
  choice: BrokerChoice;
  onSelect: (broker: BrokerKey) => void;
}) {
  return (
    <motion.button
      type="button"
      onClick={() => onSelect(choice.key)}
      className="group relative overflow-hidden rounded-2xl border border-border/60 bg-background/70 p-5 text-left shadow-lg transition-colors hover:border-primary/50"
      whileHover={{
        y: -8,
        boxShadow: "0 24px 60px rgba(0,0,0,0.22)",
      }}
      whileTap={{ scale: 0.99 }}
      transition={{ type: "spring", stiffness: 320, damping: 24 }}
    >
      <div className={`pointer-events-none absolute inset-0 bg-gradient-to-br ${choice.glowClass} opacity-90`} />
      <div className="relative space-y-5">
        <div className="flex items-start justify-between gap-3">
          <div className="space-y-2">
            <div className="flex items-center gap-2">
              <div className="rounded-full bg-primary/15 p-2 text-primary">
                <PlugZap className="h-4 w-4" />
              </div>
              <p className="text-lg font-semibold">{choice.title}</p>
            </div>
            <p className="max-w-sm text-sm leading-6 text-muted-foreground">{choice.subtitle}</p>
          </div>
          <Badge className={choice.accentClass}>Live</Badge>
        </div>

        <div className="grid gap-2 text-sm text-muted-foreground">
          <div className="rounded-xl border border-white/5 bg-background/65 px-3 py-2">
            {choice.bulletOne}
          </div>
          <div className="rounded-xl border border-white/5 bg-background/65 px-3 py-2">
            {choice.bulletTwo}
          </div>
        </div>

        <div className="flex items-center justify-between rounded-xl border border-primary/20 bg-primary/10 px-3 py-3 text-sm font-medium text-primary">
          <span>{choice.connectLabel}</span>
          <ArrowRight className="h-4 w-4 transition-transform group-hover:translate-x-1" />
        </div>
      </div>
    </motion.button>
  );
}

export default function BrokerConnectDialog({
  layout = "desktop",
  open,
  onOpenChange,
  triggerClassName: triggerClassNameProp,
}: BrokerConnectDialogProps) {
  const [connectOpenInternal, setConnectOpenInternal] = useState(false);
  const isControlled = open !== undefined;
  const connectOpen = isControlled ? open : connectOpenInternal;
  const setConnectOpen = (nextOpen: boolean) => {
    if (!isControlled) {
      setConnectOpenInternal(nextOpen);
    }
    onOpenChange?.(nextOpen);
  };
  const [loginPromptOpen, setLoginPromptOpen] = useState(false);
  const [selectedBroker, setSelectedBroker] = useState<BrokerKey | null>(null);
  const [zerodhaApiKey, setZerodhaApiKey] = useState("");
  const [zerodhaApiSecret, setZerodhaApiSecret] = useState("");
  const [growwApiKey, setGrowwApiKey] = useState("");
  const [growwApiSecret, setGrowwApiSecret] = useState("");
  const [holdings, setHoldings] = useState<any[]>([]);

  const { refetch: refetchSessionUser } = useQuery<SessionUser | null>({
    queryKey: ["/me"],
    queryFn: getQueryFn<SessionUser | null>({ on401: "returnNull" }),
    staleTime: 0,
    refetchOnMount: "always",
  });

  const { data: brokerStatus, refetch: refetchStatus } = useQuery<BrokerStatusResponse | null>({
    queryKey: ["/broker/status"],
    queryFn: getQueryFn<BrokerStatusResponse>({ on401: "returnNull" }),
    staleTime: 0,
    refetchOnMount: "always",
  });

  const connected = !!brokerStatus?.connected;
  const connectedBroker = (brokerStatus?.broker || "").trim().toUpperCase() as BrokerKey | "";
  const brokerLabel = formatBrokerName(connectedBroker);
  const connectedAt = brokerStatus?.connected_at ? new Date(brokerStatus.connected_at) : null;
  const canReconnectWithSavedZerodha = connected && connectedBroker === "ZERODHA";
  const canReconnectWithSavedGroww = connected && connectedBroker === "GROWW";

  const triggerClassName = useMemo(() => {
    const layoutClasses =
      layout === "mobile" ? "w-full justify-center shimmer" : "px-4 rounded-xl shimmer";
    return connected
      ? `${layoutClasses} disabled:opacity-100 disabled:cursor-default`
      : layoutClasses;
  }, [connected, layout]);

  const selectedChoice = brokerChoices.find((choice) => choice.key === selectedBroker) || null;

  const zerodhaLoginMutation = useMutation({
    mutationFn: async () => {
      if (!zerodhaApiKey.trim()) {
        throw new Error("Zerodha API key is required");
      }
      if (!zerodhaApiSecret.trim()) {
        throw new Error("Zerodha API secret is required");
      }
      const redirectUrl = `${window.location.origin}/login`;
      const res = await apiRequest("POST", "/broker/zerodha/login", {
        apiKey: zerodhaApiKey,
        apiSecret: zerodhaApiSecret,
        redirectUrl,
      });
      return (await res.json()) as { loginUrl: string };
    },
    onSuccess: ({ loginUrl }) => {
      window.open(loginUrl, "_blank", "noopener,noreferrer");
      toast({
        title: "Continue in Zerodha",
        description: "Log in and return here. We will connect your broker automatically.",
      });
    },
    onError: (err: any) =>
      toast({
        title: "Could not start Zerodha login",
        description: err?.message || "Try again.",
      }),
  });

  const zerodhaReconnectMutation = useMutation({
    mutationFn: async () => {
      const redirectUrl = buildReconnectRedirectUrl();
      const params = new URLSearchParams({ redirectUrl });
      const res = await apiRequest("GET", `/broker/login-url?${params.toString()}`);
      return (await res.json()) as { loginUrl: string };
    },
    onSuccess: ({ loginUrl }) => {
      window.open(loginUrl, "_blank", "noopener,noreferrer");
      toast({
        title: "Continue in Zerodha",
        description: "Log in and return here. We will reconnect your broker automatically.",
      });
    },
    onError: (err: any) => {
      const message = String(err?.message || "");
      if (message.includes("400:") && message.includes("Broker credentials not configured")) {
        toast({
          title: "Enter Zerodha API credentials",
          description: "Saved credentials are missing. Enter the API key and secret once to reconnect.",
        });
        return;
      }
      toast({
        title: "Could not reconnect Zerodha",
        description: err?.message || "Try again.",
      });
    },
  });

  const growwConnectMutation = useMutation({
    mutationFn: async () => {
      if (!growwApiKey.trim()) {
        throw new Error("Groww API key is required");
      }
      if (!growwApiSecret.trim()) {
        throw new Error("Groww API secret is required");
      }
      const res = await apiRequest("POST", "/broker/groww/connect", {
        apiKey: growwApiKey,
        apiSecret: growwApiSecret,
      });
      return (await res.json()) as {
        connected?: boolean;
        broker?: string;
        userName?: string;
      };
    },
    onSuccess: async (data) => {
      await refetchStatus();
      setConnectOpen(false);
      toast({
        title: "Groww connected",
        description:
          data?.userName
            ? `Connected as ${data.userName}.`
            : "Your Groww broker session is now active.",
      });
    },
    onError: (err: any) =>
      toast({
        title: "Could not connect Groww",
        description: err?.message || "Try again.",
      }),
  });

  const growwReconnectMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest("POST", "/broker/groww/reconnect");
      return (await res.json()) as {
        connected?: boolean;
        broker?: string;
        userName?: string;
      };
    },
    onSuccess: async (data) => {
      await refetchStatus();
      toast({
        title: "Groww reconnected",
        description:
          data?.userName
            ? `Session refreshed for ${data.userName}.`
            : "Your Groww broker session has been refreshed.",
      });
    },
    onError: (err: any) => {
      const message = String(err?.message || "");
      if (message.includes("400:") && message.includes("Broker credentials not configured")) {
        toast({
          title: "Enter Groww API credentials",
          description: "Saved credentials are missing. Enter the API key and secret once to reconnect.",
        });
        return;
      }
      toast({
        title: "Could not reconnect Groww",
        description: err?.message || "Try again.",
      });
    },
  });

  const holdingsMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest("GET", "/broker/holdings");
      return (await res.json()) as HoldingsResponse;
    },
    onSuccess: (data) => {
      setHoldings(data?.holdings || []);
      toast({
        title: "Holdings fetched",
        description: `Latest positions pulled from ${formatBrokerName(
          data?.broker || brokerStatus?.broker,
        )}.`,
      });
    },
    onError: (err: any) =>
      toast({
        title: "Could not fetch holdings",
        description: err?.message || "Check your broker session and try again.",
      }),
  });

  const disconnectMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest("POST", "/broker/disconnect");
      return (await res.json()) as { connected: boolean };
    },
    onSuccess: async () => {
      await refetchStatus();
      setSelectedBroker(null);
      toast({
        title: "Broker disconnected",
        description: "Your broker has been unlinked.",
      });
    },
    onError: (err: any) =>
      toast({
        title: "Disconnect failed",
        description: err?.message || "Try again.",
      }),
  });

  const handleConnectClick = async () => {
    if (connected) {
      return;
    }
    const latest = await refetchSessionUser();
    if (!latest.data) {
      setLoginPromptOpen(true);
      return;
    }
    setConnectOpen(true);
  };

  useEffect(() => {
    if (!connectOpen) {
      setSelectedBroker(null);
      return;
    }
    if (connectedBroker === "ZERODHA" || connectedBroker === "GROWW") {
      setSelectedBroker(connectedBroker);
      return;
    }
    setSelectedBroker(null);
  }, [connectOpen, connectedBroker]);

  useEffect(() => {
    const consumeCallback = (rawValue?: string) => {
      const value = rawValue || localStorage.getItem(CALLBACK_STORAGE_KEY);
      if (!value) return;
      localStorage.removeItem(CALLBACK_STORAGE_KEY);

      try {
        const payload = JSON.parse(value) as {
          status?: "success" | "error";
          message?: string;
          ts?: number;
        };
        if (payload.ts && Date.now() - payload.ts > CALLBACK_MAX_AGE_MS) {
          return;
        }
        if (payload.status === "success") {
          refetchStatus();
          toast({
            title: "Zerodha connected",
            description: "Your broker connection has been completed.",
          });
          setConnectOpen(false);
        } else if (payload.status === "error") {
          toast({
            title: "Zerodha login failed",
            description: payload.message || "Please retry the login.",
          });
        }
      } catch {
        return;
      }
    };

    consumeCallback();

    const handleStorage = (event: StorageEvent) => {
      if (event.key !== CALLBACK_STORAGE_KEY || !event.newValue) {
        return;
      }
      consumeCallback(event.newValue);
    };

    window.addEventListener("storage", handleStorage);
    return () => window.removeEventListener("storage", handleStorage);
  }, [refetchStatus]);

  const renderSelectedBrokerForm = () => {
    if (!selectedChoice) {
      return null;
    }

    if (selectedChoice.key === "ZERODHA") {
      return (
        <motion.div
          key="zerodha-step"
          initial={{ opacity: 0, x: 20 }}
          animate={{ opacity: 1, x: 0 }}
          exit={{ opacity: 0, x: -20 }}
          transition={{ duration: 0.28, ease: "easeOut" }}
          className="space-y-4"
        >
          <div className="relative overflow-hidden rounded-2xl border border-cyan-400/30 bg-background/80 p-5">
            <div className="absolute inset-0 bg-gradient-to-br from-cyan-500/20 via-transparent to-transparent" />
            <div className="relative flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
              <div className="space-y-2">
                <div className="flex items-center gap-2">
                  <div className="rounded-full bg-cyan-500/15 p-2 text-cyan-200">
                    <PlugZap className="h-4 w-4" />
                  </div>
                  <p className="text-lg font-semibold">Zerodha approval</p>
                </div>
                <p className="max-w-2xl text-sm leading-6 text-muted-foreground">
                  Enter your Kite API key and secret, then continue in Zerodha to approve the session. After the
                  first setup, reconnect can reuse the saved credentials.
                </p>
              </div>
              <Badge className="border-cyan-400/40 bg-cyan-500/10 text-cyan-200">Live flow</Badge>
            </div>
          </div>

          <div className="grid gap-4 md:grid-cols-2">
            <div className="space-y-1.5">
              <Label htmlFor="zerodha-api-key">API key</Label>
              <Input
                id="zerodha-api-key"
                placeholder="Enter Zerodha API key"
                value={zerodhaApiKey}
                onChange={(e) => setZerodhaApiKey(e.target.value)}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="zerodha-api-secret">API secret</Label>
              <Input
                id="zerodha-api-secret"
                placeholder="Enter Zerodha API secret"
                type="password"
                value={zerodhaApiSecret}
                onChange={(e) => setZerodhaApiSecret(e.target.value)}
              />
            </div>
          </div>

          <div className="flex flex-col gap-2 sm:flex-row sm:flex-wrap">
            <Button
              className="w-full sm:w-auto"
              onClick={() => zerodhaLoginMutation.mutate()}
              disabled={zerodhaLoginMutation.isPending}
            >
              <ArrowUpRight className="h-4 w-4" />
              {zerodhaLoginMutation.isPending ? "Opening Zerodha..." : "Open Zerodha login"}
            </Button>
            {canReconnectWithSavedZerodha ? (
              <Button
                variant="secondary"
                className="w-full sm:w-auto"
                onClick={() => zerodhaReconnectMutation.mutate()}
                disabled={zerodhaReconnectMutation.isPending}
              >
                <RefreshCcw className="h-4 w-4" />
                {zerodhaReconnectMutation.isPending ? "Opening Zerodha..." : "Reconnect saved Zerodha"}
              </Button>
            ) : null}
          </div>

          <div className="rounded-2xl border border-border/60 bg-background/60 p-4 text-xs leading-6 text-muted-foreground">
            Keep this tab open until the broker login completes. Zerodha access tokens expire daily, so reconnect
            may be required after market sessions.
          </div>
        </motion.div>
      );
    }

    return (
      <motion.div
        key="groww-step"
        initial={{ opacity: 0, x: 20 }}
        animate={{ opacity: 1, x: 0 }}
        exit={{ opacity: 0, x: -20 }}
        transition={{ duration: 0.28, ease: "easeOut" }}
        className="space-y-4"
      >
        <div className="relative overflow-hidden rounded-2xl border border-emerald-400/30 bg-background/80 p-5">
          <div className="absolute inset-0 bg-gradient-to-br from-emerald-500/20 via-transparent to-transparent" />
          <div className="relative flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
            <div className="space-y-2">
              <div className="flex items-center gap-2">
                <div className="rounded-full bg-emerald-500/15 p-2 text-emerald-200">
                  <Sparkles className="h-4 w-4" />
                </div>
                <p className="text-lg font-semibold">Groww approval</p>
              </div>
              <p className="max-w-2xl text-sm leading-6 text-muted-foreground">
                Enter your Groww API key and secret to create the broker session directly. Reconnect runs
                server-side, so you can refresh the session without another browser callback step.
              </p>
            </div>
            <Badge className="border-emerald-400/40 bg-emerald-500/10 text-emerald-200">Direct API</Badge>
          </div>
        </div>

        <div className="grid gap-4 md:grid-cols-2">
          <div className="space-y-1.5">
            <Label htmlFor="groww-api-key">API key</Label>
            <Input
              id="groww-api-key"
              placeholder="Enter Groww API key"
              value={growwApiKey}
              onChange={(e) => setGrowwApiKey(e.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="groww-api-secret">API secret</Label>
            <Input
              id="groww-api-secret"
              placeholder="Enter Groww API secret"
              type="password"
              value={growwApiSecret}
              onChange={(e) => setGrowwApiSecret(e.target.value)}
            />
          </div>
        </div>

        <div className="flex flex-col gap-2 sm:flex-row sm:flex-wrap">
          <Button
            className="w-full sm:w-auto"
            onClick={() => growwConnectMutation.mutate()}
            disabled={growwConnectMutation.isPending}
          >
            <PlugZap className="h-4 w-4" />
            {growwConnectMutation.isPending ? "Connecting Groww..." : "Connect Groww"}
          </Button>
          {canReconnectWithSavedGroww ? (
            <Button
              variant="secondary"
              className="w-full sm:w-auto"
              onClick={() => growwReconnectMutation.mutate()}
              disabled={growwReconnectMutation.isPending}
            >
              <RefreshCcw className="h-4 w-4" />
              {growwReconnectMutation.isPending ? "Refreshing Groww..." : "Reconnect saved Groww"}
            </Button>
          ) : null}
        </div>

        <div className="rounded-2xl border border-border/60 bg-background/60 p-4 text-xs leading-6 text-muted-foreground">
          Groww reconnect uses your saved approval data on the server, so the portfolio can refresh access without
          opening another tab after the first setup.
        </div>
      </motion.div>
    );
  };

  return (
    <>
      <Dialog open={connectOpen} onOpenChange={setConnectOpen}>
        <Button
          variant="secondary"
          className={[triggerClassName, triggerClassNameProp].filter(Boolean).join(" ")}
          disabled={connected}
          onClick={handleConnectClick}
        >
          <PlugZap className="h-4 w-4" />
          {connected ? "Broker connected" : "Connect broker"}
        </Button>
        <DialogContent className="overflow-hidden border-border/70 bg-gradient-to-br from-background via-background to-muted/30 sm:max-w-3xl">
          <div className="pointer-events-none absolute inset-0">
            <div className="absolute -right-24 top-0 h-64 w-64 rounded-full bg-primary/10 blur-3xl" />
            <div className="absolute left-0 top-40 h-56 w-56 rounded-full bg-chart-2/10 blur-3xl" />
          </div>

          <motion.div
            className="relative space-y-5"
            initial={{ opacity: 0, y: 12 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.45, ease: "easeOut" }}
          >
            <DialogHeader className="space-y-3">
              <div className="flex flex-wrap items-center gap-2">
                <Badge className="border-primary/30 bg-primary/10 text-primary">Broker setup</Badge>
                <Badge variant={connected ? "secondary" : "outline"}>
                  {connected ? `${brokerLabel} connected` : "No broker connected"}
                </Badge>
              </div>
              <DialogTitle>Connect your broker</DialogTitle>
              <DialogDescription>
                Choose a broker first, then complete a guided setup flow instead of juggling every provider at once.
              </DialogDescription>
            </DialogHeader>

            <div className="grid gap-3 rounded-2xl border border-border/60 bg-card/60 p-3 sm:grid-cols-[1fr_1fr]">
              <div
                className={`rounded-xl px-4 py-3 text-sm ${
                  selectedBroker
                    ? "border border-border/60 bg-background/40 text-muted-foreground"
                    : "border border-primary/30 bg-primary/10 text-primary"
                }`}
              >
                <p className="text-xs uppercase tracking-[0.18em]">Step 1</p>
                <p className="mt-1 font-medium">Choose your broker</p>
              </div>
              <div
                className={`rounded-xl px-4 py-3 text-sm ${
                  selectedBroker
                    ? "border border-primary/30 bg-primary/10 text-primary"
                    : "border border-border/60 bg-background/40 text-muted-foreground"
                }`}
              >
                <p className="text-xs uppercase tracking-[0.18em]">Step 2</p>
                <p className="mt-1 font-medium">Enter broker details</p>
              </div>
            </div>

            <div className="rounded-2xl border border-border/60 bg-card/70 p-4">
              <div className="mb-4 flex flex-col gap-3 rounded-2xl border border-border/60 bg-gradient-to-r from-primary/10 via-background to-background px-4 py-4">
                <div className="flex items-start gap-3">
                  <div className="rounded-full bg-primary/15 p-2 text-primary">
                    <Sparkles className="h-4 w-4" />
                  </div>
                  <div className="space-y-1 text-sm">
                    <p className="font-medium">Secure brokerage linking</p>
                    <p className="leading-6 text-muted-foreground">
                      The setup keeps your execution on the broker side while QuantFortune only syncs holdings,
                      funds, and live strategy status.
                    </p>
                  </div>
                </div>
                {connected ? (
                  <div className="flex items-center gap-2 text-xs text-muted-foreground">
                    <ShieldCheck className="h-4 w-4 text-primary" />
                    <span>
                      {brokerStatus?.userName
                        ? `Linked as ${brokerStatus.userName}`
                        : `Linked to ${brokerLabel}`}{" "}
                      via {brokerLabel}
                      {" - "}
                      {connectedAt ? connectedAt.toLocaleString() : "just now"}
                    </span>
                  </div>
                ) : null}
              </div>

              <AnimatePresence mode="wait">
                {!selectedBroker ? (
                  <motion.div
                    key="broker-picker"
                    initial={{ opacity: 0, x: -20 }}
                    animate={{ opacity: 1, x: 0 }}
                    exit={{ opacity: 0, x: 20 }}
                    transition={{ duration: 0.28, ease: "easeOut" }}
                    className="space-y-5"
                  >
                    <div className="space-y-1">
                      <p className="text-lg font-semibold">Choose a broker to connect</p>
                      <p className="text-sm text-muted-foreground">
                        Pick the broker you want to authorize now. You can change or reconnect later from the same dashboard.
                      </p>
                    </div>

                    <div className="grid gap-4 xl:grid-cols-2">
                      {brokerChoices.map((choice) => (
                        <BrokerChoiceCard
                          key={choice.key}
                          choice={choice}
                          onSelect={setSelectedBroker}
                        />
                      ))}
                    </div>

                    <div className="rounded-2xl border border-dashed border-border/50 bg-background/50 p-4">
                      <p className="text-sm font-medium text-foreground">More brokers on the way</p>
                      <div className="mt-3 flex flex-wrap gap-2 text-sm text-muted-foreground">
                        <Badge variant="outline">Angel One (coming soon)</Badge>
                        <Badge variant="outline">ICICI Direct (coming soon)</Badge>
                        <Badge variant="outline">HDFC Securities (coming soon)</Badge>
                      </div>
                    </div>
                  </motion.div>
                ) : (
                  <motion.div
                    key={`broker-details-${selectedBroker}`}
                    initial={{ opacity: 0, x: 20 }}
                    animate={{ opacity: 1, x: 0 }}
                    exit={{ opacity: 0, x: -20 }}
                    transition={{ duration: 0.28, ease: "easeOut" }}
                    className="space-y-4"
                  >
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <Button
                        variant="ghost"
                        className="h-auto px-0 text-muted-foreground hover:bg-transparent hover:text-foreground"
                        onClick={() => setSelectedBroker(null)}
                      >
                        <ChevronLeft className="mr-1 h-4 w-4" />
                        Back to broker selection
                      </Button>
                      <Badge className={selectedChoice?.accentClass}>{selectedChoice?.title}</Badge>
                    </div>

                    {renderSelectedBrokerForm()}
                  </motion.div>
                )}
              </AnimatePresence>

              {connected ? (
                <div className="mt-5 space-y-3 rounded-2xl border border-border/60 bg-background/80 p-4">
                  <div className="flex flex-wrap items-center gap-2">
                    <div className="flex items-center gap-2">
                      <ShieldCheck className="h-4 w-4 text-primary" />
                      <p className="text-sm font-semibold">Latest holdings</p>
                    </div>
                    <div className="ml-auto flex flex-wrap gap-2">
                      <Button
                        variant="secondary"
                        onClick={() => holdingsMutation.mutate()}
                        disabled={holdingsMutation.isPending}
                      >
                        <RefreshCcw className="h-4 w-4" />
                        {holdingsMutation.isPending ? "Fetching..." : "Fetch holdings"}
                      </Button>
                      <Button
                        variant="outline"
                        onClick={() => disconnectMutation.mutate()}
                        disabled={disconnectMutation.isPending}
                      >
                        {disconnectMutation.isPending ? "Disconnecting..." : "Disconnect broker"}
                      </Button>
                    </div>
                  </div>

                  {holdings.length === 0 ? (
                    <p className="text-xs text-muted-foreground">
                      No holdings pulled yet. Click &ldquo;Fetch holdings&rdquo; after connecting.
                    </p>
                  ) : (
                    <div className="grid gap-2">
                      {holdings.map((item, idx) => (
                        <div
                          key={`${item.tradingsymbol || item.instrument_token || item.symbol || idx}`}
                          className="flex items-center justify-between rounded-md border border-border/50 bg-card/40 px-3 py-2 text-sm"
                        >
                          <div>
                            <p className="font-medium">
                              {item.tradingsymbol || item.symbol || "Instrument"}
                            </p>
                            <p className="text-xs text-muted-foreground">
                              Qty: {item.quantity ?? item.qty ?? "-"} | Avg:{" "}
                              {item.average_price ?? item.avg_price ?? "-"}
                            </p>
                          </div>
                          <Badge variant="secondary">
                            {item.exchange || item.exchange_type || "N/A"}
                          </Badge>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              ) : null}
            </div>
          </motion.div>
        </DialogContent>
      </Dialog>
      <LoginRequiredDialog
        open={loginPromptOpen}
        onOpenChange={setLoginPromptOpen}
        context="connect your broker"
      />
    </>
  );
}
