"use client";

import { useMemo, useCallback, useState } from "react";
import type { ColumnDef, ColumnPreferences, ViewKey } from "@capakraken/shared";
import { trpc } from "~/lib/trpc/client.js";

// Simple localStorage helper (no external lib needed)
function readLocalVisible(view: ViewKey): string[] | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = localStorage.getItem(`colvis_${view}`);
    return raw ? (JSON.parse(raw) as string[]) : null;
  } catch {
    return null;
  }
}

function writeLocalVisible(view: ViewKey, keys: string[]) {
  if (typeof window === "undefined") return;
  localStorage.setItem(`colvis_${view}`, JSON.stringify(keys));
}

export function useColumnConfig(
  view: ViewKey,
  builtinColumns: ColumnDef[],
  customColumns: ColumnDef[] = [],
) {
  const allColumns = useMemo(
    () => [...builtinColumns, ...customColumns],
    [builtinColumns, customColumns],
  );

  // Local optimistic state — immediately reflects user toggles without waiting for server
  const [localVisible, setLocalVisible] = useState<string[] | null>(
    () => readLocalVisible(view),
  );

  const { data: serverPrefs } = trpc.user.getColumnPreferences.useQuery(undefined, {
    staleTime: 300_000,
    placeholderData: (prev) => prev,
  });
  const setMutation = trpc.user.setColumnPreferences.useMutation();

  const visibleKeys = useMemo(() => {
    const alwaysVisible = allColumns.filter((c) => !c.hideable).map((c) => c.key);
    // Local state (optimistic) → server prefs → defaults
    const saved =
      localVisible ??
      (serverPrefs as ColumnPreferences | undefined)?.[view]?.visible ??
      null;
    if (saved) {
      const valid = saved.filter((k) => allColumns.some((c) => c.key === k));
      return [...new Set([...alwaysVisible, ...valid])];
    }
    return allColumns.filter((c) => c.defaultVisible).map((c) => c.key);
  }, [localVisible, serverPrefs, allColumns, view]);

  const visibleColumns = useMemo(
    () =>
      allColumns
        .filter((c) => visibleKeys.includes(c.key))
        .sort((a, b) => visibleKeys.indexOf(a.key) - visibleKeys.indexOf(b.key)),
    [allColumns, visibleKeys],
  );

  const setVisible = useCallback(
    (keys: string[]) => {
      setLocalVisible(keys);          // immediate re-render
      writeLocalVisible(view, keys);  // persist for next page load
      setMutation.mutate({ view, visible: keys }); // sync to server
    },
    [view, setMutation],
  );

  return { allColumns, visibleColumns, visibleKeys, setVisible };
}
