import { apiGet, isApiError, apiPost, apiPut } from '@/lib/api' import type { Material, MaterialIndexResponse, MaterialVersion, FetchMaterialsParams, MaterialFilter, MaterialSyncSuppression, MaterialSidebarTag, MaterialTagTree } from '@/types' export type FetchMaterialTreeParams = { parentId?: number | null materialFilter: MaterialFilter } export type MaterialSyncSuppressionResponse = { suppressions: MaterialSyncSuppression[] } export type MaterialChangesResponse = { versions: MaterialVersion[] count: number } const MATERIAL_FILTERS: MaterialFilter[] = ['present', 'missing', 'any'] export const parseMaterialFilter = ( value: unknown, fallback: MaterialFilter = 'present', ): MaterialFilter => typeof value === 'string' && MATERIAL_FILTERS.includes (value as MaterialFilter) ? value as MaterialFilter : fallback export const fetchMaterials = async ( { q, tagState, mediaKind, createdFrom, createdTo, updatedFrom, updatedTo, sort, direction, page, tagId, includeDescendants, groupBy, limit }: FetchMaterialsParams, ): Promise => await apiGet ('/materials', { params: { ...(q && { q }), tag_state: tagState, media_kind: mediaKind, ...(tagId != null && { tag_id: tagId }), ...(includeDescendants && { include_descendants: '1' }), ...(groupBy !== 'none' && { group_by: groupBy }), ...(createdFrom && { created_from: createdFrom }), ...(createdTo && { created_to: createdTo }), ...(updatedFrom && { updated_from: updatedFrom }), ...(updatedTo && { updated_to: updatedTo }), sort, direction, page, limit} }) export const fetchMaterial = async (id: string): Promise => { try { return await apiGet (`/materials/${ id }`) } catch (error) { if (isApiError (error) && error.response?.status === 404) return null throw error } } export const fetchMaterialChanges = async ( { materialId, tag, eventType, page, limit }: { materialId?: string tag?: string eventType?: string page: number limit: number }): Promise => await apiGet ('/materials/versions', { params: { ...(materialId && { material_id: materialId }), ...(tag && { tag }), ...(eventType && { event_type: eventType }), page, limit} }) export const fetchMaterialTagTree = async ( { parentId, materialFilter }: FetchMaterialTreeParams): Promise => await apiGet ('/tags/with-depth', { params: { ...(parentId != null && { parent: String (parentId) }), material_filter: materialFilter} }) export const fetchMaterialTagByName = async ( name: string, materialFilter: MaterialFilter): Promise => { try { return await apiGet (`/tags/name/${ encodeURIComponent (name) }/materials`, { params: { material_filter: materialFilter } }) } catch (error) { if (isApiError (error) && error.response?.status === 404) return null throw error } } export const createMaterial = async (formData: FormData): Promise => await apiPost ('/materials', formData) export const updateMaterial = async ( id: string, formData: FormData): Promise => await apiPut (`/materials/${ id }`, formData) export const fetchMaterialSyncSuppressions = async (): Promise => await apiGet ('/materials/suppressions') export const createMaterialSyncSuppression = async ( payload: { sourceKind: string sourceUri?: string drivePath?: string driveFileId?: string reason: string }): Promise => await apiPost ('/materials/suppressions', { source_kind: payload.sourceKind, source_uri: payload.sourceUri, drive_path: payload.drivePath, drive_file_id: payload.driveFileId, reason: payload.reason})