import type { FC, ReactNode } from 'react';
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { useAuth } from './auth';

const LINKS_PREFIX = 'skeen-quicklinks:';
const MODE_PREFIX = 'skeen-quicklinks-mode:';

// Accesos iniciales sugeridos la primera vez (el usuario puede quitarlos)
const DEFAULT_LINKS = ['/agenda', '/pacientes', '/ventas'];

export type QuickLinksMode = 'menu' | 'right' | 'bottom';

export const QUICK_LINKS_MODE_LABELS: Record<QuickLinksMode, string> = {
  menu: 'En el menú lateral',
  right: 'Barra de iconos a la derecha',
  bottom: 'Barra de iconos abajo',
};

interface QuickLinksValue {
  links: string[];
  mode: QuickLinksMode;
  editing: boolean;
  setEditing: (v: boolean) => void;
  setMode: (m: QuickLinksMode) => void;
  toggle: (href: string) => void;
  remove: (href: string) => void;
  move: (href: string, dir: -1 | 1) => void;
  isPinned: (href: string) => boolean;
}

const QuickLinksContext = createContext<QuickLinksValue | null>(null);

const readJson = <T,>(key: string, fallback: T): T => {
  try {
    const raw = localStorage.getItem(key);
    if (raw === null) return fallback;
    return JSON.parse(raw) as T;
  } catch {
    return fallback;
  }
};

const writeJson = (key: string, value: unknown) => {
  try {
    localStorage.setItem(key, JSON.stringify(value));
  } catch {
    // localStorage lleno o no disponible: se mantiene solo en memoria
  }
};

const readLinks = (key: string): string[] => {
  const raw = typeof localStorage !== 'undefined' ? localStorage.getItem(key) : null;
  if (raw === null) {
    writeJson(key, DEFAULT_LINKS);
    return DEFAULT_LINKS;
  }
  const parsed = readJson<unknown>(key, []);
  return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === 'string') : [];
};

const readMode = (key: string): QuickLinksMode => {
  const m = readJson<string>(key, 'menu');
  return m === 'right' || m === 'bottom' || m === 'menu' ? m : 'menu';
};

/**
 * Accesos rápidos personalizables, persistidos en localStorage por usuario.
 * Compartido por SkeenLayout, HomeNestLayout y QuickLinksDock.
 */
export const QuickLinksProvider: FC<{ children: ReactNode }> = ({ children }) => {
  const { user } = useAuth();
  const linksKey = `${LINKS_PREFIX}${user?.id ?? 'anon'}`;
  const modeKey = `${MODE_PREFIX}${user?.id ?? 'anon'}`;

  const [links, setLinks] = useState<string[]>(() => readLinks(linksKey));
  const [mode, setModeState] = useState<QuickLinksMode>(() => readMode(modeKey));
  const [editing, setEditing] = useState(false);

  useEffect(() => {
    setLinks(readLinks(linksKey));
    setModeState(readMode(modeKey));
    setEditing(false);
  }, [linksKey, modeKey]);

  const persistLinks = useCallback(
    (updater: (prev: string[]) => string[]) => {
      setLinks((prev) => {
        const next = updater(prev);
        writeJson(linksKey, next);
        return next;
      });
    },
    [linksKey]
  );

  const setMode = useCallback(
    (m: QuickLinksMode) => {
      setModeState(m);
      writeJson(modeKey, m);
    },
    [modeKey]
  );

  const toggle = useCallback(
    (href: string) =>
      persistLinks((prev) => (prev.includes(href) ? prev.filter((l) => l !== href) : [...prev, href])),
    [persistLinks]
  );

  const remove = useCallback(
    (href: string) => persistLinks((prev) => prev.filter((l) => l !== href)),
    [persistLinks]
  );

  const move = useCallback(
    (href: string, dir: -1 | 1) =>
      persistLinks((prev) => {
        const i = prev.indexOf(href);
        const j = i + dir;
        if (i < 0 || j < 0 || j >= prev.length) return prev;
        const next = [...prev];
        [next[i], next[j]] = [next[j], next[i]];
        return next;
      }),
    [persistLinks]
  );

  const isPinned = useCallback((href: string) => links.includes(href), [links]);

  return (
    <QuickLinksContext.Provider
      value={{ links, mode, editing, setEditing, setMode, toggle, remove, move, isPinned }}
    >
      {children}
    </QuickLinksContext.Provider>
  );
};

export function useQuickLinks(): QuickLinksValue {
  const ctx = useContext(QuickLinksContext);
  if (!ctx) throw new Error('useQuickLinks debe usarse dentro de QuickLinksProvider');
  return ctx;
}
