'use client';

import type { Membership, StoreCapability } from '@alqove/api-client';
import { useAuthStore } from '@/stores/auth';

/** Discovery returns active memberships only. Persisted IDs never grant access. */
export function useSelectedMembership(): Membership | undefined {
  return useAuthStore((state) => state.user && !state.isLoading
    ? state.memberships?.find((membership) => membership.store_id === state.selectedStoreId)
    : undefined);
}

export function useSelectedStoreId(): string | null {
  return useSelectedMembership()?.store_id ?? null;
}

/** Capture at command origin (before timers, onMutate, uploads, or other awaits).
 * Keep this value in the command variables, NOT a ref refreshed on render.
 * Recheck after every await, before dispatch, and before visible success effects.
 */
export function captureCommandGeneration(): number {
  return useAuthStore.getState().commandGeneration;
}

export function isCommandCurrent(generation: number): boolean {
  const state = useAuthStore.getState();
  return generation === state.commandGeneration && !!state.user && !!state.token && !state.isLoading;
}

export function requireCommandGeneration(generation: number): void {
  if (!isCommandCurrent(generation)) throw new Error('Store access changed. Refresh and try again.');
}

/** Two-argument calls remain valid for synchronous dispatch. Async commands MUST
 * pass their originating generation as the third argument, not capture it here.
 */
export function requireSelectedStore(storeId: string | null, capability: StoreCapability = 'store.admin', generation?: number): string {
  if (generation !== undefined) requireCommandGeneration(generation);
  const state = useAuthStore.getState();
  const membership = state.memberships?.find((entry) => entry.store_id === storeId);
  if (!state.user || state.isLoading || !storeId || state.selectedStoreId !== storeId || !membership?.capabilities.includes(capability)) {
    throw new Error('Store access changed. Refresh and try again.');
  }
  return storeId;
}
