// 배치관리 전용 API 클라이언트 (기존 소스와 완전 분리)
// 작성일: 2024-12-24

import { apiClient } from "./client";

// 배치관리 전용 타입 정의
export interface BatchConnectionInfo {
  type: "internal" | "external";
  id?: number;
  name: string;
  db_type?: string;
}

export interface BatchColumnInfo {
  column_name: string;
  data_type: string;
  is_nullable?: string;
  column_default?: string | null;
}

export interface BatchTableInfo {
  table_name: string;
  columns: BatchColumnInfo[];
  description?: string | null;
}

export interface BatchApiResponse<T = unknown> {
  success: boolean;
  data?: T;
  message?: string;
  error?: string;
}

class BatchManagementAPIClass {
  private static readonly BASE_PATH = "/batch-management";

  /**
   * 사용 가능한 커넥션 목록 조회
   */
  static async getAvailableConnections(): Promise<BatchConnectionInfo[]> {
    try {
      const response = await apiClient.get<BatchApiResponse<BatchConnectionInfo[]>>(`${this.BASE_PATH}/connections`);

      if (!response.data.success) {
        throw new Error(response.data.message || "커넥션 목록 조회에 실패했습니다.");
      }

      return response.data.data || [];
    } catch (error) {
      console.error("커넥션 목록 조회 오류:", error);
      throw error;
    }
  }

  /**
   * 특정 커넥션의 테이블 목록 조회
   */
  static async getTablesFromConnection(
    connectionType: "internal" | "external",
    connectionId?: number,
  ): Promise<string[]> {
    try {
      let url = `${this.BASE_PATH}/connections/${connectionType}`;
      if (connectionType === "external" && connectionId) {
        url += `/${connectionId}`;
      }
      url += "/tables";

      const response = await apiClient.get<BatchApiResponse<string[]>>(url);

      if (!response.data.success) {
        throw new Error(response.data.message || "테이블 목록 조회에 실패했습니다.");
      }

      return response.data.data || [];
    } catch (error) {
      console.error("테이블 목록 조회 오류:", error);
      throw error;
    }
  }

  /**
   * 특정 테이블의 컬럼 정보 조회
   */
  static async getTableColumns(
    connectionType: "internal" | "external",
    tableName: string,
    connectionId?: number,
  ): Promise<BatchColumnInfo[]> {
    try {
      let url = `${this.BASE_PATH}/connections/${connectionType}`;
      if (connectionType === "external" && connectionId) {
        url += `/${connectionId}`;
      }
      url += `/tables/${encodeURIComponent(tableName)}/columns`;

      console.log("🔍 컬럼 조회 API 호출:", { url, connectionType, connectionId, tableName });

      const response = await apiClient.get<BatchApiResponse<BatchColumnInfo[]>>(url);

      console.log("🔍 컬럼 조회 API 응답:", response.data);

      if (!response.data.success) {
        throw new Error(response.data.message || "컬럼 정보 조회에 실패했습니다.");
      }

      return response.data.data || [];
    } catch (error) {
      console.error("❌ 컬럼 정보 조회 오류:", error);
      throw error;
    }
  }

  /**
   * REST API 데이터 미리보기
   */
  static async previewRestApiData(
    apiUrl: string,
    apiKey: string,
    endpoint: string,
    method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
    paramInfo?: {
      paramType: "url" | "query";
      paramName: string;
      paramValue: string;
      paramSource: "static" | "dynamic";
    },
    requestBody?: string,
    authServiceName?: string, // DB에서 토큰 가져올 서비스명
    dataArrayPath?: string, // 데이터 배열 경로 (예: response, data.items)
  ): Promise<{
    fields: string[];
    samples: any[];
    totalCount: number;
  }> {
    try {
      const requestData: any = {
        apiUrl,
        apiKey,
        endpoint,
        method,
        requestBody,
      };

      // 파라미터 정보가 있으면 추가
      if (paramInfo) {
        requestData.paramType = paramInfo.paramType;
        requestData.paramName = paramInfo.paramName;
        requestData.paramValue = paramInfo.paramValue;
        requestData.paramSource = paramInfo.paramSource;
      }

      // DB에서 토큰 가져올 서비스명 추가
      if (authServiceName) {
        requestData.authServiceName = authServiceName;
      }

      // 데이터 배열 경로 추가
      if (dataArrayPath) {
        requestData.dataArrayPath = dataArrayPath;
      }

      const response = await apiClient.post<
        BatchApiResponse<{
          fields: string[];
          samples: any[];
          totalCount: number;
        }>
      >(`${this.BASE_PATH}/rest-api/preview`, requestData);

      if (!response.data.success) {
        throw new Error(response.data.message || "REST API 미리보기에 실패했습니다.");
      }

      return response.data.data || { fields: [], samples: [], totalCount: 0 };
    } catch (error) {
      console.error("REST API 미리보기 오류:", error);
      throw error;
    }
  }

  /**
   * 인증 서비스명 목록 조회
   */
  static async getAuthServiceNames(): Promise<string[]> {
    try {
      const response = await apiClient.get<BatchApiResponse<string[]>>(`${this.BASE_PATH}/auth-services`);

      if (!response.data.success) {
        throw new Error(response.data.message || "인증 서비스 목록 조회에 실패했습니다.");
      }

      return response.data.data || [];
    } catch (error) {
      console.error("인증 서비스 목록 조회 오류:", error);
      throw error;
    }
  }

  /**
   * REST API 배치 저장
   */
  static async saveRestApiBatch(batchData: {
    batchName: string;
    batchType: string;
    cronSchedule: string;
    description?: string;
    apiMappings: any[];
    authServiceName?: string;
    dataArrayPath?: string; // REST API 응답에서 데이터 배열 경로
    saveMode?: "INSERT" | "UPSERT";
    conflictKey?: string;
  }): Promise<{ success: boolean; message: string; data?: any }> {
    try {
      const response = await apiClient.post<BatchApiResponse<any>>(`${this.BASE_PATH}/rest-api/save`, batchData);
      return {
        success: response.data.success,
        message: response.data.message || "",
        data: response.data.data,
      };
    } catch (error) {
      console.error("REST API 배치 저장 오류:", error);
      throw error;
    }
  }
}

export const BatchManagementAPI = BatchManagementAPIClass;
