'use client';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import type { CopyWeekInput, ScheduleSettingsInput, ShiftInput, ShiftUpdateInput } from '@alqove/api-client';
import { api } from '@/lib/api';
import { captureCommandGeneration, requireSelectedStore } from '@/lib/stores/store-context';

export const SCHEDULE_KEYS = {
  store: (storeId: string) => ['scheduling', storeId] as const,
  week: (storeId: string, week: string, own: boolean) => ['scheduling', storeId, 'week', own ? 'my' : 'team', week] as const,
  settings: (storeId: string) => ['scheduling', storeId, 'settings'] as const,
};
export function useScheduleWeek(storeId: string | null, week: string, own = false) {
  return useQuery({
    queryKey: SCHEDULE_KEYS.week(storeId ?? '', week, own),
    queryFn: () => own ? api.scheduling.myWeek(storeId!, week) : api.scheduling.week(storeId!, week),
    enabled: Boolean(storeId && week),
  });
}
export function useScheduleSettings(storeId: string | null) {
  return useQuery({ queryKey: SCHEDULE_KEYS.settings(storeId ?? ''), queryFn: () => api.scheduling.settings(storeId!), enabled: Boolean(storeId) });
}
export type ScheduleMutation =
  | { action: 'create'; input: ShiftInput }
  | { action: 'update'; id: string; input: ShiftUpdateInput }
  | { action: 'delete'; id: string; revision: string }
  | { action: 'publish'; week: string }
  | { action: 'settings'; input: ScheduleSettingsInput };
export function useScheduleMutation(storeId: string) {
  const qc = useQueryClient();
  const mutation = useMutation({
    mutationFn: async (command: ScheduleMutation & { generation: number }) => {
      requireSelectedStore(storeId, command.action === 'settings' ? 'settings.schedule' : command.action === 'publish' ? 'schedule.publish' : 'schedule.manage', command.generation);
      switch (command.action) {
        case 'create': return api.scheduling.createShift(storeId, command.input);
        case 'update': return api.scheduling.updateShift(storeId, command.id, command.input);
        case 'delete': return api.scheduling.deleteShift(storeId, command.id, command.revision);
        case 'publish': return api.scheduling.publish(storeId, command.week);
        case 'settings': return api.scheduling.updateSettings(storeId, command.input);
      }
    },
    // Refetch rather than merging local guesses into published or revisioned data.
    onSuccess: async (_data, command) => {
      const capability = command.action === 'settings' ? 'settings.schedule' : command.action === 'publish' ? 'schedule.publish' : 'schedule.manage';
      requireSelectedStore(storeId, capability, command.generation);
      await qc.invalidateQueries({ queryKey: SCHEDULE_KEYS.store(storeId) });
      requireSelectedStore(storeId, capability, command.generation);
    },
  });
  // Capture synchronously at command origin, BEFORE TanStack's async dispatch.
  // Same-store token replacement or switching away and back invalidates it too.
  return {
    ...mutation,
    mutate: (command: ScheduleMutation) => mutation.mutate({ ...command, generation: captureCommandGeneration() }),
    mutateAsync: (command: ScheduleMutation) => mutation.mutateAsync({ ...command, generation: captureCommandGeneration() }),
  };
}
export function useCopyWeek(storeId: string) {
  const qc = useQueryClient();
  const mutation = useMutation({
    mutationFn: ({ input, generation }: { input: CopyWeekInput; generation: number }) => {
      requireSelectedStore(storeId, 'schedule.manage', generation);
      return api.scheduling.copyWeek(storeId, input);
    },
    onSuccess: async (_data, { input, generation }) => {
      requireSelectedStore(storeId, 'schedule.manage', generation);
      if (!input.preview) await qc.invalidateQueries({ queryKey: SCHEDULE_KEYS.store(storeId) });
      requireSelectedStore(storeId, 'schedule.manage', generation);
    },
  });
  return {
    ...mutation,
    mutate: (input: CopyWeekInput) => mutation.mutate({ input, generation: captureCommandGeneration() }),
    mutateAsync: (input: CopyWeekInput) => mutation.mutateAsync({ input, generation: captureCommandGeneration() }),
  };
}
