/**
 * 플로우 관리 API 클라이언트
 */

import {
  FlowDefinition,
  CreateFlowDefinitionRequest,
  UpdateFlowDefinitionRequest,
  FlowStep,
  CreateFlowStepRequest,
  UpdateFlowStepRequest,
  FlowStepConnection,
  CreateFlowConnectionRequest,
  FlowStepDataCount,
  FlowStepDataList,
  MoveDataRequest,
  MoveBatchDataRequest,
  FlowAuditLog,
  ApiResponse,
} from "@/types/flow";

// API URL 동적 설정
const getApiBaseUrl = (): string => {
  // 1. 환경변수가 있으면 우선 사용
  if (process.env.NEXT_PUBLIC_API_URL) {
    return process.env.NEXT_PUBLIC_API_URL;
  }

  // 2. 클라이언트 사이드에서 동적 설정
  if (typeof window !== "undefined") {
    const currentHost = window.location.hostname;

    // 프로덕션 환경: v1.vexplor.com → api.vexplor.com
    if (currentHost === "v1.vexplor.com") {
      return "https://api.vexplor.com/api";
    }

    // 로컬 개발환경
    if (currentHost === "localhost" || currentHost === "127.0.0.1") {
      return "http://localhost:8080/api";
    }
  }

  // 3. 기본값
  return "/api";
};

const API_BASE = getApiBaseUrl();

// 토큰 가져오기
function getAuthToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem("authToken") || sessionStorage.getItem("authToken");
}

// 인증 헤더 생성 헬퍼
function getAuthHeaders(): HeadersInit {
  const token = getAuthToken();
  const headers: HeadersInit = {
    "Content-Type": "application/json",
  };
  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }
  return headers;
}

// ============================================
// 플로우 정의 API
// ============================================

/**
 * 플로우 정의 목록 조회
 */
export async function getFlowDefinitions(params?: {
  tableName?: string;
  isActive?: boolean;
}): Promise<ApiResponse<FlowDefinition[]>> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.tableName) queryParams.append("tableName", params.tableName);
    if (params?.isActive !== undefined) queryParams.append("isActive", String(params.isActive));

    const url = `${API_BASE}/flow/definitions${queryParams.toString() ? `?${queryParams.toString()}` : ""}`;

    const response = await fetch(url, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 정의 상세 조회
 */
export async function getFlowDefinition(id: number): Promise<ApiResponse<FlowDefinition>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 정의 상세 조회 (별칭)
 */
export const getFlowById = getFlowDefinition;

/**
 * 플로우 정의 생성
 */
export async function createFlowDefinition(data: CreateFlowDefinitionRequest): Promise<ApiResponse<FlowDefinition>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions`, {
      method: "POST",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 정의 수정
 */
export async function updateFlowDefinition(
  id: number,
  data: UpdateFlowDefinitionRequest,
): Promise<ApiResponse<FlowDefinition>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
      method: "PUT",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 정의 삭제
 */
export async function deleteFlowDefinition(id: number): Promise<ApiResponse<{ success: boolean }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions/${id}`, {
      method: "DELETE",
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 플로우 단계 API
// ============================================

/**
 * 플로우 단계 목록 조회
 */
export async function getFlowSteps(flowId: number): Promise<ApiResponse<FlowStep[]>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions/${flowId}/steps`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 단계 생성
 */
export async function createFlowStep(flowId: number, data: CreateFlowStepRequest): Promise<ApiResponse<FlowStep>> {
  try {
    const response = await fetch(`${API_BASE}/flow/definitions/${flowId}/steps`, {
      method: "POST",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 단계 수정
 */
export async function updateFlowStep(stepId: number, data: UpdateFlowStepRequest): Promise<ApiResponse<FlowStep>> {
  try {
    const response = await fetch(`${API_BASE}/flow/steps/${stepId}`, {
      method: "PUT",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 단계 삭제
 */
export async function deleteFlowStep(stepId: number): Promise<ApiResponse<{ success: boolean }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/steps/${stepId}`, {
      method: "DELETE",
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 플로우 연결 API
// ============================================

/**
 * 플로우 연결 목록 조회
 */
export async function getFlowConnections(flowId: number): Promise<ApiResponse<FlowStepConnection[]>> {
  try {
    const response = await fetch(`${API_BASE}/flow/connections/${flowId}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 연결 생성
 */
export async function createFlowConnection(
  data: CreateFlowConnectionRequest,
): Promise<ApiResponse<FlowStepConnection>> {
  try {
    const response = await fetch(`${API_BASE}/flow/connections`, {
      method: "POST",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 연결 삭제
 */
export async function deleteFlowConnection(connectionId: number): Promise<ApiResponse<{ success: boolean }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/connections/${connectionId}`, {
      method: "DELETE",
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 플로우 실행 API
// ============================================

/**
 * 특정 단계의 데이터 카운트 조회
 */
export async function getStepDataCount(flowId: number, stepId: number): Promise<ApiResponse<FlowStepDataCount>> {
  try {
    const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/count`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 특정 단계의 데이터 리스트 조회 (페이징)
 */
export async function getStepDataList(
  flowId: number,
  stepId: number,
  page: number = 1,
  pageSize: number = 20,
): Promise<ApiResponse<FlowStepDataList>> {
  try {
    const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/list?page=${page}&pageSize=${pageSize}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 스텝의 컬럼 라벨 조회
 */
export async function getStepColumnLabels(
  flowId: number,
  stepId: number,
): Promise<ApiResponse<Record<string, string>>> {
  try {
    const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/column-labels`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 모든 단계의 데이터 카운트 조회
 */
export async function getAllStepCounts(flowId: number): Promise<ApiResponse<FlowStepDataCount[]>> {
  try {
    const response = await fetch(`${API_BASE}/flow/${flowId}/steps/counts`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 데이터 이동
 */
export async function moveData(data: MoveDataRequest): Promise<ApiResponse<{ success: boolean }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/move`, {
      method: "POST",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 데이터를 다음 스텝으로 이동 (편의 함수)
 */
export async function moveDataToNextStep(
  flowId: number,
  fromStepId: number,
  toStepId: number,
  recordId: string | number,
): Promise<ApiResponse<{ success: boolean }>> {
  return moveData({
    flowId,
    fromStepId,
    recordId: String(recordId),
    toStepId,
  });
}

/**
 * 배치 데이터 이동
 */
export async function moveBatchData(
  data: MoveBatchDataRequest,
): Promise<ApiResponse<{ success: boolean; results: any[] }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/move-batch`, {
      method: "POST",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(data),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 오딧 로그 API
// ============================================

/**
 * 특정 레코드의 오딧 로그 조회
 */
export async function getAuditLogs(flowId: number, recordId: string): Promise<ApiResponse<FlowAuditLog[]>> {
  try {
    const response = await fetch(`${API_BASE}/flow/audit/${flowId}/${recordId}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

/**
 * 플로우 전체 오딧 로그 조회
 */
export async function getFlowAuditLogs(flowId: number, limit: number = 100): Promise<ApiResponse<FlowAuditLog[]>> {
  try {
    const response = await fetch(`${API_BASE}/flow/audit/${flowId}?limit=${limit}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 플로우 스텝 데이터 수정 API
// ============================================

/**
 * 플로우 스텝 데이터 업데이트 (인라인 편집)
 * @param flowId 플로우 정의 ID
 * @param stepId 스텝 ID
 * @param recordId 레코드의 primary key 값
 * @param updateData 업데이트할 데이터
 */
export async function updateFlowStepData(
  flowId: number,
  stepId: number,
  recordId: string | number,
  updateData: Record<string, any>,
): Promise<ApiResponse<{ success: boolean }>> {
  try {
    const response = await fetch(`${API_BASE}/flow/${flowId}/step/${stepId}/data/${recordId}`, {
      method: "PUT",
      headers: getAuthHeaders(),
      credentials: "include",
      body: JSON.stringify(updateData),
    });

    return await response.json();
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
}

// ============================================
// 프로시저/함수 API
// ============================================

import type { ProcedureListItem, ProcedureParameterInfo } from "@/types/flowExternalDb";

/**
 * 프로시저/함수 목록 조회
 */
export async function getFlowProcedures(
  dbSource: "internal" | "external",
  connectionId?: number,
  schema?: string,
): Promise<ApiResponse<ProcedureListItem[]>> {
  try {
    const params = new URLSearchParams({ dbSource });
    if (connectionId) params.set("connectionId", String(connectionId));
    if (schema) params.set("schema", schema);

    const response = await fetch(`${API_BASE}/flow/procedures?${params.toString()}`, {
      headers: getAuthHeaders(),
      credentials: "include",
    });

    return await response.json();
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}

/**
 * 프로시저/함수 파라미터 조회
 */
export async function getFlowProcedureParameters(
  name: string,
  dbSource: "internal" | "external",
  connectionId?: number,
  schema?: string,
): Promise<ApiResponse<ProcedureParameterInfo[]>> {
  try {
    const params = new URLSearchParams({ dbSource });
    if (connectionId) params.set("connectionId", String(connectionId));
    if (schema) params.set("schema", schema);

    const response = await fetch(
      `${API_BASE}/flow/procedures/${encodeURIComponent(name)}/parameters?${params.toString()}`,
      {
        headers: getAuthHeaders(),
        credentials: "include",
      },
    );

    return await response.json();
  } catch (error: any) {
    return { success: false, error: error.message };
  }
}
