/**
 * 노드 플로우 API
 */

import { apiClient } from "./client";

export interface NodeFlow {
  flowId: number;
  flowName: string;
  flowDescription: string;
  flowData: string | any; // JSONB는 문자열 또는 객체로 반환될 수 있음
  createdAt: string;
  updatedAt: string;
}

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
}

/**
 * 플로우 목록 조회
 */
export async function getNodeFlows(): Promise<NodeFlow[]> {
  const response = await apiClient.get<ApiResponse<NodeFlow[]>>("/dataflow/node-flows");
  if (response.data.success && response.data.data) {
    return response.data.data;
  }
  throw new Error(response.data.message || "플로우 목록을 불러올 수 없습니다.");
}

/**
 * 플로우 상세 조회
 */
export async function getNodeFlow(flowId: number): Promise<NodeFlow> {
  const response = await apiClient.get<ApiResponse<NodeFlow>>(`/dataflow/node-flows/${flowId}`);
  if (response.data.success && response.data.data) {
    return response.data.data;
  }
  throw new Error(response.data.message || "플로우를 불러올 수 없습니다.");
}

/**
 * 플로우 저장 (신규)
 */
export async function createNodeFlow(data: {
  flowName: string;
  flowDescription: string;
  flowData: string;
}): Promise<{ flowId: number }> {
  const response = await apiClient.post<ApiResponse<{ flowId: number }>>("/dataflow/node-flows", data);
  if (response.data.success && response.data.data) {
    return response.data.data;
  }
  throw new Error(response.data.message || "플로우를 저장할 수 없습니다.");
}

/**
 * 플로우 수정
 */
export async function updateNodeFlow(data: {
  flowId: number;
  flowName: string;
  flowDescription: string;
  flowData: string;
}): Promise<{ flowId: number }> {
  const response = await apiClient.put<ApiResponse<{ flowId: number }>>("/dataflow/node-flows", data);
  if (response.data.success && response.data.data) {
    return response.data.data;
  }
  throw new Error(response.data.message || "플로우를 수정할 수 없습니다.");
}

/**
 * 플로우 삭제
 */
export async function deleteNodeFlow(flowId: number): Promise<void> {
  const response = await apiClient.delete<ApiResponse<void>>(`/dataflow/node-flows/${flowId}`);
  if (!response.data.success) {
    throw new Error(response.data.message || "플로우를 삭제할 수 없습니다.");
  }
}

/**
 * 플로우 실행
 */
export async function executeNodeFlow(flowId: number, contextData: Record<string, any>): Promise<ExecutionResult> {
  const response = await apiClient.post<ApiResponse<ExecutionResult>>(
    `/dataflow/node-flows/${flowId}/execute`,
    contextData,
  );
  if (response.data.success && response.data.data) {
    return response.data.data;
  }
  throw new Error(response.data.message || "플로우를 실행할 수 없습니다.");
}

/**
 * 플로우 실행 결과 인터페이스
 */
export interface ExecutionResult {
  success: boolean;
  message: string;
  executionTime: number;
  nodes: NodeExecutionSummary[];
  summary: {
    total: number;
    success: number;
    failed: number;
    skipped: number;
  };
}

export interface NodeExecutionSummary {
  nodeId: string;
  nodeName: string;
  nodeType: string;
  status: "success" | "failed" | "skipped" | "pending";
  duration?: number;
  error?: string;
}

/**
 * 플로우 소스 테이블 정보 인터페이스
 */
export interface FlowSourceTableInfo {
  sourceTable: string | null;
  sourceNodeType: string | null;
  sourceNodeId?: string;
  displayName?: string;
  message?: string;
}

/**
 * 플로우 소스 테이블 조회
 * 플로우의 첫 번째 소스 노드(tableSource, externalDBSource)에서 테이블명 추출
 */
export async function getFlowSourceTable(flowId: number): Promise<FlowSourceTableInfo> {
  try {
    const response = await apiClient.get<ApiResponse<FlowSourceTableInfo>>(
      `/dataflow/node-flows/${flowId}/source-table`,
    );
    if (response.data.success && response.data.data) {
      return response.data.data;
    }
    return {
      sourceTable: null,
      sourceNodeType: null,
      message: response.data.message || "소스 테이블 정보를 가져올 수 없습니다.",
    };
  } catch (error) {
    console.error("플로우 소스 테이블 조회 실패:", error);
    return {
      sourceTable: null,
      sourceNodeType: null,
      message: "API 호출 중 오류가 발생했습니다.",
    };
  }
}
