import type { ApiSettings, CampaignListItem } from "../types"; import { apiFetch } from "./client"; export type CampaignListResponse = | CampaignListItem[] | { campaigns?: CampaignListItem[]; items?: CampaignListItem[]; results?: CampaignListItem[]; }; export type CampaignUpdatePayload = { external_id?: string | null; name?: string | null; status?: string | null; description?: string | null; }; export type CampaignCreateMinimalPayload = { external_id?: string; name?: string; description?: string | null; current_flow?: string; current_step?: string; }; export type CampaignCreateResponse = { campaign: CampaignListItem & { current_version_id?: string | null; }; version: CampaignVersionListItem; }; export type CampaignVersionListItem = { id: string; campaign_id: string; version_number: number; schema_version?: string; source_filename?: string | null; source_base_path?: string | null; workflow_state?: string; current_flow?: string; current_step?: string | null; is_complete?: boolean; editor_state?: Record; autosaved_at?: string | null; published_at?: string | null; locked_at?: string | null; locked_by_user_id?: string | null; created_at?: string; updated_at?: string; validation_summary?: Record | null; build_summary?: Record | null; }; export type CampaignVersionDetail = CampaignVersionListItem & { raw_json: Record; campaign_json?: Record; }; export type CampaignVersionUpdatePayload = { campaign_json?: Record | null; current_flow?: string | null; current_step?: string | null; workflow_state?: string | null; is_complete?: boolean | null; editor_state?: Record | null; source_filename?: string | null; source_base_path?: string | null; }; export type CampaignPartialValidationPayload = { campaign_json?: Record | null; section?: string | null; }; export type CampaignPartialValidationResponse = { ok: boolean; section?: string | null; error_count: number; warning_count: number; info_count: number; issues: Record[]; }; export type CampaignSummary = { generated_at?: string; campaign?: CampaignListItem; current_version?: { id: string; version_number?: number; schema_version?: string; source_filename?: string | null; created_at?: string | null; validation_summary?: Record | null; build_summary?: Record | null; } | null; cards?: { jobs_total?: number; queueable?: number; needs_attention?: number; sent?: number; failed?: number; imap_appended?: number; imap_failed?: number; }; status_counts?: Record>; issues?: Record; attachments?: Record; attempts?: Record; delivery?: Record; recent_failures?: Record[]; }; export type CampaignQueuePayload = { version_id?: string | null; include_warnings?: boolean; enqueue_celery?: boolean; dry_run?: boolean; }; export type CampaignSendNowPayload = { version_id?: string | null; include_warnings?: boolean; check_files?: boolean; validate_before_send?: boolean; build_before_send?: boolean; dry_run?: boolean; use_rate_limit?: boolean; enqueue_imap_task?: boolean; }; export async function listCampaigns(settings: ApiSettings): Promise { const response = await apiFetch(settings, "/api/v1/campaigns"); if (Array.isArray(response)) { return response; } return response.campaigns ?? response.items ?? response.results ?? []; } export async function getCampaign(settings: ApiSettings, campaignId: string): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}`); } export async function updateCampaignMetadata( settings: ApiSettings, campaignId: string, payload: CampaignUpdatePayload ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}`, { method: "PUT", body: JSON.stringify(payload) }); } export async function createNewCampaign( settings: ApiSettings, overrides: CampaignCreateMinimalPayload = {} ): Promise { const now = new Date(); const stamp = now.toISOString().slice(0, 19).replace(/[-:T]/g, ""); const payload = { external_id: overrides.external_id ?? `new-campaign-${stamp}`, name: overrides.name ?? "New Campaign", description: overrides.description ?? "", current_flow: overrides.current_flow ?? "create", current_step: overrides.current_step ?? "basics" }; return apiFetch(settings, "/api/v1/campaigns/new", { method: "POST", body: JSON.stringify(payload) }); } export async function getCampaignSchema(settings: ApiSettings): Promise { return apiFetch(settings, "/api/v1/schemas/campaign"); } export async function listCampaignVersions( settings: ApiSettings, campaignId: string ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions`); } export async function getCampaignVersion( settings: ApiSettings, campaignId: string, versionId: string ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}`); } export async function unlockCampaignVersionValidation( settings: ApiSettings, campaignId: string, versionId: string ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/unlock-validation`, { method: "POST" }); } export async function updateCampaignVersion( settings: ApiSettings, campaignId: string, versionId: string, payload: CampaignVersionUpdatePayload ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}`, { method: "PUT", body: JSON.stringify(payload) }); } export async function forkCampaignVersion( settings: ApiSettings, campaignId: string, versionId: string, payload: CampaignVersionUpdatePayload = {} ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/fork`, { method: "POST", body: JSON.stringify(payload) }); } export async function autosaveCampaignVersion( settings: ApiSettings, campaignId: string, versionId: string, payload: CampaignVersionUpdatePayload ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/autosave`, { method: "POST", body: JSON.stringify(payload) }); } export async function setCampaignVersionStep( settings: ApiSettings, campaignId: string, versionId: string, currentStep: string, currentFlow?: string | null ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/set-step`, { method: "POST", body: JSON.stringify({ current_flow: currentFlow, current_step: currentStep }) }); } export async function validatePartial( settings: ApiSettings, campaignId: string, versionId: string, payload: CampaignPartialValidationPayload = {} ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/validate-partial`, { method: "POST", body: JSON.stringify(payload) }); } export async function publishCampaignVersion( settings: ApiSettings, campaignId: string, versionId: string ): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/publish`, { method: "POST" }); } export async function validateVersion( settings: ApiSettings, versionId: string, checkFiles = false ): Promise> { return apiFetch>(settings, `/api/v1/campaigns/versions/${versionId}/validate`, { method: "POST", body: JSON.stringify({ check_files: checkFiles }) }); } export async function buildVersion( settings: ApiSettings, versionId: string, writeEml = true ): Promise> { return apiFetch>(settings, `/api/v1/campaigns/versions/${versionId}/build`, { method: "POST", body: JSON.stringify({ write_eml: writeEml }) }); } export async function getCampaignSummary(settings: ApiSettings, campaignId: string): Promise { return apiFetch(settings, `/api/v1/campaigns/${campaignId}/summary`); } export async function getCampaignJobs(settings: ApiSettings, campaignId: string): Promise<{ jobs: Record[] }> { return apiFetch<{ jobs: Record[] }>(settings, `/api/v1/campaigns/${campaignId}/jobs`); } export async function queueCampaign( settings: ApiSettings, campaignId: string, payload: CampaignQueuePayload = {} ): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/queue`, { method: "POST", body: JSON.stringify(payload) }); } export async function sendCampaignNow( settings: ApiSettings, campaignId: string, payload: CampaignSendNowPayload = {} ): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/send-now`, { method: "POST", body: JSON.stringify(payload) }); } export async function pauseCampaign(settings: ApiSettings, campaignId: string): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/pause`, { method: "POST" }); } export async function resumeCampaign(settings: ApiSettings, campaignId: string): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/resume`, { method: "POST" }); } export async function cancelCampaign(settings: ApiSettings, campaignId: string): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/cancel`, { method: "POST" }); } export async function appendSent( settings: ApiSettings, campaignId: string, dryRun = false ): Promise> { return apiFetch>(settings, `/api/v1/campaigns/${campaignId}/append-sent`, { method: "POST", body: JSON.stringify({ dry_run: dryRun }) }); }