export interface WeddingConfig {
	siteUrl: string;
	weddingDate: string;
	ceremonyTime: string;
	rsvpByDate: string;
	venueName: string;
	venueAddress: string;
	rsvpPhone: string;
}

export type GuestType = 'adult' | 'child';

export interface Guest {
	name: string;
	type: GuestType;
}

export interface RsvpPayload {
	guests: Guest[];
	message?: string;
}

export interface PhotoUploadPayload {
	name: string;
	message?: string;
	email?: string;
	phone?: string;
	files: FileList;
}

export interface GuestListEntry {
	name: string;
	isChild: boolean;
}

export interface GuestList {
	guests: GuestListEntry[];
	total: number;
	adults: number;
	children: number;
}

export class ApiError extends Error {
	constructor(
		message: string,
		public status: number
	) {
		super(message);
	}
}

async function parseError(response: Response): Promise<string> {
	try {
		const body = await response.json();
		if (typeof body?.error === 'string') return body.error;
	} catch {
		// fall through to status text
	}
	return response.statusText || `Request failed (${response.status})`;
}

export async function fetchConfig(fetchImpl: typeof fetch = fetch): Promise<WeddingConfig> {
	const response = await fetchImpl('/api/config');
	if (!response.ok) throw new ApiError(await parseError(response), response.status);
	return response.json();
}

export async function submitRsvp(payload: RsvpPayload): Promise<void> {
	const response = await fetch('/api/rsvp', {
		method: 'POST',
		headers: { 'content-type': 'application/json' },
		body: JSON.stringify(payload)
	});
	if (!response.ok) throw new ApiError(await parseError(response), response.status);
}

export async function fetchGuests(fetchImpl: typeof fetch = fetch): Promise<GuestList> {
	const response = await fetchImpl('/api/guests');
	if (!response.ok) throw new ApiError(await parseError(response), response.status);
	return response.json();
}

export async function uploadPhotos(payload: PhotoUploadPayload): Promise<void> {
	const form = new FormData();
	form.set('name', payload.name);
	if (payload.message) form.set('message', payload.message);
	if (payload.email) form.set('email', payload.email);
	if (payload.phone) form.set('phone', payload.phone);
	for (const file of payload.files) form.append('files', file);

	const response = await fetch('/api/photos/upload', { method: 'POST', body: form });
	if (!response.ok) throw new ApiError(await parseError(response), response.status);
}
