/**
 * Pipeline API client functions.
 *
 * Provides methods for interacting with the pipeline API endpoints.
 */

import type {
  PipelineInfo,
  PipelineDetail,
  DashboardConfig,
  ExecutionStatus,
  WidgetData,
} from './pipeline-types';

// API base URL - defaults to same origin in production
const API_BASE = process.env.NEXT_PUBLIC_API_URL || '';

/**
 * Fetch all registered pipelines.
 */
export async function listPipelines(enabledOnly = true): Promise<PipelineInfo[]> {
  const url = `${API_BASE}/api/pipelines?enabled_only=${enabledOnly}`;
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to fetch pipelines: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Fetch details for a specific pipeline.
 */
export async function getPipeline(pipelineId: string): Promise<PipelineDetail> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}`;
  const response = await fetch(url);

  if (!response.ok) {
    if (response.status === 404) {
      throw new Error(`Pipeline not found: ${pipelineId}`);
    }
    throw new Error(`Failed to fetch pipeline: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Fetch dashboard configuration for a pipeline.
 */
export async function getDashboardConfig(pipelineId: string): Promise<DashboardConfig> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/dashboard`;
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to fetch dashboard config: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Fetch data for a specific widget.
 */
export async function getWidgetData(
  pipelineId: string,
  widgetId: string,
  params: {
    business_id?: string;
    job_id?: string;
    time_range?: string;
    page?: number;
    page_size?: number;
  } = {}
): Promise<WidgetData> {
  const searchParams = new URLSearchParams();

  if (params.business_id) {
    searchParams.set('business_id', params.business_id);
  }
  if (params.job_id) {
    searchParams.set('job_id', params.job_id);
  }
  if (params.time_range) {
    searchParams.set('time_range', params.time_range);
  }
  if (params.page) {
    searchParams.set('page', params.page.toString());
  }
  if (params.page_size) {
    searchParams.set('page_size', params.page_size.toString());
  }

  const url = `${API_BASE}/api/pipelines/${pipelineId}/widgets/${widgetId}?${searchParams}`;
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to fetch widget data: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Execute a pipeline.
 */
export async function executePipeline(
  pipelineId: string,
  request: {
    job_id?: string;
    business_id?: string;
    input_data?: Record<string, unknown>;
    stages?: string[];
    options?: Record<string, unknown>;
  }
): Promise<{
  execution_id: string;
  pipeline_id: string;
  success: boolean;
  stages_run: string[];
  error?: string;
}> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/execute`;
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(request),
  });

  if (!response.ok) {
    throw new Error(`Failed to execute pipeline: ${response.statusText}`);
  }

  return response.json();
}

/**
 * List execution history for a pipeline.
 */
export async function listExecutions(
  pipelineId: string,
  params: {
    status?: string;
    limit?: number;
    offset?: number;
  } = {}
): Promise<ExecutionStatus[]> {
  const searchParams = new URLSearchParams();

  if (params.status) {
    searchParams.set('status', params.status);
  }
  if (params.limit) {
    searchParams.set('limit', params.limit.toString());
  }
  if (params.offset) {
    searchParams.set('offset', params.offset.toString());
  }

  const url = `${API_BASE}/api/pipelines/${pipelineId}/executions?${searchParams}`;
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to fetch executions: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Get a specific execution by ID.
 */
export async function getExecution(
  pipelineId: string,
  executionId: string
): Promise<ExecutionStatus> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/executions/${executionId}`;
  const response = await fetch(url);

  if (!response.ok) {
    if (response.status === 404) {
      throw new Error(`Execution not found: ${executionId}`);
    }
    throw new Error(`Failed to fetch execution: ${response.statusText}`);
  }

  return response.json();
}

/**
 * Enable a pipeline.
 */
export async function enablePipeline(pipelineId: string): Promise<void> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/enable`;
  const response = await fetch(url, { method: 'POST' });

  if (!response.ok) {
    throw new Error(`Failed to enable pipeline: ${response.statusText}`);
  }
}

/**
 * Disable a pipeline.
 */
export async function disablePipeline(pipelineId: string): Promise<void> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/disable`;
  const response = await fetch(url, { method: 'POST' });

  if (!response.ok) {
    throw new Error(`Failed to disable pipeline: ${response.statusText}`);
  }
}

/**
 * Check pipeline health.
 */
export async function checkPipelineHealth(
  pipelineId: string
): Promise<{
  pipeline_id: string;
  healthy: boolean;
  checks?: Record<string, unknown>;
  message?: string;
  error?: string;
}> {
  const url = `${API_BASE}/api/pipelines/${pipelineId}/health`;
  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Failed to check pipeline health: ${response.statusText}`);
  }

  return response.json();
}
