import { apiFetch, type ApiSettings } from "@govoplan/core-webui"; export type SchedulingStatus = "draft" | "collecting" | "closed" | "decided" | "handed_off" | "cancelled" | "archived"; export type SchedulingCandidateSlot = { id: string; poll_option_id?: string | null; label: string; description?: string | null; start_at: string; end_at: string; timezone: string; location?: string | null; position: number; freebusy_checked_at?: string | null; freebusy_status?: string | null; freebusy_conflicts: Record[]; tentative_hold_event_id?: string | null; metadata?: Record; }; export type SchedulingParticipant = { id: string; respondent_id?: string | null; display_name?: string | null; email?: string | null; participant_type: string; required: boolean; status: string; poll_invitation_id?: string | null; invitation_token?: string | null; last_invited_at?: string | null; responded_at?: string | null; metadata?: Record; }; export type SchedulingRequest = { id: string; tenant_id: string; title: string; description?: string | null; location?: string | null; timezone: string; status: SchedulingStatus; poll_id?: string | null; selected_slot_id?: string | null; organizer_user_id?: string | null; deadline_at?: string | null; allow_external_participants: boolean; allow_participant_updates: boolean; result_visibility: string; calendar_integration_enabled: boolean; calendar_id?: string | null; calendar_freebusy_enabled: boolean; calendar_hold_enabled: boolean; create_calendar_event_on_decision: boolean; calendar_event_id?: string | null; handed_off_at?: string | null; cancelled_at?: string | null; created_at: string; updated_at: string; metadata?: Record; slots: SchedulingCandidateSlot[]; participants: SchedulingParticipant[]; }; export type SchedulingRequestListResponse = { requests: SchedulingRequest[] }; export type SchedulingStatusResponse = { request: SchedulingRequest }; export type SchedulingCandidateSlotPayload = { label?: string | null; description?: string | null; start_at: string; end_at: string; timezone?: string | null; location?: string | null; metadata?: Record; }; export type SchedulingParticipantPayload = { respondent_id?: string | null; display_name?: string | null; email?: string | null; participant_type?: "internal" | "external" | "resource"; required?: boolean; metadata?: Record; }; export type SchedulingRequestCreatePayload = { title: string; description?: string | null; location?: string | null; timezone?: string; status?: "draft" | "collecting"; deadline_at?: string | null; allow_external_participants?: boolean; allow_participant_updates?: boolean; result_visibility?: "organizer" | "after_response" | "after_close" | "public"; calendar?: { enabled?: boolean; calendar_id?: string | null; freebusy_enabled?: boolean; tentative_holds_enabled?: boolean; create_event_on_decision?: boolean; }; slots: SchedulingCandidateSlotPayload[]; participants?: SchedulingParticipantPayload[]; create_participant_invitations?: boolean; metadata?: Record; }; export type SchedulingDecisionPayload = { slot_id?: string | null; poll_option_id?: string | null; handoff_to_calendar?: boolean | null; }; export type SchedulingAvailabilityValue = "available" | "maybe" | "unavailable"; export type SchedulingAvailabilityPayload = { answers: Array<{ slot_id: string; value: SchedulingAvailabilityValue; }>; }; export type SchedulingCalendarActionResponse = { request: SchedulingRequest; created_event_ids: string[]; updated_slot_ids: string[]; warnings: string[]; }; export type SchedulingNotification = { id: string; request_id: string; participant_id?: string | null; event_kind: string; channel: string; recipient?: string | null; status: string; payload: Record; error?: string | null; sent_at?: string | null; created_at: string; updated_at: string; metadata?: Record; }; export type SchedulingNotificationListResponse = { notifications: SchedulingNotification[] }; export type SchedulingPollOptionResult = { option_id: string; option_key: string; label: string; count: number; score: number; values: Record; }; export type SchedulingSummaryResponse = { request: SchedulingRequest; poll_summary: { poll_id: string; kind: string; status: string; response_count: number; option_results: SchedulingPollOptionResult[]; leading_option_ids: string[]; }; }; export type SchedulingAddressLookupCandidate = { contact_id: string; address_book_id: string; display_name: string; email?: string | null; email_label?: string | null; organization?: string | null; role_title?: string | null; tags: string[]; source_kind: string; source_ref?: string | null; source_revision?: string | null; provenance: Record; }; export type SchedulingAddressLookupResponse = { available: boolean; candidates: SchedulingAddressLookupCandidate[]; }; const json = (payload: unknown) => ({ method: "POST", body: JSON.stringify(payload ?? {}) }); export function lookupSchedulingAddresses(settings: ApiSettings, query: string, limit = 25): Promise { const params = new URLSearchParams({ query, limit: String(limit) }); return apiFetch(settings, `/api/v1/scheduling/address-lookup?${params.toString()}`); } export function listSchedulingRequests(settings: ApiSettings, status?: string): Promise { const query = status ? `?status=${encodeURIComponent(status)}` : ""; return apiFetch(settings, `/api/v1/scheduling/requests${query}`); } export function createSchedulingRequest(settings: ApiSettings, payload: SchedulingRequestCreatePayload): Promise { return apiFetch(settings, "/api/v1/scheduling/requests", json(payload)); } export function submitSchedulingAvailability( settings: ApiSettings, requestId: string, payload: SchedulingAvailabilityPayload ): Promise { return apiFetch( settings, `/api/v1/scheduling/requests/${requestId}/responses`, json(payload) ); } export function openSchedulingRequest(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/open`, json({})); } export function closeSchedulingRequest(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/close`, json({})); } export function decideSchedulingRequest(settings: ApiSettings, requestId: string, payload: SchedulingDecisionPayload): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/decide`, json(payload)); } export function evaluateSchedulingFreeBusy(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/calendar/freebusy`, json({})); } export function createSchedulingHolds(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/calendar/holds`, json({})); } export function createSchedulingCalendarEvent(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/calendar/event`, json({})); } export function schedulingSummary(settings: ApiSettings, requestId: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/summary`); } export function createSchedulingNotifications(settings: ApiSettings, requestId: string, eventKind: string): Promise { return apiFetch(settings, `/api/v1/scheduling/requests/${requestId}/notifications`, json({ event_kind: eventKind })); } export function listSchedulingNotifications(settings: ApiSettings, requestId?: string): Promise { const query = requestId ? `?request_id=${encodeURIComponent(requestId)}` : ""; return apiFetch(settings, `/api/v1/scheduling/notifications${query}`); }