"use client";

import {
  Suspense,
  useEffect,
  useCallback,
  useRef,
  useState,
  useMemo,
} from "react";
import { useQueryState } from "nuqs";
import {
  ColumnMetadata,
  TableMetadata,
  fetchColumns,
  fetchTables,
  fetchClients,
  fetchSchemas,
  runDdl,
  ApiError,
} from "@/app/lib/api";
import { useSettings } from "@/app/lib/settings";
import { FeatureFlags, useAppStore } from "@/app/lib/store";
import { toast } from "sonner";
import Sidebar from "./components/Sidebar";
import DataGrid from "./components/DataGrid";
import SchemaInspector from "./components/SchemaInspector";
import SqlEditor from "./components/SqlEditor";
import DatabaseOverview from "./components/DatabaseOverview";
import SettingsPage from "./components/SettingsPage";
import ClusterHealth from "./components/ClusterHealth";
import ApiKeysPage from "./components/ApiKeysPage";
import SdkDocs from "./components/SdkDocs";
import LogsPage from "./components/LogsPage";
import AuditLogPage from "./components/AuditLogPage";
import BackupsPage from "./components/BackupsPage";
import FunctionsPage from "./components/FunctionsPage";
import TriggersPage from "./components/TriggersPage";
import ReplicationPage from "./components/ReplicationPage";
import AuthPage from "./components/AuthPage";
import AuthConfigPage from "./components/AuthConfigPage";
import ModulesPage from "./components/ModulesPage";
import WorkspacePage from "./components/WorkspacePage";
import ClientStatisticsPage from "./components/ClientStatisticsPage";
import PipelinesPage from "./components/PipelinesPage";
import DataApiPage from "./components/DataApiPage";
import ObservabilityPage from "./components/ObservabilityPage";
import StoragePage from "./components/StoragePage";
import ConnectionModal from "./components/ConnectionModal";
import CreateTableDialog from "./components/CreateTableDialog";
import TableSelectPage from "./components/TableSelectPage";
import CellDetailSheet from "./components/CellDetailSheet";
import RowDetailSheet from "./components/RowDetailSheet";
import TransactionIsland, {
  type PendingEdit,
} from "./components/TransactionIsland";
import {
  Panel,
  Group as PanelGroup,
  Separator as PanelSeparator,
} from "react-resizable-panels";
import { Leva, folder, useControls } from "leva";

/** Matches react-resizable-panels Panel panelRef handle for collapse/expand */
interface PanelHandle {
  collapse: () => void;
  expand: () => void;
  getSize: () => { asPercentage: number; inPixels: number };
  isCollapsed: () => boolean;
  resize: (size: string | number) => void;
}

const envPreferredClient = process.env.NEXT_PUBLIC_ATHENA_CLIENT;
const VIEW_OPTIONS = [
  "table-editor",
  "sql-editor",
  "database",
  "logs",
  "audit-log",
  "functions",
  "triggers",
  "backups",
  "replication",
  "client-statistics",
  "auth",
  "auth-config",
  "api-keys",
  "data-api",
  "observability",
  "storage",
  "settings",
  "cluster-health",
  "sdk-docs",
  "modules",
  "workspace",
  "pipelines",
] as const;

function isTauriRuntime(): boolean {
  if (typeof window === "undefined") return false;
  return "__TAURI_INTERNALS__" in window || "__TAURI__" in window;
}

interface DevLevaControlsProps {
  clients: string[];
  selectedClient: string | null;
  onSelectClient: (client: string) => void;
  schemas: string[];
  currentSchema: string;
  setCurrentSchema: (schema: string) => void;
  activeView: string;
  setActiveView: (view: string) => void;
  tables: TableMetadata[];
  selectedTable: TableMetadata | null;
  onSelectTable: (table: TableMetadata) => void;
  sidebarOpen: boolean;
  inspectorOpen: boolean;
  setSidebarOpen: (open: boolean) => void;
  setInspectorOpen: (open: boolean) => void;
  sidebarMaxWidth: number;
  inspectorMaxWidth: number;
  setSidebarMaxWidth: (pct: number) => void;
  setInspectorMaxWidth: (pct: number) => void;
  flags: FeatureFlags;
  setFlag: (key: keyof FeatureFlags, value: boolean) => void;
}

function DevLevaControls({
  clients,
  selectedClient,
  onSelectClient,
  schemas,
  currentSchema,
  setCurrentSchema,
  activeView,
  setActiveView,
  tables,
  selectedTable,
  onSelectTable,
  sidebarOpen,
  inspectorOpen,
  setSidebarOpen,
  setInspectorOpen,
  sidebarMaxWidth,
  inspectorMaxWidth,
  setSidebarMaxWidth,
  setInspectorMaxWidth,
  flags,
  setFlag,
}: DevLevaControlsProps) {
  const tableNames = useMemo(() => tables.map((t) => t.table_name), [tables]);

  const flagKeys = useMemo(
    () =>
      [
        "enableModules",
        "enableWorkspaceSettings",
        "enableAuthConfig",
        "enableClientStatistics",
        "enableSdkDocs",
        "enableClusterHealth",
        "compactDatagrid",
        "showRowNumbers",
        "showColumnIcons",
        "showDocumentIcons",
        "sortColumnsByDdl",
        "hideNullColumns",
      ] as const,
    [],
  );

  const syncing = useRef(false);

  const [, setValues] = useControls(
    "Dev UI",
    () => ({
      client: {
        value: selectedClient ?? "",
        options: clients.length > 0 ? clients : [""],
        label: "Client",
        onChange: (client: string) => {
          if (syncing.current) return;
          if (!client || client === selectedClient) return;
          onSelectClient(client);
        },
      },
      schema: {
        value: currentSchema,
        options: schemas.length > 0 ? schemas : ["public"],
        label: "Schema",
        onChange: (schema: string) => {
          if (syncing.current) return;
          if (schema === currentSchema) return;
          setCurrentSchema(schema);
        },
      },
      activeView: {
        value: activeView,
        options: VIEW_OPTIONS as unknown as string[],
        label: "View",
        onChange: (view: string) => {
          if (syncing.current) return;
          if (view === activeView) return;
          setActiveView(view);
        },
      },
      sidebarOpen: {
        value: sidebarOpen,
        label: "Sidebar open",
        onChange: (open: boolean) => {
          if (syncing.current) return;
          if (open === sidebarOpen) return;
          setSidebarOpen(open);
        },
      },
      inspectorOpen: {
        value: inspectorOpen,
        label: "Inspector open",
        onChange: (open: boolean) => {
          if (syncing.current) return;
          if (open === inspectorOpen) return;
          setInspectorOpen(open);
        },
      },
      sidebarWidthPct: {
        value: sidebarMaxWidth,
        min: 5,
        max: 60,
        step: 1,
        label: "Sidebar max %",
        onChange: (pct: number) => {
          if (syncing.current) return;
          if (pct === sidebarMaxWidth) return;
          setSidebarMaxWidth(pct);
        },
      },
      inspectorWidthPct: {
        value: inspectorMaxWidth,
        min: 10,
        max: 70,
        step: 1,
        label: "Inspector max %",
        onChange: (pct: number) => {
          if (syncing.current) return;
          if (pct === inspectorMaxWidth) return;
          setInspectorMaxWidth(pct);
        },
      },
      ...(tableNames.length > 0
        ? {
            table: {
              value: selectedTable?.table_name ?? tableNames[0],
              options: tableNames,
              label: "Table",
              onChange: (tableName: string) => {
                if (syncing.current) return;
                if (tableName === selectedTable?.table_name) return;
                const match = tables.find((t) => t.table_name === tableName);
                if (match) onSelectTable(match);
              },
            },
          }
        : {}),
      Flags: folder(
        Object.fromEntries(
          flagKeys.map((key) => [
            key,
            {
              value: flags[key],
              label: key,
              onChange: (v: boolean) => {
                if (syncing.current) return;
                if (flags[key] === v) return;
                setFlag(key, v);
              },
            },
          ]),
        ),
        { collapsed: true },
      ),
    }),
    [
      activeView,
      clients,
      currentSchema,
      flagKeys,
      flags,
      inspectorMaxWidth,
      inspectorOpen,
      schemas,
      selectedClient,
      selectedTable,
      sidebarMaxWidth,
      sidebarOpen,
      tableNames,
      tables,
    ],
  );

  useEffect(() => {
    syncing.current = true;
    setValues({
      client: selectedClient ?? "",
      schema: currentSchema,
      activeView,
      sidebarOpen,
      inspectorOpen,
      sidebarWidthPct: sidebarMaxWidth,
      inspectorWidthPct: inspectorMaxWidth,
      ...(tableNames.length > 0
        ? { table: selectedTable?.table_name ?? tableNames[0] }
        : {}),
      ...Object.fromEntries(flagKeys.map((key) => [key, flags[key]])),
    });
    queueMicrotask(() => {
      syncing.current = false;
    });
  }, [
    activeView,
    currentSchema,
    flags,
    flagKeys,
    inspectorMaxWidth,
    inspectorOpen,
    selectedClient,
    selectedTable?.table_name,
    sidebarMaxWidth,
    sidebarOpen,
    tableNames,
    setValues,
  ]);

  return (
    <div style={{ width: 400, maxWidth: "40vw" }}>
      <Leva collapsed oneLineLabels titleBar={{ title: "Dev Controls" }} fill />
    </div>
  );
}

export default function Home() {
  return (
    <Suspense
      fallback={
        <div className="flex h-screen items-center justify-center bg-background text-muted-foreground text-sm">
          Loading…
        </div>
      }
    >
      <HomeInner />
    </Suspense>
  );
}

function HomeInner() {
  const { baseUrl, apiKey, localBackupApiKey, pgDumpPath, pgRestorePath } =
    useSettings();
  const ctx = useMemo(
    () => ({ baseUrl, apiKey, localBackupApiKey, pgDumpPath, pgRestorePath }),
    [baseUrl, apiKey, localBackupApiKey, pgDumpPath, pgRestorePath],
  );

  const {
    selectedClient,
    setSelectedClient,
    preferences,
    setPreferences,
    flags,
    setFlag,
  } = useAppStore();
  const showDevLeva =
    process.env.NODE_ENV !== "production" && !isTauriRuntime();

  const sidebarPanelRef = useRef<PanelHandle>(null);
  const inspectorPanelRef = useRef<PanelHandle>(null);

  const [clients, setClients] = useState<string[]>([]);
  const [clientsLoading, setClientsLoading] = useState(true);
  const [clientsError, setClientsError] = useState<string | null>(null);
  const [tables, setTables] = useState<TableMetadata[]>([]);

  const [tableParam, setTableParam] = useQueryState("table");
  const [selectedTable, setSelectedTableState] = useState<TableMetadata | null>(
    null,
  );

  const setSelectedTable = useCallback(
    (t: TableMetadata | null) => {
      setSelectedTableState(t);
      setTableParam(t ? t.table_name : null);
    },
    [setTableParam],
  );

  const [columns, setColumns] = useState<ColumnMetadata[]>([]);
  const [columnsLoading, setColumnsLoading] = useState(false);
  const [tablesLoading, setTablesLoading] = useState(false);
  const [tablesError, setTablesError] = useState<string | null>(null);
  const [dataRefreshKey, setDataRefreshKey] = useState(0);
  const [schemaVersion, setSchemaVersion] = useState(0);
  const [activeView, setActiveView] = useState("table-editor");
  const [schemas, setSchemas] = useState<string[]>(["public"]);
  const [currentSchema, setCurrentSchema] = useState("public");
  const [showConnection, setShowConnection] = useState(false);
  const [showCreateTable, setShowCreateTable] = useState(false);
  const [allColumns, setAllColumns] = useState<Map<string, ColumnMetadata[]>>(
    new Map(),
  );

  const [cellDetail, setCellDetail] = useState<{
    column: string;
    columnType?: string;
    value: unknown;
    rowId?: string;
  } | null>(null);

  const [rowDetail, setRowDetail] = useState<Record<string, unknown> | null>(
    null,
  );

  const [pendingEdits, setPendingEdits] = useState<PendingEdit[]>([]);
  const [executingEdits, setExecutingEdits] = useState(false);

  const typeMap = useMemo(() => {
    const m = new Map<string, string>();
    for (const c of columns) {
      if (c.data_type) m.set(c.column_name, c.data_type);
    }
    return m;
  }, [columns]);

  const loadTablesForClient = useCallback(
    (clientName: string) => {
      setTablesLoading(true);
      fetchTables(ctx, clientName)
        .then((entries) => {
          setTables(entries);

          const urlTable = tableParam;
          const match = urlTable
            ? entries.find((t) => t.table_name === urlTable)
            : null;
          const initial = match ?? entries[0] ?? null;
          setSelectedTableState(initial);
          if (initial && !match) setTableParam(initial.table_name);

          setTablesError(entries.length === 0 ? "No tables available" : null);

          const colMap = new Map<string, ColumnMetadata[]>();
          Promise.all(
            entries.slice(0, 50).map((t) =>
              fetchColumns(
                ctx,
                t.table_name,
                clientName,
                undefined,
                0,
                true,
                t.table_schema ?? undefined,
              )
                .then((cols) => {
                  colMap.set(t.table_name, cols);
                })
                .catch(() => {}),
            ),
          ).then(() => setAllColumns(colMap));
        })
        .catch((error) => {
          setTables([]);
          setSelectedTable(null);
          const msg =
            error instanceof ApiError ? error.message : "Failed to load tables";
          setTablesError(msg);
          if (error instanceof ApiError && error.retryable) {
            toast.error("Connection issue", { description: msg });
          }
        })
        .finally(() => setTablesLoading(false));
    },
    [ctx, tableParam, setTableParam, setSelectedTable],
  );

  useEffect(() => {
    let canceled = false;
    fetchClients(ctx)
      .then((entries) => {
        if (canceled) return;
        setClients(entries);

        const storedClient = selectedClient;
        const initial =
          storedClient && entries.includes(storedClient)
            ? storedClient
            : envPreferredClient && entries.includes(envPreferredClient)
              ? envPreferredClient
              : (entries[0] ?? null);

        setSelectedClient(initial);
        setClientsError(
          entries.length === 0 ? "No Postgres clients configured" : null,
        );
        if (initial) {
          loadTablesForClient(initial);
          fetchSchemas(ctx, initial).then((s) => {
            if (!canceled) setSchemas(s.length > 0 ? s : ["public"]);
          });
        }
      })
      .catch((error) => {
        if (canceled) return;
        const msg =
          error instanceof ApiError ? error.message : "Failed to load clients";
        setClientsError(msg);
        if (error instanceof ApiError && error.status === 401) {
          setClientsError(
            "Authentication required — set your API key in Settings",
          );
        }
      })
      .finally(() => {
        if (!canceled) setClientsLoading(false);
      });
    return () => {
      canceled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [ctx]);

  const handleClientChange = useCallback(
    (client: string) => {
      setSelectedClient(client);
      setTables([]);
      setSelectedTable(null);
      setColumns([]);
      loadTablesForClient(client);
      fetchSchemas(ctx, client).then(setSchemas);
    },
    [loadTablesForClient, ctx, setSelectedClient, setSelectedTable],
  );

  useEffect(() => {
    if (!selectedTable || !selectedClient) return;
    const controller = new AbortController();
    setColumnsLoading(true);
    fetchColumns(
      ctx,
      selectedTable.table_name,
      selectedClient,
      controller.signal,
      schemaVersion,
      true,
      selectedTable.table_schema,
    )
      .then((result) => {
        setColumns(result);
      })
      .catch((err) => {
        if (err instanceof ApiError && err.code === "ABORTED") return;
        setColumns([]);
      })
      .finally(() => {
        setColumnsLoading(false);
      });
    return () => {
      controller.abort();
    };
  }, [selectedTable, schemaVersion, selectedClient, ctx]);

  const triggerDataRefresh = () => setDataRefreshKey((p) => p + 1);
  const triggerSchemaRefresh = () => setSchemaVersion((p) => p + 1);

  const handleMutation = () => {
    triggerDataRefresh();
    triggerSchemaRefresh();
  };

  const handleSchemaChange = () => {
    triggerSchemaRefresh();
    triggerDataRefresh();
  };

  const handleSelectTable = useCallback(
    (table: TableMetadata) => {
      setSelectedTable(table);
      setColumns([]);
      if (activeView !== "table-editor") {
        setActiveView("table-editor");
      }
    },
    [activeView, setSelectedTable],
  );

  const handleCellView = useCallback(
    (column: string, value: unknown, rowId?: string) => {
      setCellDetail({ column, columnType: typeMap.get(column), value, rowId });
    },
    [typeMap],
  );

  const handleCellEdit = useCallback(
    (tableName: string, column: string, value: string, rowId: string) => {
      setCellDetail({ column, columnType: typeMap.get(column), value, rowId });
    },
    [typeMap],
  );

  const handleRowView = useCallback((row: Record<string, unknown>) => {
    setRowDetail(row);
  }, []);

  const handleAddPendingEdit = useCallback(
    (column: string, newValue: string, rowId: string) => {
      if (!selectedTable) return;
      const sql = `UPDATE ${selectedTable.table_schema ?? "public"}.${selectedTable.table_name} SET ${column} = '${newValue.replace(/'/g, "''")}' WHERE id = '${rowId}';`;
      setPendingEdits((prev) => [
        ...prev.filter((e) => !(e.column === column && e.rowId === rowId)),
        {
          id: `${selectedTable.table_name}-${column}-${rowId}`,
          tableName: selectedTable.table_name,
          column,
          oldValue: "",
          newValue,
          rowId,
          sql,
        },
      ]);
      setCellDetail(null);
      toast.info("Edit queued", {
        description: "Execute from the bottom bar when ready",
      });
    },
    [selectedTable],
  );

  const handleExecuteEdits = useCallback(async () => {
    if (pendingEdits.length === 0 || !selectedClient) return;
    setExecutingEdits(true);
    try {
      const combined = pendingEdits.map((e) => e.sql).join("\n");
      await runDdl(ctx, combined, selectedClient);
      toast.success(`Executed ${pendingEdits.length} changes`);
      setPendingEdits([]);
      handleMutation();
    } catch (err) {
      const msg =
        err instanceof ApiError ? err.message : "Failed to execute changes";
      toast.error("Execution failed", { description: msg });
    } finally {
      setExecutingEdits(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pendingEdits, selectedClient, ctx]);

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (
        e.code === "KeyB" &&
        (e.ctrlKey || e.metaKey) &&
        !e.shiftKey &&
        !e.altKey
      ) {
        e.preventDefault();
        setPreferences({ sidebarOpen: !preferences.sidebarOpen });
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [preferences.sidebarOpen, setPreferences]);

  // Sync sidebar/inspector open state with panel collapse
  useEffect(() => {
    const sidebar = sidebarPanelRef.current;
    if (!sidebar) return;
    if (preferences.sidebarOpen) sidebar.expand();
    else sidebar.collapse();
  }, [preferences.sidebarOpen]);
  useEffect(() => {
    const inspector = inspectorPanelRef.current;
    if (!inspector) return;
    if (preferences.inspectorOpen) inspector.expand();
    else inspector.collapse();
  }, [preferences.inspectorOpen]);

  const setSidebarOpen = useCallback(
    (open: boolean) => setPreferences({ sidebarOpen: open }),
    [setPreferences],
  );
  const setInspectorOpen = useCallback(
    (open: boolean) => setPreferences({ inspectorOpen: open }),
    [setPreferences],
  );
  const setSidebarMaxWidth = useCallback(
    (pct: number) => setPreferences({ sidebarMaxWidth: pct }),
    [setPreferences],
  );
  const setInspectorMaxWidth = useCallback(
    (pct: number) => setPreferences({ inspectorMaxWidth: pct }),
    [setPreferences],
  );

  return (
    <div className="flex h-screen overflow-hidden bg-background text-foreground">
      <PanelGroup orientation="horizontal" className="flex-1">
        <Panel
          defaultSize={preferences.sidebarOpen ? 15 : 0}
          minSize={`200px`}
          maxSize={`${preferences.sidebarMaxWidth}%`}
          collapsible
          collapsedSize={0}
          id="sidebar"
          className="flex min-w-0"
          panelRef={sidebarPanelRef}
        >
          <div className="flex h-full w-full overflow-hidden">
            <Sidebar
              onCollapse={() => setSidebarOpen(false)}
              clients={clients}
              selectedClient={selectedClient}
              onClientChange={handleClientChange}
              tables={tables}
              selectedTable={selectedTable}
              onSelectTable={handleSelectTable}
              tablesLoading={tablesLoading}
              tablesError={tablesError}
              clientsLoading={clientsLoading}
              clientsError={clientsError}
              activeView={activeView}
              onViewChange={setActiveView}
              schemas={schemas}
              currentSchema={currentSchema}
              onSchemaChange={setCurrentSchema}
              onShowConnection={() => setShowConnection(true)}
            />
          </div>
        </Panel>

        {/* Show sidebar tab when collapsed */}
        {!preferences.sidebarOpen && (
          <button
            type="button"
            onClick={() => setSidebarOpen(true)}
            className="hidden md:flex shrink-0 w-6 items-center justify-center border-r border-border bg-sidebar text-muted-foreground hover:text-foreground hover:bg-sidebar/90 transition-colors"
            title="Show sidebar (Ctrl+B)"
          >
            <svg
              className="h-3.5 w-3.5 rotate-180"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={2}
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
              />
            </svg>
          </button>
        )}

        <PanelSeparator />

        <Panel defaultSize={65} minSize={30} id="main">
          <div className="flex flex-1 h-full min-h-0 min-w-0">
            {activeView === "table-editor" && !selectedTable && (
              <TableSelectPage
                clients={clients}
                selectedClient={selectedClient}
                onClientChange={handleClientChange}
                clientsLoading={clientsLoading}
                clientsError={clientsError}
                tables={tables}
                tablesLoading={tablesLoading}
                onSelectTable={handleSelectTable}
              />
            )}

            {activeView === "table-editor" && selectedTable && (
              <DataGrid
                table={selectedTable}
                columns={columns}
                clientName={selectedClient}
                refreshKey={dataRefreshKey}
                onMutation={handleMutation}
                onCellView={handleCellView}
                onCellEdit={handleCellEdit}
                onRowView={handleRowView}
              />
            )}

            {activeView === "sql-editor" && (
              <SqlEditor
                clientName={selectedClient}
                onMutation={handleMutation}
                tables={tables}
                allColumns={allColumns}
              />
            )}

            {activeView === "database" && (
              <DatabaseOverview
                clients={clients}
                selectedClient={selectedClient}
                tables={tables}
                onSelectTable={handleSelectTable}
                currentSchema={currentSchema}
                onCreateTable={() => setShowCreateTable(true)}
              />
            )}

            {activeView === "logs" && <LogsPage clientName={selectedClient} />}

            {activeView === "audit-log" && (
              <AuditLogPage clientName={selectedClient} />
            )}

            {activeView === "functions" && (
              <FunctionsPage
                clientName={selectedClient}
                currentSchema={currentSchema}
              />
            )}

            {activeView === "triggers" && (
              <TriggersPage
                clientName={selectedClient}
                currentSchema={currentSchema}
              />
            )}

            {activeView === "backups" && <BackupsPage />}

            {activeView === "replication" && <ReplicationPage />}

            {activeView === "client-statistics" && <ClientStatisticsPage />}

            {activeView === "auth" && <AuthPage clientName={selectedClient} />}

            {activeView === "auth-config" && (
              <AuthConfigPage clientName={selectedClient} />
            )}

            {activeView === "api-keys" && <ApiKeysPage />}

            {activeView === "data-api" && <DataApiPage />}

            {activeView === "observability" && <ObservabilityPage />}

            {activeView === "storage" && <StoragePage />}

            {activeView === "settings" && <SettingsPage />}

            {activeView === "cluster-health" && <ClusterHealth />}

            {activeView === "sdk-docs" && <SdkDocs />}

            {activeView === "modules" && <ModulesPage />}

            {activeView === "workspace" && <WorkspacePage />}

            {activeView === "pipelines" && (
              <PipelinesPage clientName={selectedClient} tables={tables} />
            )}
          </div>
        </Panel>

        {activeView === "table-editor" && (
          <>
            <PanelSeparator />
            <Panel
              defaultSize={preferences.inspectorOpen ? 20 : 0}
              minSize={`200px`}
              maxSize={`${preferences.inspectorMaxWidth}%`}
              collapsible
              collapsedSize={0}
              id="inspector"
              className="hidden lg:flex min-w-0"
              panelRef={inspectorPanelRef}
            >
              <div className="flex h-full w-full overflow-hidden">
                <SchemaInspector
                  table={selectedTable}
                  columns={columns}
                  columnsLoading={columnsLoading}
                  clientName={selectedClient}
                  onSchemaChange={handleSchemaChange}
                  onCollapse={() => setInspectorOpen(false)}
                />
              </div>
            </Panel>
            {!preferences.inspectorOpen && (
              <button
                type="button"
                onClick={() => setInspectorOpen(true)}
                className="hidden lg:flex shrink-0 w-6 items-center justify-center border-l border-border bg-muted/50 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
                title="Show schema inspector"
              >
                <svg
                  className="h-3.5 w-3.5"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
                  />
                </svg>
              </button>
            )}
          </>
        )}
      </PanelGroup>

      {cellDetail && selectedTable && (
        <CellDetailSheet
          open={!!cellDetail}
          onClose={() => setCellDetail(null)}
          columnName={cellDetail.column}
          columnType={cellDetail.columnType}
          value={cellDetail.value}
          tableName={selectedTable.table_name}
          rowId={cellDetail.rowId}
          onEdit={handleAddPendingEdit}
        />
      )}

      <RowDetailSheet
        open={!!rowDetail}
        onClose={() => setRowDetail(null)}
        row={rowDetail}
        columns={columns}
      />

      <TransactionIsland
        edits={pendingEdits}
        onExecute={handleExecuteEdits}
        onClear={() => setPendingEdits([])}
        onRemove={(id) =>
          setPendingEdits((prev) => prev.filter((e) => e.id !== id))
        }
        executing={executingEdits}
      />

      <ConnectionModal
        open={showConnection}
        onOpenChange={setShowConnection}
        clientName={selectedClient}
      />

      <CreateTableDialog
        open={showCreateTable}
        onOpenChange={setShowCreateTable}
        clientName={selectedClient}
        currentSchema={currentSchema}
        existingTableNames={tables
          .filter((t) => (t.table_schema ?? "public") === currentSchema)
          .map((t) => t.table_name)}
        onCreated={handleMutation}
      />

      {showDevLeva && (
        <DevLevaControls
          clients={clients}
          selectedClient={selectedClient}
          onSelectClient={handleClientChange}
          schemas={schemas}
          currentSchema={currentSchema}
          setCurrentSchema={setCurrentSchema}
          activeView={activeView}
          setActiveView={setActiveView}
          tables={tables}
          selectedTable={selectedTable}
          onSelectTable={handleSelectTable}
          sidebarOpen={preferences.sidebarOpen}
          inspectorOpen={preferences.inspectorOpen}
          setSidebarOpen={setSidebarOpen}
          setInspectorOpen={setInspectorOpen}
          sidebarMaxWidth={preferences.sidebarMaxWidth}
          inspectorMaxWidth={preferences.inspectorMaxWidth}
          setSidebarMaxWidth={setSidebarMaxWidth}
          setInspectorMaxWidth={setInspectorMaxWidth}
          flags={flags}
          setFlag={setFlag}
        />
      )}
    </div>
  );
}
