import { useEffect, useMemo, useRef, useState } from "react";
import type { KeyboardEvent as ReactKeyboardEvent } from "react";
import { createPortal } from "react-dom";
import {
  DndContext,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragOverlay,
} from "@dnd-kit/core";
import {
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { motion } from "framer-motion";
import { Search, Plus, BarChart3, Save, FolderOpen, Trash2, Pencil, X, Pill, ChevronRight } from "lucide-react";
import { DayPicker } from "react-day-picker";
import "react-day-picker/dist/style.css";
import type { GraphDataset } from "../../types/medical";
import { ChartComponent } from "./ChartComponent";
import { searchDatasetsByName } from "./searchDatasets";
import { formatDateRange } from "../../utils/helpers";
import { normalizeSearchText } from "../../utils/text.ts";
import {
  buildDatasetsFromTests,
  buildDatasetsFromDeviceReadings,
  buildDatasetsFromPrescriptions,
  datasetHasOutOfReferencePoint,
  isDateWithinRange,
  parseDateOption,
  resolveDatasetsForTest,
  type ParsedTestQuery,
  type TimeframePreset,
} from "./graphHelpers.ts";
import { useGraphActions } from "./useGraphActions.ts";
import { useGraphPresets } from "./useGraphPresets.ts";
import { useGraphSearch, type SearchResultItem } from "./useGraphSearch.ts";
import { useGraphDateFilter } from "./useGraphDateFilter.ts";
import { useGraphSessionStorage } from "./useGraphSessionStorage.ts";
import type { APIGraphCreationContext, APITest } from "../../services/medical";
import { fetchDeviceReadings, fetchPrescriptions, fetchTests } from "../../services/medical";
import { METRIC_CONFIG, type APIDeviceReading, type MetricId } from "../../devices/types";
import { useAuthStore } from "../../store/useAuthStore";
import { usePractitionerStore } from "../../practitioner/store/usePractitionerStore";

interface GraphItem {
  id: string; // Unique instance ID
  datasets: GraphDataset[];
  creation: APIGraphCreationContext;
  normalizeByReference?: boolean;
}

const TIMEFRAME_PRESET_LABELS: Record<Exclude<TimeframePreset, "custom">, string> = {
  all: "All",
  "1m": "Last 1 Month",
  "3m": "Last 3 Months",
  "6m": "Last 6 Months",
  "12m": "Last 12 Months",
};

const GRAPH_SESSION_STORAGE_KEY = "hipograf.graph-area.graphs.v1";
const DEVICE_HISTORY_START_DATE = "2000-01-01";

const toLocalYmd = (date: Date): string => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
};

const fetchWearableReadings = async (): Promise<Partial<Record<MetricId, APIDeviceReading[]>>> => {
  const endDate = toLocalYmd(new Date());
  const entries = await Promise.all(
    (Object.keys(METRIC_CONFIG) as MetricId[]).map(async (metric) => [
      metric,
      await fetchDeviceReadings(metric, DEVICE_HISTORY_START_DATE, endDate),
    ] as const)
  );

  return Object.fromEntries(entries) as Partial<Record<MetricId, APIDeviceReading[]>>;
};

// Sortable Item Wrapper
function SortableGraph({
  id,
  item,
  onRemove,
  onMoveUp,
  onMoveDown,
  onSplit,
  onSplitDataset,
  onNormalizeChange,
  onDatasetColorChange,
  onDatasetStyleChange,
}: {
  id: string;
  item: GraphItem;
  onRemove: () => void;
  onMoveUp: () => void;
  onMoveDown: () => void;
  onSplit: () => void;
  onSplitDataset: (datasetId: string) => void;
  onNormalizeChange: (enabled: boolean) => void;
  onDatasetColorChange: (datasetId: string, color: string) => void;
  onDatasetStyleChange: (
    datasetId: string,
    styleUpdate: Partial<Pick<GraphDataset, "lineStyle" | "pointStyle">>
  ) => void;
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    zIndex: isDragging ? 999 : undefined,
  };

  return (
    <motion.div layout transition={{ type: "spring", stiffness: 350, damping: 30 }} ref={setNodeRef} style={style} className="mb-8 relative hover:z-20">
       <ChartComponent 
          id={item.id} 
          datasets={item.datasets} 
          onRemove={onRemove}
          onMoveUp={onMoveUp}
          onMoveDown={onMoveDown}
          onSplit={onSplit}
          onSplitDataset={onSplitDataset}
          normalizeByReference={item.normalizeByReference ?? false}
          onNormalizeByReferenceChange={onNormalizeChange}
          onDatasetColorChange={onDatasetColorChange}
          onDatasetStyleChange={onDatasetStyleChange}
          isDragging={isDragging}
          dragAttributes={attributes}
          dragListeners={listeners}
       />
    </motion.div>
  );
}

export function GraphArea({ initialSelectedMetric }: { initialSelectedMetric?: string | null }) {
  const [graphs, setGraphs] = useState<GraphItem[]>([]);
  const [allTests, setAllTests] = useState<APITest[]>([]);
  const [allDatasets, setAllDatasets] = useState<GraphDataset[]>([]);
  const [dateOptions, setDateOptions] = useState<string[]>([]);
  const [isLoadingDatasets, setIsLoadingDatasets] = useState(false);
  const [datasetLoadError, setDatasetLoadError] = useState<string | null>(null);
  const hasAppliedInitialMetric = useRef(false);
  const user = useAuthStore(s => s.user);
  const viewingPatientId = usePractitionerStore((s) => s.viewingPatientId);
  const activePatientId = viewingPatientId || user?._id;
  const graphSessionKey = useMemo(
    () => (activePatientId ? `${GRAPH_SESSION_STORAGE_KEY}:${activePatientId}` : null),
    [activePatientId]
  );

  useGraphSessionStorage(graphSessionKey, graphs, setGraphs);

  const {
    dateFilterMode,
    selectedPreset,
    sliderStartDate,
    sliderEndDate,
    appliedDateRange,
    dateRangeError,
    clearDateRange,
    applyTimeframePreset,
    customRange,
    handleCustomRangeChange,
    dataDates,
    today,
    visibleMonth,
    setVisibleMonth,
  } = useGraphDateFilter({ dateOptions });

  const availableDatasets = useMemo(() => {
    return allDatasets
      .map((dataset) => ({
        ...dataset,
        data: dataset.data.filter((point) => isDateWithinRange(point.date, appliedDateRange)),
      }))
      .filter((dataset) => dataset.data.length > 0);
  }, [allDatasets, appliedDateRange]);

  const availableTests = useMemo(() => {
    return allTests.filter((test) =>
      availableDatasets.some((dataset) => dataset.sourceTestIds?.includes(test._id))
    );
  }, [allTests, availableDatasets]);

  const testEntryDates = useMemo(() => {
    return allDatasets
      .filter((dataset) => dataset.type !== "medication")
      .flatMap((dataset) => dataset.data.map((point) => parseDateOption(point.date)));
  }, [allDatasets]);

  const medicationEntryDates = useMemo(() => {
    return allDatasets
      .filter((dataset) => dataset.type === "medication")
      .flatMap((dataset) => dataset.data.map((point) => parseDateOption(point.date)));
  }, [allDatasets]);

  const {
    storedPresets,
    selectedPresetId,
    setSelectedPresetId,
    isLoadingPresets,
    presetActionError,
    isSavingPreset,
    isPresetModalOpen,
    presetModalMode,
    presetNameDraft,
    setPresetNameDraft,
    createPresetInBackend,
    saveSelectedPreset,
    renameSelectedPreset,
    requestDeleteSelectedPreset,
    submitPresetModal,
    closePresetModal,
    loadSelectedPreset,
  } = useGraphPresets({
    userId: activePatientId,
    graphs,
    setGraphs,
    availableDatasets,
  });

  const {
    searchQuery,
    setSearchQuery,
    showResults,
    setShowResults,
    activeSearchResultIndex,
    searchInputRef,
    parsedQueryResult,
    isParsingQuery,
    parseQueryError,
    searchResultItems,
    handleSearchInputKeyDown: handleSearchInputKeyDownBase,
    formatParsedQueryRange,
  } = useGraphSearch({
    userId: activePatientId,
    availableTests,
    availableDatasets,
    dateRange: appliedDateRange,
  });

  const {
    activeId,
    customCollisionDetection,
    handleDragStart,
    handleDragEnd,
    addGraphFromDatasets,
    addGraph,
    removeGraph,
    clearAllGraphs,
    moveGraphUp,
    moveGraphDown,
    updateDatasetColor,
    updateDatasetStyle,
    updateGraphNormalization,
    splitGraph,
    splitDatasetFromGraph,
  } = useGraphActions({
    setGraphs,
    availableDatasets,
    dateOptions,
    dateFilterMode,
    selectedPreset,
    appliedDateRange,
    sliderStartDate,
    sliderEndDate,
    searchQuery,
    setSearchQuery,
    setShowResults,
  });

  useEffect(() => {
    if (!activePatientId) return;

    setIsLoadingDatasets(true);
    setDatasetLoadError(null);

    Promise.allSettled([fetchTests(activePatientId), fetchPrescriptions(activePatientId), fetchWearableReadings()]).then(([testsResult, prescriptionsResult, wearableResult]) => {
      const tests = testsResult.status === "fulfilled" ? testsResult.value : [];
      const prescriptions = prescriptionsResult.status === "fulfilled" ? prescriptionsResult.value : [];
      const wearableReadings = wearableResult.status === "fulfilled" ? wearableResult.value : {};

      setAllTests(tests);

      const testDatasets = buildDatasetsFromTests(tests);
      const medicationDatasets = buildDatasetsFromPrescriptions(prescriptions);
      const wearableDatasets = buildDatasetsFromDeviceReadings(wearableReadings);

      setAllDatasets([...testDatasets, ...medicationDatasets, ...wearableDatasets]);

      const uniqueDates = Array.from(
        new Set([
          ...testDatasets.flatMap((dataset) => dataset.data.map((point) => point.date)),
          ...medicationDatasets.flatMap((dataset) => dataset.data.map((point) => point.date)),
          ...wearableDatasets.flatMap((dataset) => dataset.data.map((point) => point.date)),
        ])
      ).sort((a, b) => new Date(a).getTime() - new Date(b).getTime());

      setDateOptions(uniqueDates);

      const rejectedCount = [testsResult, prescriptionsResult, wearableResult].filter(
        (result) => result.status === "rejected"
      ).length;

      if (rejectedCount === 3) {
        setDatasetLoadError("Unable to load graph data for this date range");
      } else if (rejectedCount > 0) {
        setDatasetLoadError("Some graph data could not be loaded");
      }

      setIsLoadingDatasets(false);
    });
  }, [activePatientId]);

  // Sensors - use simple PointerSensor
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 5,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const filterDatasetToDateRange = (dataset: GraphDataset, query: ParsedTestQuery): GraphDataset => {
    const startDate = query.start?.trim();
    const endDate = query.end?.trim();

    if (!startDate && !endDate) {
      return dataset;
    }

    return {
      ...dataset,
      data: dataset.data.filter((point) =>
        isDateWithinRange(point.date, { startDate, endDate })
      ),
    };
  };

  const resolveDatasetForQuery = (
    query: ParsedTestQuery,
    sourceTests: APITest[],
    sourceDatasets: GraphDataset[]
  ): GraphDataset | null => {
    const parameter = query.test_parameter.trim();
    if (!parameter) return null;

    const matchingTest = sourceTests.find((test) => {
      const normalizedParameter = normalizeSearchText(parameter);
      return normalizeSearchText(test.name) === normalizedParameter || normalizeSearchText(test.testId) === normalizedParameter;
    });

    if (matchingTest) {
      const testDatasets = resolveDatasetsForTest(sourceDatasets, matchingTest._id);
      return testDatasets[0] ? filterDatasetToDateRange(testDatasets[0], query) : null;
    }

    const testId = query.test_id;
    const candidateDatasets = testId
      ? sourceDatasets.filter((dataset) => dataset.sourceTestIds?.includes(testId))
      : sourceDatasets;

    const normalizedParameter = normalizeSearchText(parameter);
    const exactMatch = candidateDatasets.find((dataset) => normalizeSearchText(dataset.name) === normalizedParameter);
    if (exactMatch) {
      return filterDatasetToDateRange(exactMatch, query);
    }

    const [bestMatch] = searchDatasetsByName(candidateDatasets, parameter);
    return bestMatch ? filterDatasetToDateRange(bestMatch, query) : null;
  };



  const handleParsedSearchResultClick = (result: SearchResultItem & { kind: "parsed" }) => {
    const datasetsToAdd = result.queries.flatMap((query) => {
      const parameter = query.test_parameter.trim();
      if (!parameter) return [];

      const normalizedParameter = normalizeSearchText(parameter);
      const matchingTest = allTests.find(
        (test) => normalizeSearchText(test.name) === normalizedParameter || normalizeSearchText(test.testId) === normalizedParameter
      );

      if (matchingTest) {
        return resolveDatasetsForTest(allDatasets, matchingTest._id).map((dataset) => filterDatasetToDateRange(dataset, query));
      }

      const matchedDataset = resolveDatasetForQuery(query, allTests, allDatasets);
      return matchedDataset ? [matchedDataset] : [];
    });

    const uniqueDatasets = datasetsToAdd.filter(
      (dataset, index, datasets) => datasets.findIndex((candidate) => candidate.id === dataset.id) === index
    );

    const filteredDatasets = parsedQueryResult?.outOfReferenceOnly
      ? uniqueDatasets.filter((dataset) => datasetHasOutOfReferencePoint(dataset))
      : uniqueDatasets;

    if (filteredDatasets.length === 0) {
      setShowResults(false);
      return;
    }

    addGraphFromDatasets(filteredDatasets, result.subtitle);
  };

  const activateSearchResult = (item: SearchResultItem) => {
    if (item.kind === "parsed") {
      handleParsedSearchResultClick(item);
      return;
    }

    if (item.kind === "test") {
      addGraphFromDatasets(item.datasets, item.title);
      return;
    }

    addGraph(item.dataset.id);
  };

  const handleSearchInputKeyDown = (event: ReactKeyboardEvent<HTMLInputElement>) => {
    handleSearchInputKeyDownBase(event);

    if (event.defaultPrevented || event.key !== "Enter") return;

    if (activeSearchResultIndex === null) return;
    const activeItem = searchResultItems[activeSearchResultIndex];
    if (!activeItem) return;

    event.preventDefault();
    activateSearchResult(activeItem);
  };

  useEffect(() => {
    if (hasAppliedInitialMetric.current) return;

    const metric = initialSelectedMetric?.trim();
    if (!metric) {
      hasAppliedInitialMetric.current = true;
      return;
    }

    if (availableDatasets.length === 0) return;

    const exactMatch =
      availableDatasets.find((dataset) => dataset.name === metric) ??
      availableDatasets.find((dataset) => dataset.id === metric) ??
      null;

    if (exactMatch) {
      hasAppliedInitialMetric.current = true;
      addGraph(exactMatch.id);
      return;
    }

    const normalizedMetric = normalizeSearchText(metric);
    const matchedDataset =
      availableDatasets.find((dataset) => normalizeSearchText(dataset.name) === normalizedMetric) ??
      searchDatasetsByName(availableDatasets, metric)[0] ??
      null;

    hasAppliedInitialMetric.current = true;
    if (matchedDataset) {
      addGraph(matchedDataset.id);
    }
  }, [addGraph, availableDatasets, initialSelectedMetric]);

  return (
    <div className="w-full space-y-8 pb-20 xl:grid xl:grid-cols-[minmax(0,1fr)_360px] xl:gap-8 xl:space-y-0 xl:items-start">
      <div className="w-full rounded-3xl border border-slate-200/80 bg-gradient-to-br from-white to-slate-50 p-4 shadow-sm xl:col-start-2 xl:row-start-2 xl:sticky xl:top-6">
        <div className="flex flex-col gap-1">
          <div>

          {isPresetModalOpen && presetModalMode && typeof document !== "undefined" && createPortal(
            <>
              <div
                className="fixed inset-0 z-[200] bg-slate-900/50 backdrop-blur-sm"
                onClick={closePresetModal}
              />
              <div className="fixed left-1/2 top-1/2 z-[210] w-[min(92vw,32rem)] -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-slate-100 bg-white shadow-2xl">
                <div className="flex items-start justify-between border-b border-slate-100 p-5">
                  <div>
                    <h3 className="text-lg font-semibold text-slate-900">
                      {presetModalMode === "create"
                        ? "Create preset"
                        : presetModalMode === "rename"
                          ? "Rename preset"
                          : "Delete preset"}
                    </h3>
                    <p className="mt-0.5 text-sm text-slate-500">
                      {presetModalMode === "create"
                        ? "Give this preset a name before saving it."
                        : presetModalMode === "rename"
                          ? "Update the name of the selected preset."
                          : "This will permanently remove the selected preset."}
                    </p>
                  </div>
                  <button
                    type="button"
                    onClick={closePresetModal}
                    className="rounded-lg p-2 text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-600"
                  >
                    <X size={18} />
                  </button>
                </div>

                <div className="p-5">
                  {presetModalMode === "delete" ? (
                    <div className="rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
                      Are you sure you want to delete <span className="font-semibold">{presetNameDraft || "this preset"}</span>? This action cannot be undone.
                    </div>
                  ) : (
                    <>
                      <label className="block text-xs font-semibold uppercase tracking-wide text-slate-500">
                        Preset name
                      </label>
                      <input
                        type="text"
                        value={presetNameDraft}
                        onChange={(e) => setPresetNameDraft(e.target.value)}
                        autoFocus
                        className="mt-2 h-11 w-full rounded-xl border border-slate-200 bg-white px-3 text-sm text-slate-800 shadow-sm outline-none transition focus:border-blue-300 focus:ring-2 focus:ring-blue-100"
                        placeholder="Enter preset name"
                      />
                    </>
                  )}

                  <div className="mt-5 flex items-center justify-end gap-3">
                    <button
                      type="button"
                      onClick={closePresetModal}
                      disabled={isSavingPreset}
                      className="inline-flex h-11 items-center justify-center rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
                    >
                      Cancel
                    </button>
                    <button
                      type="button"
                      onClick={submitPresetModal}
                      disabled={isSavingPreset}
                      className={`inline-flex h-11 items-center justify-center rounded-xl px-4 text-sm font-semibold text-white shadow-sm transition disabled:cursor-not-allowed disabled:opacity-50 ${
                        presetModalMode === "delete"
                          ? "bg-rose-600 hover:bg-rose-700"
                          : "bg-slate-900 hover:bg-slate-800"
                      }`}
                    >
                      {isSavingPreset
                        ? presetModalMode === "delete"
                          ? "Deleting..."
                          : "Saving..."
                        : presetModalMode === "create"
                          ? "Create"
                          : presetModalMode === "rename"
                            ? "Rename"
                            : "Delete"}
                    </button>
                  </div>
                </div>
              </div>
            </>,
            document.body
          )}
          </div>

          <div className="flex flex-col gap-4">
            <div className="relative z-30 rounded-2xl border border-slate-200 bg-white p-3 shadow-sm transition-all hover:shadow-md focus-within:border-blue-300 focus-within:ring-2 focus-within:ring-blue-100">
              <div className="relative group">
                <div className="absolute inset-y-0 left-0 flex items-center pl-5 pointer-events-none">
                  <Search className="h-5 w-5 text-slate-400 group-focus-within:text-blue-600 transition-colors" />
                </div>
                <input
                  type="text"
                  className="block h-14 w-full rounded-2xl border border-slate-200 bg-white pl-14 pr-4 text-xs font-medium text-slate-800 outline-none placeholder:text-slate-300 focus:border-blue-300 focus:ring-2 focus:ring-blue-100"
                  placeholder="Search health metrics or medications..."
                  value={searchQuery}
                  onChange={(e) => {
                    setSearchQuery(e.target.value);
                    setShowResults(true);
                  }}
                  onFocus={() => setShowResults(true)}
                  onKeyDown={handleSearchInputKeyDown}
                  ref={searchInputRef}
                />
              </div>

              {showResults && (
                <div className="mt-3 max-h-80 overflow-y-auto rounded-3xl border border-slate-100 bg-white shadow-[0_18px_40px_-24px_rgba(15,23,42,0.45)] ring-1 ring-slate-200/70 divide-y divide-slate-100">
                  {isParsingQuery && (
                    <div className="bg-slate-50 px-4 py-3 text-xs text-slate-500">
                      Parsing query...
                    </div>
                  )}

                  {!isParsingQuery && parseQueryError && (
                    <div className="bg-rose-50 px-4 py-3 text-xs text-rose-600">
                      {parseQueryError}
                    </div>
                  )}

                  {searchResultItems.length > 0 ? (
                    searchResultItems.map((item, index) => {
                      const isHighlighted = activeSearchResultIndex === index;

                      return (
                      <button
                        key={item.id}
                        onClick={() => {
                          if (item.kind === "parsed") {
                            handleParsedSearchResultClick(item);
                            return;
                          }

                          if (item.kind === "test") {
                            addGraphFromDatasets(item.datasets, item.title);
                            return;
                          }

                          addGraph(item.dataset.id);
                        }}
                        tabIndex={-1}
                        className={
                          item.kind === "parsed"
                            ? `hp-search-result relative w-full overflow-hidden border border-transparent appearance-none px-4 py-4 text-left text-xs transition-colors duration-200 hover:bg-blue-50/95 active:bg-blue-50/95 focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 active:outline-none active:ring-0 active:ring-offset-0 flex items-center justify-between gap-4 group first:mt-0 ${
                                isHighlighted
                                  ? "bg-blue-50/95"
                                  : "bg-gradient-to-r from-blue-50/90 via-white to-blue-50/50"
                              }`
                            : `hp-search-result relative w-full overflow-hidden border border-transparent appearance-none px-4 py-4 text-left text-xs transition-colors duration-200 hover:bg-slate-50/80 active:bg-slate-50/80 focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 active:outline-none active:ring-0 active:ring-offset-0 flex items-center justify-between gap-4 group first:mt-0 ${
                                isHighlighted ? "bg-slate-50/80" : ""
                              }`
                        }
                      >
                        <span
                          aria-hidden="true"
                          className={
                            item.kind === "parsed"
                              ? `pointer-events-none absolute inset-0 transition-colors duration-200 ${
                                  isHighlighted ? "bg-blue-100/70" : "bg-blue-100/0 group-hover:bg-blue-100/70"
                                }`
                              : `pointer-events-none absolute inset-0 transition-colors duration-200 ${
                                  isHighlighted ? "bg-slate-100/70" : "bg-slate-100/0 group-hover:bg-slate-100/70"
                                }`
                          }
                        />
                        {item.kind === "parsed" ? (
                          <div className="relative z-10 flex w-full flex-col gap-3 text-left">
                            <div className="flex items-start justify-between gap-3">
                              <div className="flex items-center gap-3 min-w-0">
                                <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-2xl bg-blue-100 text-blue-600 shadow-inner transition-colors group-hover:bg-blue-200">
                                  <Search size={16} />
                                </div>
                                <div className="min-w-0">
                                  <span className="block text-xs font-semibold text-blue-950">{item.title}</span>
                                </div>
                              </div>
                              <div className="rounded-full bg-white px-3 py-1 text-[11px] font-semibold text-blue-700 shadow-sm ring-1 ring-blue-100 transition-all group-hover:bg-blue-600 group-hover:text-white group-hover:ring-blue-600">
                                {item.queries.length > 0 ? `${item.queries.length} test${item.queries.length === 1 ? "" : "s"}` : "No match"}
                              </div>
                            </div>

                            <div className="space-y-2 rounded-2xl bg-white/90 p-3 ring-1 ring-blue-100/80">
                              <div className="text-[10px] font-semibold uppercase tracking-[0.18em] text-blue-500">
                                Filtered time range
                              </div>
                              <div className="space-y-1 text-xs text-slate-600">
                                {item.queries.map((query, queryIndex) => (
                                  <div key={`${query.test_parameter}-${query.start}-${query.end}-${queryIndex}`} className="flex flex-wrap items-center gap-x-2 gap-y-1">
                                    <span className="text-xs font-semibold text-slate-700">{query.test_parameter || "Test"}</span>
                                    <span className="text-slate-300">•</span>
                                    <span className="text-xs text-slate-500">{formatParsedQueryRange(query)}</span>
                                  </div>
                                ))}
                              </div>
                            </div>
                          </div>
                        ) : item.kind === "test" ? (
                          <div className="relative z-10 flex w-full flex-col gap-3 text-left">
                            <div className="flex items-center gap-3 min-w-0">
                              <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-2xl bg-emerald-100 text-emerald-600 shadow-inner transition-colors group-hover:bg-emerald-200">
                                <BarChart3 size={16} />
                              </div>
                              <span className="block text-xs font-semibold text-emerald-950">{item.title}</span>
                            </div>

                            {item.test.subtests.length > 0 && (
                              <div className="space-y-1.5 rounded-2xl bg-emerald-50/30 p-2.5 ring-1 ring-emerald-100/50">
                                <div className="text-[9px] font-bold uppercase tracking-[0.2em] text-emerald-600/80">
                                  Available Subtests
                                </div>
                                <div className="text-[11px] font-medium text-slate-600 leading-relaxed">
                                  {item.test.subtests.map((subtest) => subtest.name).join(", ")}
                                </div>
                              </div>
                            )}
                          </div>
                        ) : (
                          <div className="relative z-10 flex min-w-0 items-center gap-3">
                            <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-2xl bg-slate-100 text-slate-500 shadow-inner transition-colors group-hover:bg-white group-hover:text-blue-500">
                              <BarChart3 size={16} />
                            </div>
                            <div className="min-w-0 gap-2 flex flex-col">
                              <span className="block text-xs font-semibold text-slate-700">{item.dataset.name}</span>
                              {item.dataset.type === "medication" ? (
                                <span className="flex items-center gap-1 text-[9px] font-semibold uppercase tracking-[0.18em] text-emerald-500">
                                  <Pill size={12} />
                                  {item.dataset.data.length > 0 ? formatDateRange(item.dataset.data[0].date, item.dataset.data[item.dataset.data.length - 1].date) : "No dates"}
                                </span>
                              ) : item.dataset.id.startsWith("wearable-") ? (
                                <span className="text-[10px] font-semibold uppercase tracking-[0.18em] text-cyan-500">Wearable • {item.dataset.unit}</span>
                              ) : (
                                <span className="text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-400">{item.dataset.type} • {item.dataset.unit}</span>
                              )}
                            </div>
                          </div>
                        )}
                        {item.kind === "parsed" ? null : (
                          <div className="relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-slate-50 text-slate-300 ring-1 ring-slate-200 transition-all group-hover:bg-blue-500 group-hover:text-white group-hover:ring-blue-500 group-hover:translate-x-0.5">
                            <ChevronRight className="h-4 w-4" />
                          </div>
                        )}
                      </button>
                      );
                    })
                  ) : (
                    <div className="flex flex-col items-center gap-2 px-6 py-8 text-center text-xs text-slate-400">
                      <Search className="h-8 w-8 opacity-20" />
                      <span>The search did not yield any results</span>
                    </div>
                  )}
                </div>
              )}

              {showResults && (
                <div className="fixed inset-0 z-[-1]" onClick={() => setShowResults(false)} />
              )}
            </div>

            <div className="rounded-2xl border border-slate-200 bg-white/90 p-4 shadow-sm overflow-hidden">
              <div className="mb-3 flex items-center justify-between gap-4">
                <div>
                  <label className="block text-xs font-semibold uppercase tracking-wide text-slate-500">
                    Filter Date Range
                  </label>
                </div>
                <button
                  type="button"
                  onClick={clearDateRange}
                  className="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-xs font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50"
                >
                  Clear
                </button>
              </div>

              <div className="mb-3 flex flex-wrap gap-2">
                {(Object.keys(TIMEFRAME_PRESET_LABELS) as Array<Exclude<TimeframePreset, "custom">>).map((preset) => (
                  <button
                    key={preset}
                    type="button"
                    disabled={dateOptions.length === 0}
                    onClick={() => applyTimeframePreset(preset)}
                    className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
                      dateFilterMode === "preset" && selectedPreset === preset
                        ? "bg-blue-600 text-white shadow-sm"
                        : "border border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50"
                    }`}
                  >
                    {TIMEFRAME_PRESET_LABELS[preset]}
                  </button>
                ))}
              </div>

              <div
                className="rounded-xl border border-slate-200 bg-white p-3"
              >
                <DayPicker
                  mode="range"
                  selected={customRange}
                  onSelect={handleCustomRangeChange}
                  month={visibleMonth}
                  onMonthChange={setVisibleMonth}
                  disabled={{ after: today }}
                  captionLayout="dropdown"
                  startMonth={dataDates[0]}
                  endMonth={today}
                  navLayout="around"
                  modifiers={{ hasTestEntry: testEntryDates, hasMedicationEntry: medicationEntryDates }}
                  modifiersClassNames={{
                    hasTestEntry: "hp-day-has-test-entry",
                    hasMedicationEntry: "hp-day-has-medication-entry",
                  }}
                  className="hp-day-picker"
                  showOutsideDays
                  numberOfMonths={1}
                />
                <p className="mt-2 text-[11px] text-slate-500">
                  Blue dots indicate test entries. Green dots indicate days with actively prescribed medications.
                </p>
              </div>

              <div className="mt-3 min-h-[18px] text-center">
                {dateRangeError && (
                  <p className="text-xs font-medium text-rose-500">{dateRangeError}</p>
                )}
                {!dateRangeError && datasetLoadError && (
                  <p className="text-xs font-medium text-rose-500">{datasetLoadError}</p>
                )}
                {isLoadingDatasets && (
                  <p className="text-xs font-medium text-slate-500">Loading plot data...</p>
                )}
              </div>
            </div>

            <div className="rounded-2xl border border-slate-200/80 bg-white/90 p-4 shadow-sm backdrop-blur">
              <div className="flex flex-col gap-4">
                <div>
                  <label className="block text-xs font-semibold uppercase tracking-wide text-slate-500">
                    Saved Presets
                  </label>
                  <p className="mt-1 text-sm text-slate-500">
                    Load, save, or delete plot layouts for this patient.
                  </p>
                </div>

                {storedPresets.length === 0 && !isLoadingPresets && (
                  <div className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500">
                    No saved presets yet. Create one after you build a plot.
                  </div>
                )}

                <div className="grid gap-2 sm:grid-cols-2">
                  <select
                    value={selectedPresetId}
                    onChange={(e) => setSelectedPresetId(e.target.value)}
                    className="h-11 w-full rounded-xl border border-slate-200 bg-white px-3 text-sm text-slate-700 shadow-sm transition focus:border-blue-300 focus:outline-none focus:ring-2 focus:ring-blue-100 disabled:cursor-not-allowed disabled:bg-slate-50 sm:col-span-2"
                    disabled={isLoadingPresets || storedPresets.length === 0}
                  >
                    <option value="">
                      {storedPresets.length === 0 ? "No saved presets available" : "Select a saved preset"}
                    </option>
                    {storedPresets.map((preset) => (
                      <option key={preset._id} value={preset._id}>
                        {preset.name}
                      </option>
                    ))}
                  </select>

                  <button
                    type="button"
                    onClick={loadSelectedPreset}
                    disabled={!selectedPresetId || isLoadingPresets}
                    className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
                  >
                    <FolderOpen size={16} />
                    Load
                  </button>

                  <button
                    type="button"
                    onClick={createPresetInBackend}
                    disabled={graphs.length === 0 || isSavingPreset}
                    className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
                  >
                    <Plus size={16} />
                    Create
                  </button>

                  <button
                    type="button"
                    onClick={saveSelectedPreset}
                    disabled={!selectedPresetId || graphs.length === 0 || isSavingPreset}
                    className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
                  >
                    <Save size={16} />
                    Save
                  </button>

                  <button
                    type="button"
                    onClick={renameSelectedPreset}
                    disabled={!selectedPresetId || isSavingPreset}
                    className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 shadow-sm transition hover:border-slate-300 hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
                  >
                    <Pencil size={16} />
                    Rename
                  </button>

                  <button
                    type="button"
                    onClick={requestDeleteSelectedPreset}
                    disabled={!selectedPresetId || isSavingPreset}
                    className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-xl border border-rose-200 bg-white px-4 text-sm font-semibold text-rose-700 shadow-sm transition hover:border-rose-300 hover:bg-rose-50 disabled:cursor-not-allowed disabled:opacity-50 sm:col-span-2"
                  >
                    <Trash2 size={16} />
                    Delete
                  </button>
                </div>
              </div>

              {presetActionError && (
                <div className="mt-4 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">
                  {presetActionError}
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* Graphs Grid */}
      <DndContext
        sensors={sensors}
        collisionDetection={customCollisionDetection}
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
      >
        <div className="w-full min-h-[400px] xl:col-start-1 xl:row-start-2">
          <div className="mb-4 flex items-center justify-between gap-3">
            <div>
              <h2 className="text-sm font-semibold uppercase tracking-wide text-slate-500">
                Plots
              </h2>
            </div>
            <button
              type="button"
              onClick={clearAllGraphs}
              disabled={graphs.length === 0}
              className="inline-flex h-11 items-center justify-center gap-2 rounded-xl border border-rose-200 bg-white px-4 text-sm font-semibold text-rose-700 shadow-sm transition hover:border-rose-300 hover:bg-rose-50 disabled:cursor-not-allowed disabled:opacity-50"
            >
              <Trash2 size={16} />
              Clear
            </button>
          </div>
          <SortableContext
            items={graphs.map(g => g.id)}
            strategy={verticalListSortingStrategy}
          >
            {graphs.length === 0 && (
              <div className="flex flex-col items-center justify-center py-24 border-2 border-dashed border-slate-200 rounded-3xl bg-slate-50/50">
                <div className="w-16 h-16 bg-white rounded-2xl flex items-center justify-center shadow-sm mb-4">
                  <BarChart3 className="text-slate-300 w-8 h-8" />
                </div>
              </div>
             )}
             {graphs.map((graph) => (
               <SortableGraph 
                  key={graph.id} 
                  id={graph.id} 
                  item={graph} 
                  onRemove={() => removeGraph(graph.id)}
                  onMoveUp={() => moveGraphUp(graph.id)}
                  onMoveDown={() => moveGraphDown(graph.id)}
                  onSplit={() => splitGraph(graph.id)}
                onSplitDataset={(datasetId) => splitDatasetFromGraph(graph.id, datasetId)}
                onNormalizeChange={(enabled) => updateGraphNormalization(graph.id, enabled)}
                  onDatasetColorChange={(datasetId, color) => updateDatasetColor(graph.id, datasetId, color)}
                  onDatasetStyleChange={(datasetId, styleUpdate) => updateDatasetStyle(graph.id, datasetId, styleUpdate)}
               />
             ))}
          </SortableContext>
        </div>

        {/* Drag Overlay */}
        <DragOverlay>
           {activeId ? (
              <div className="opacity-90 scale-105 rotate-1 w-[min(92vw,760px)] bg-white rounded-2xl shadow-2xl border border-slate-200 p-4">
                {(() => {
                  const item = graphs.find((g) => g.id === activeId);
                  if (!item) return null;

                  return (
                    <>
                      <div className="flex flex-wrap items-center gap-2">
                        {item.datasets.map((ds) => (
                          <div key={ds.id} className="flex items-center gap-1.5 px-2 py-1 bg-slate-50 rounded-md border border-slate-100">
                            <span className="w-2.5 h-2.5 rounded-full" style={{ backgroundColor: ds.color }} />
                            <span className="text-sm font-semibold text-slate-700 whitespace-nowrap">{ds.name}</span>
                          </div>
                        ))}
                      </div>
                      <div className="mt-3 h-24 rounded-xl border border-dashed border-slate-200 bg-slate-50 flex items-center justify-center text-sm text-slate-500">
                        Dragging chart preview
                      </div>
                    </>
                  );
                })()}
              </div>
           ) : null}
        </DragOverlay>
      </DndContext>
    </div>
  );
}
