import { getWebhookUrl } from '@/lib/config'; export interface Event { id?: string | number; user_id?: number; name?: string; title?: string; // neuer Titel-Name vom Timeline-Endpoint description?: string; location?: string; url?: string; image?: string; manager_name?: string; manager_email?: string; guests?: any; begin_date?: string; // ISO date string (YYYY-MM-DD) end_date?: string; // ISO date string (YYYY-MM-DD) eventDate?: string; // ISO date string (YYYY-MM-DD) vom Timeline-Endpoint (camelCase) event_date?: string; // ISO date string (YYYY-MM-DD) direkt aus SQL-Query status?: 'PENDING' | 'ON_AIR'; // aggregierter Status für Timeline overall_status?: 'PENDING' | 'ON_AIR'; // Alias-Name aus SQL-Query creation_date?: number; last_update?: number; } // Payload-Struktur für den neuen Event-Endpunkt interface CreateEventPayload { title: string; description?: string; eventDate: string; // YYYY-MM-DD promotionStartDate?: string; // YYYY-MM-DD coverMediaUrl?: string; ticketUrl?: string; admissionTimes?: string; ticketPrice?: string; promotionSlots: Array<{ slotIndex: number; slotType: 'EVENT_MAIN' | 'ARTIST'; promoDate: string; // YYYY-MM-DD artistName?: string; artistInstagram?: string; }>; } export interface EventDetail extends CreateEventPayload { id: string | number; } export const createEvent = async (payload: CreateEventPayload): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/new`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); return result; } catch (error) { console.error('Error creating event manually:', error); throw error; } }; export interface ArtistCollabUpdateByOpPayload { eventId: string | number; slotId?: string | number; slotIndex?: number; artistDescription?: string; artistInstagram?: string; artistFacebook?: string; artistLinkedin?: string; artistTiktok?: string; artistYoutube?: string; } export const updateArtistCollabDataByOp = async ( payload: ArtistCollabUpdateByOpPayload ): Promise<{ success: boolean; message?: string }> => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/update_artist_data_byop`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const raw = await response.json(); const data = Array.isArray(raw) ? raw[0] ?? {} : raw ?? {}; return { success: data.success !== false, message: data.message, }; } catch (error) { console.error('Error updating artist collab data by op:', error); return { success: false, message: error instanceof Error ? error.message : 'Unknown error' }; } }; export const getEventInfoFromUrl = async (url: string): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/getinfofromurl`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ url }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error('Error getting event info from URL:', error); throw error; } }; export const fetchCurrentEvents = async (apiFetch: Function): Promise => { const webhookUrl = `${getWebhookUrl()}/events/get_current`; try { const response = await apiFetch(webhookUrl, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Failed to fetch events'); const raw = await response.json(); // n8n kann die Liste ggf. als String-JSON zurückgeben const data = typeof raw === 'string' ? (() => { try { return JSON.parse(raw); } catch { return raw; } })() : raw; return Array.isArray(data) ? data : data ? [data] : []; } catch (error) { console.error('Error fetching events:', error); throw error; } } export interface ArtistCollabUpdatePayload { token: string; slotId?: string | number; eventId?: string | number; artistDescription?: string; artistInstagram?: string; artistFacebook?: string; artistLinkedin?: string; artistTiktok?: string; artistYoutube?: string; } export const updateArtistCollabData = async ( payload: ArtistCollabUpdatePayload ): Promise<{ success: boolean; message?: string }> => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/update_artist_data`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const raw = await response.json(); const data = Array.isArray(raw) ? raw[0] ?? {} : raw ?? {}; return { success: data.success !== false, message: data.message, }; } catch (error) { console.error('Error updating artist collab data:', error); return { success: false, message: error instanceof Error ? error.message : 'Unknown error' }; } }; export const fetchEventById = async ( apiFetch: Function, id: string | number ): Promise => { const webhookUrl = `${getWebhookUrl()}/events/getbyid?id=${id}`; const response = await apiFetch(webhookUrl, { method: 'GET', headers: { 'Content-Type': 'application/json' }, }); if (!response.ok) throw new Error('Failed to fetch event'); const raw = await response.json(); // n8n kann entweder ein Objekt, ein Array mit einem Objekt // oder einen JSON-String zurückgeben – hier alles abfangen. const data = typeof raw === 'string' ? (() => { try { return JSON.parse(raw); } catch { return raw; } })() : raw; if (Array.isArray(data)) { return (data[0] || {}) as EventDetail; } return data as EventDetail; }; export const updateEvent = async ( id: string | number, payload: CreateEventPayload ): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/update`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id, ...payload }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); return result; } catch (error) { console.error('Error updating event:', error); throw error; } }; export const fetchEvents = async (apiFetch: Function): Promise => { const webhookUrl = `${getWebhookUrl()}/events`; try { const response = await apiFetch(webhookUrl, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Failed to fetch events'); const data = await response.json(); return Array.isArray(data) ? data : data ? [data] : []; } catch (error) { console.error('Error fetching events:', error); throw error; } } export const createEventFromUrl = async (url: string): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/event/new_fromurl`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ url, command: 'eventmodus_extract_from_url' }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data.message_from_ai || data; } catch (error) { console.error('Error creating event from URL:', error); throw error; } }; // Helper function to format dates to YYYY-MM-DD export const formatDateForInput = (dateString: string): string => { if (!dateString) return ''; const date = new Date(dateString); return date.toISOString().split('T')[0]; }; export interface CollabLinkResponse { token: string; url?: string; [key: string]: any; } export const generateCollabLink = async ( eventId: string | number, slotIndex: number, artistName?: string, artistInstagram?: string ): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/generate_collab_link`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ eventId, slotIndex, artistName, artistInstagram }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = (await response.json()) as CollabLinkResponse; return data; } catch (error) { console.error('Error generating collaboration link:', error); throw error; } }; export interface CollabMediaItem { id: string; url: string; type?: string; } export interface CollabInfo { eventTitle: string; promoDate?: string; artistName?: string; artistDescription?: string; artistMediaUrl?: string; artistInstagram?: string; slotId?: string | number; eventId?: string | number; media?: CollabMediaItem[]; } export const fetchArtistSlotByToken = async (token: string): Promise => { try { const { apiFetch } = await import('@/utils/apiFetch'); const response = await apiFetch(`${getWebhookUrl()}/events/slots/getartistsslot`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ token }), }); if (response.status === 401 || response.status === 403 || response.status === 404) { // Token ungültig, abgelaufen oder Slot nicht gefunden return null; } if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const raw = await response.json(); const data: any = (() => { if (!raw) return null; if (Array.isArray(raw)) return raw[0] ?? null; if (typeof raw === 'string') { try { const parsed = JSON.parse(raw); return Array.isArray(parsed) ? parsed[0] ?? null : parsed; } catch { return null; } } return raw as any; })(); if (!data) return null; return { eventTitle: data.eventTitle ?? data.event_title ?? data.title ?? '', promoDate: data.promoDate ?? data.promo_date, artistName: data.artistName ?? data.artist_name, artistDescription: data.artistDescription ?? data.artist_description, artistMediaUrl: data.artistMediaUrl ?? data.artist_media_url, artistInstagram: data.artistInstagram ?? data.artist_instagram, slotId: data.id ?? data.slot_id, eventId: data.event_id ?? data.eventId, media: Array.isArray(data.media) ? data.media.map((m: any) => ({ id: String(m.id), url: m.url || m.file_url, type: m.type || m.file_type, })) : [], }; } catch (error) { console.error('Error fetching artist slot by token:', error); throw error; } };