import { useEffect, useState } from 'react';
import { parseEvents } from './domain';
import type { CommunityEvent } from './domain';

export type LoadState =
  | { status: 'loading' }
  | { status: 'error'; message: string }
  | { status: 'success'; events: CommunityEvent[] };

export async function loadEvents(url: string, signal: AbortSignal): Promise<CommunityEvent[]> {
  const response = await fetch(url, { signal });
  if (!response.ok) throw new Error(`Could not load events (HTTP ${response.status}).`);
  const value: unknown = await response.json();
  return parseEvents(value);
}

export function useEvents(url: string, attempt = 0): LoadState {
  const [state, setState] = useState<LoadState>({ status: 'loading' });
  useEffect(() => {
    const controller = new AbortController();
    let active = true;
    setState({ status: 'loading' });
    loadEvents(url, controller.signal).then(
      events => { if (active) setState({ status: 'success', events }); },
      (error: unknown) => {
        if (active) setState({ status: 'error', message: error instanceof Error ? error.message : 'Loading failed.' });
      },
    );
    return () => { active = false; controller.abort(); };
  }, [url, attempt]);
  return state;
}

// Every runnable entry is two directories below the project/build root.
// Resolving against the document preserves hosting under a subdirectory.
export function fixtureUrl(file = 'events.json'): string {
  return new URL(`../../fixtures/${file}`, window.location.href).href;
}
