'use client';

import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
import { useSearchParams } from 'next/navigation';
import type { HermesInstanceFilter } from './hermes';

// Persisted across navigation so the switcher choice sticks. Bumping the key
// resets the stored value (use this if we ever change the allowed filter
// values incompatibly).
const STORAGE_KEY = 'hermes.instanceFilter.v1';
const DEFAULT_FILTER: HermesInstanceFilter = 'all';

const VALID_FILTERS: HermesInstanceFilter[] = ['all', 'vijay', 'bheem'];

function readPersisted(): HermesInstanceFilter {
  if (typeof window === 'undefined') return DEFAULT_FILTER;
  try {
    const raw = window.localStorage.getItem(STORAGE_KEY);
    if (raw && (VALID_FILTERS as string[]).includes(raw)) {
      return raw as HermesInstanceFilter;
    }
  } catch {
    // localStorage may be unavailable (private mode / SSR). Fall through to default.
  }
  return DEFAULT_FILTER;
}

interface HermesInstanceContextValue {
  selectedInstance: HermesInstanceFilter;
  setSelectedInstance: (next: HermesInstanceFilter) => void;
}

const HermesInstanceContext = createContext<HermesInstanceContextValue | null>(null);

export function HermesInstanceProvider({ children }: { children: ReactNode }) {
  // Always start with the default on the server so the SSR + first client render
  // agree (avoids hydration mismatch). After mount we read the persisted value.
  const [selectedInstance, setSelectedInstanceState] = useState<HermesInstanceFilter>(DEFAULT_FILTER);

  // Deep-link hydration: `?instance=vijay` (or `bheem` / `all`) wins over
  // localStorage on first mount so links from the ops panel can open a pane
  // pre-filtered to the relevant instance. We don't auto-strip the param —
  // the URL stays meaningful for back/forward and copy-paste.
  const searchParams = useSearchParams();

  useEffect(() => {
    const fromUrl = searchParams?.get('instance');
    if (fromUrl && (VALID_FILTERS as string[]).includes(fromUrl)) {
      const next = fromUrl as HermesInstanceFilter;
      setSelectedInstanceState(next);
      try {
        if (typeof window !== 'undefined') window.localStorage.setItem(STORAGE_KEY, next);
      } catch {
        // ignore
      }
      return;
    }
    setSelectedInstanceState(readPersisted());
    // We deliberately depend on the search params object so navigations that
    // change `?instance=` re-apply.
  }, [searchParams]);

  const setSelectedInstance = useCallback((next: HermesInstanceFilter) => {
    setSelectedInstanceState(next);
    if (typeof window !== 'undefined') {
      try {
        window.localStorage.setItem(STORAGE_KEY, next);
      } catch {
        // Best-effort persistence; ignore failures.
      }
    }
  }, []);

  const value = useMemo(
    () => ({ selectedInstance, setSelectedInstance }),
    [selectedInstance, setSelectedInstance],
  );

  return <HermesInstanceContext.Provider value={value}>{children}</HermesInstanceContext.Provider>;
}

export function useHermesInstance(): HermesInstanceContextValue {
  const ctx = useContext(HermesInstanceContext);
  if (!ctx) {
    // Allow components to render outside the provider (e.g. ad-hoc usage in
    // storybook/tests) by falling back to the default — never crash the tree.
    return { selectedInstance: DEFAULT_FILTER, setSelectedInstance: () => {} };
  }
  return ctx;
}
