import { useCallback, useEffect, useState } from 'react';

const PROFILE_KEY = 'hostsTree.selectedProfile';
const EXPANDED_KEY = 'hostsTree.expandedKeys';

const safeGet = (key: string): string | null => {
  try {
    return localStorage.getItem(key);
  } catch {
    return null;
  }
};

const safeSet = (key: string, value: string) => {
  try {
    localStorage.setItem(key, value);
  } catch {
    // ignore quota/private-mode errors
  }
};

// Sentinel persisted when the user explicitly picks "Uncategorized" so the
// default-picker effect on page reload doesn't override it with the OS profile.
export const UNCATEGORIZED_SENTINEL = '__uncategorized__';

export const loadStoredProfileId = (): string | null => safeGet(PROFILE_KEY);

export const storeProfileId = (id: string | number | null) => {
  if (id === null) {
    safeSet(PROFILE_KEY, UNCATEGORIZED_SENTINEL);
    return;
  }
  safeSet(PROFILE_KEY, String(id));
};

export const clearStoredProfileId = () => {
  try {
    localStorage.removeItem(PROFILE_KEY);
  } catch {
    /* ignore */
  }
};

const readExpanded = (): Set<string> => {
  const raw = safeGet(EXPANDED_KEY);
  if (!raw) return new Set();
  try {
    const parsed = JSON.parse(raw);
    if (Array.isArray(parsed)) return new Set(parsed.filter((x): x is string => typeof x === 'string'));
  } catch {
    /* ignore */
  }
  return new Set();
};

const writeExpanded = (set: Set<string>) => {
  safeSet(EXPANDED_KEY, JSON.stringify([...set]));
};

export const useExpandedKeys = () => {
  const [expanded, setExpanded] = useState<Set<string>>(() => readExpanded());

  // Persist on every change
  useEffect(() => {
    writeExpanded(expanded);
  }, [expanded]);

  const isExpanded = useCallback((key: string) => expanded.has(key), [expanded]);

  const toggle = useCallback((key: string) => {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
  }, []);

  const setExpandedKey = useCallback((key: string, value: boolean) => {
    setExpanded(prev => {
      if (value === prev.has(key)) return prev;
      const next = new Set(prev);
      if (value) next.add(key);
      else next.delete(key);
      return next;
    });
  }, []);

  const expandAncestors = useCallback((keys: string[]) => {
    setExpanded(prev => {
      let changed = false;
      const next = new Set(prev);
      for (const k of keys) {
        if (!next.has(k)) {
          next.add(k);
          changed = true;
        }
      }
      return changed ? next : prev;
    });
  }, []);

  return { isExpanded, toggle, setExpandedKey, expandAncestors };
};
