'use client';
import { useEffect, useRef, useState } from 'react';
import { Button } from '@fayegram-ai/faye-ui/controls/button';
import { TextField } from '@fayegram-ai/faye-ui/controls/text-field';
import { Checkbox } from '@fayegram-ai/faye-ui/controls/checkbox';
import { ControlLabel } from '@fayegram-ai/faye-ui/controls/field-layout';
import { Spinner } from '@fayegram-ai/faye-ui/feedback/loading';
import { Text } from '@fayegram-ai/faye-ui/core/text';
import { Stack, Inline } from '@fayegram-ai/faye-ui/layout/layout';
import { Section } from '../example';

// Local asynchronous fixture, not a backend or data engine. Ownership belongs to the app.
function delayed<T>(value: T, milliseconds: number, signal: AbortSignal): Promise<T> {
    return new Promise((resolve, reject) => {
        const abort = () => { clearTimeout(timer); reject(new DOMException('Cancelled', 'AbortError')); };
        const timer = setTimeout(() => { signal.removeEventListener('abort', abort); resolve(value); }, milliseconds);
        signal.addEventListener('abort', abort, { once: true });
        if (signal.aborted) abort();
    });
}
export default function AsyncWorkflows() {
    const [query, setQuery] = useState(''), [result, setResult] = useState(''), [searching, setSearching] = useState(false);
    const [draft, setDraft] = useState(''), [available, setAvailable] = useState(false), [pending, setPending] = useState(false);
    const [error, setError] = useState<string>(), [saved, setSaved] = useState(''), [attempts, setAttempts] = useState(0);
    const submission = useRef<AbortController | undefined>(undefined);
    useEffect(() => {
        const controller = new AbortController();
        if (!query.trim()) { setResult(''); setSearching(false); return () => controller.abort(); }
        setSearching(true);
        delayed(query, query === 'old' ? 350 : 40, controller.signal).then(value => {
            if (!controller.signal.aborted) { setResult(value); setSearching(false); }
        }).catch(() => {}); // This fixture's only rejection is owned cancellation.
        return () => controller.abort();
    }, [query]);
    useEffect(() => () => { submission.current?.abort(); submission.current = undefined; }, []);
    return <Section title="Asynchronous application ownership" note="Local delayed requests demonstrate cancellation, retry and draft retention. No server is contacted.">
        <Stack gap="4">
            <TextField label="Search example records" value={query} onChange={event => setQuery(event.target.value)}/>
            <Inline className="docs-async-status" role="status" aria-live="polite"><span className="docs-async-indicator">{searching && <Spinner size="sm" aria-hidden="true"/>}</span><span>{searching ? 'Searching…' : result ? `Latest result: ${result}` : 'Enter a search'}</span></Inline>
            <form data-testid="async-draft-form" onSubmit={async event => {
                event.preventDefault();
                if (submission.current) return; // Synchronous ownership also guards duplicate native submits.
                const controller = new AbortController(); submission.current = controller;
                const submitted = draft, canSave = available;
                setPending(true); setError(undefined); setAttempts(value => value + 1);
                try {
                    await delayed(undefined, 250, controller.signal);
                    if (controller.signal.aborted) return;
                    if (!canSave) throw new Error('Service unavailable. Your draft is retained; enable the local service and retry.');
                    setSaved(submitted);
                } catch (caught) {
                    if (!controller.signal.aborted) setError(caught instanceof Error ? caught.message : String(caught));
                } finally {
                    if (submission.current === controller) { submission.current = undefined; setPending(false); }
                }
            }}>
                <Stack gap="3">
                    <TextField label="Project draft" name="draft" required value={draft} error={error} onChange={event => setDraft(event.target.value)}/>
                    <ControlLabel label="Local service available">{attrs => <Checkbox.Root {...attrs} checked={available} onCheckedChange={setAvailable}><Checkbox.Indicator/></Checkbox.Root>}</ControlLabel>
                    <Inline><Button type="submit" pending={pending}>{error ? 'Retry save' : 'Save draft'}</Button></Inline>
                    <Text as="p" role="status" aria-live="polite" className="docs-async-status">{pending ? 'Saving…' : saved ? `Saved draft: ${saved}` : 'Draft not saved'}</Text>
                    <output aria-label="Save attempts">{attempts}</output>
                </Stack>
            </form>
        </Stack>
    </Section>;
}
