import { queryOptions, useMutation, useQueryClient } from '@tanstack/react-query' import { toast } from 'sonner' import { apiJSON, apiMutate } from '@/lib/api-client' import { overviewKeys } from '@/queries/overview' import type { ModulePatch, ModuleRow, ModulesResponse, Page, } from '@/types/api' export const modulesKeys = { all: ['modules'] as const, list: () => [...modulesKeys.all, 'list'] as const, detail: (id: string) => [...modulesKeys.all, 'detail', id] as const, domainEntries: (id: string) => [...modulesKeys.all, 'domain-entries', id] as const, asEntries: (id: string) => [...modulesKeys.all, 'as-entries', id] as const, cdnSources: (id: string) => [...modulesKeys.all, 'cdn-sources', id] as const, ipRangeEntries: (id: string) => [...modulesKeys.all, 'ip-range-entries', id] as const, } function invalidateModules(qc: ReturnType, id?: string) { void qc.invalidateQueries({ queryKey: modulesKeys.all }) void qc.invalidateQueries({ queryKey: overviewKeys.modules() }) if (id) { void qc.invalidateQueries({ queryKey: modulesKeys.detail(id) }) } } export function modulesListQueryOptions() { return queryOptions({ queryKey: modulesKeys.list(), queryFn: () => apiJSON('/v1/modules?limit=200'), }) } export function moduleDetailQueryOptions(id: string) { return queryOptions({ queryKey: modulesKeys.detail(id), queryFn: () => apiJSON(`/v1/modules/${id}`), }) } export type ModuleEntriesPage = Page> export function moduleEntriesQueryOptions(id: string, type: ModuleRow['type']) { const pathByType: Record = { DOMAINS: `/v1/modules/${id}/domain-entries?limit=500`, AS_PREFIXES: `/v1/modules/${id}/as-entries?limit=500`, CDN_CIDRS: `/v1/modules/${id}/cdn-sources?limit=500`, IP_RANGES: `/v1/modules/${id}/ip-range-entries?limit=500`, } const path = pathByType[type] const keyByType: Record = { DOMAINS: modulesKeys.domainEntries(id), AS_PREFIXES: modulesKeys.asEntries(id), CDN_CIDRS: modulesKeys.cdnSources(id), IP_RANGES: modulesKeys.ipRangeEntries(id), } return queryOptions({ queryKey: keyByType[type], queryFn: () => apiJSON(path), }) } export function useUpdateModuleMutation() { const qc = useQueryClient() return useMutation({ mutationFn: ({ id, body }: { id: string; body: ModulePatch }) => apiMutate(`/v1/modules/${id}`, 'PATCH', body, { idempotent: false }), onSuccess: (_data, vars) => { toast.success('Модуль обновлён') invalidateModules(qc, vars.id) }, onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось обновить модуль'), }) }