import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react' import {Stack, Button, Inline} from '@sanity/ui' import {PatchEvent, set, unset} from 'sanity' import {SlugInput, type SlugInputProps} from 'sanity' import {useClient, useFormValue} from 'sanity' type PersonDoc = {name?: string} function slugify(input: string) { const folded = input .normalize('NFKD') .replace(/\p{M}+/gu, '') .replace(/ß/g, 'ss') .replace(/ø/g, 'o') .replace(/đ/g, 'd') .replace(/ł/g, 'l') return folded .toLowerCase() .trim() .replace(/[^\p{L}\p{N}]+/gu, '-') .replace(/(^-|-$)+/g, '') .slice(0, 96) } export function WorkSlugInput(props: SlugInputProps) { const client = useClient({apiVersion: '2026-01-01'}) const title = (useFormValue(['title']) as string) || '' const composerRef = (useFormValue(['composer', '_ref']) as string) || '' const arrangerRef = (useFormValue(['arranger', '_ref']) as string) || '' const [composerName, setComposerName] = useState('') const lastFetchedRef = useRef('') const [arrangerName, setArrangerName] = useState('') const lastFetchedArrangerRef = useRef('') const lastAutoSlugRef = useRef('') const desiredSource = useMemo(() => { const parts = [composerName, title, arrangerName ? `arr ${arrangerName}` : null].filter(Boolean) return parts.join(' ') }, [composerName, title, arrangerName]) const generateSlug = useCallback(() => { if (!desiredSource) return const nextSlug = slugify(desiredSource) lastAutoSlugRef.current = nextSlug props.onChange(PatchEvent.from(nextSlug ? set({_type: 'slug', current: nextSlug}) : unset())) }, [desiredSource, props.onChange]) useEffect(() => { let alive = true async function run() { if (!composerRef) { setComposerName('') lastFetchedRef.current = '' return } if (lastFetchedRef.current === composerRef) return lastFetchedRef.current = composerRef const doc = await client.fetch(`*[_type == "composer" && _id == $id][0]{name}`, { id: composerRef, }) if (!alive) return setComposerName(doc?.name || '') } run() return () => { alive = false } }, [composerRef, client]) useEffect(() => { let alive = true async function run() { if (!arrangerRef) { setArrangerName('') lastFetchedArrangerRef.current = '' return } if (lastFetchedArrangerRef.current === arrangerRef) return lastFetchedArrangerRef.current = arrangerRef const doc = await client.fetch(`*[_type == "composer" && _id == $id][0]{name}`, { id: arrangerRef, }) if (!alive) return setArrangerName(doc?.name || '') } run() return () => { alive = false } }, [arrangerRef, client]) useEffect(() => { if (!composerName || !title) return const current = props.value?.current || '' const nextSlug = slugify(desiredSource) if (!lastAutoSlugRef.current && current && current === nextSlug) { lastAutoSlugRef.current = current return } if (!current || current === lastAutoSlugRef.current) { lastAutoSlugRef.current = nextSlug props.onChange(PatchEvent.from(set({_type: 'slug', current: nextSlug}))) } }, [composerName, arrangerName, title, desiredSource, props.value?.current, props.onChange]) return (