// REST API 연결 관리 API 클라이언트

import { apiClient } from "./client";

export type AuthType = "none" | "api-key" | "bearer" | "basic" | "oauth2" | "db-token";

export interface ExternalRestApiConnection {
  id?: number;
  connection_name: string;
  description?: string;
  base_url: string;
  endpoint_path?: string;
  default_headers: Record<string, string>;
  // 기본 메서드 및 바디 추가
  default_method?: string;
  default_body?: string;

  auth_type: AuthType;
  auth_config?: {
    // API Key
    keyLocation?: "header" | "query";
    keyName?: string;
    keyValue?: string;
    // Bearer Token
    token?: string;
    // Basic Auth
    username?: string;
    password?: string;
    // OAuth2
    clientId?: string;
    clientSecret?: string;
    tokenUrl?: string;
    accessToken?: string;

    // DB 기반 토큰 모드
    dbTableName?: string;
    dbValueColumn?: string;
    dbWhereColumn?: string;
    dbWhereValue?: string;
    dbHeaderName?: string;
    dbHeaderTemplate?: string;
  };
  timeout?: number;
  retry_count?: number;
  retry_delay?: number;
  company_code: string;
  is_active: string;
  
  // 위치 이력 저장 설정 (지도 위젯용)
  save_to_history?: string; // 'Y' 또는 'N' - REST API에서 가져온 위치 데이터를 vehicle_location_history에 저장
  created_date?: Date;
  created_by?: string;
  updated_date?: Date;
  updated_by?: string;
  last_test_date?: Date;
  last_test_result?: string;
  last_test_message?: string;
}

export interface ExternalRestApiConnectionFilter {
  auth_type?: string;
  is_active?: string;
  company_code?: string;
  search?: string;
}

export interface RestApiTestRequest {
  id?: number;
  base_url: string;
  endpoint?: string;
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
  headers?: Record<string, string>;
  body?: unknown; // 테스트 요청 바디 추가
  auth_type?: AuthType;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  auth_config?: any;
  timeout?: number;
}

export interface RestApiTestResult {
  success: boolean;
  message: string;
  response_time?: number;
  status_code?: number;
  response_data?: unknown;
  error_details?: string;
}

export interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
  error?: {
    code: string;
    details?: unknown;
  };
}

export class ExternalRestApiConnectionAPI {
  private static readonly BASE_PATH = "/external-rest-api-connections";

  /**
   * 연결 목록 조회
   */
  static async getConnections(filter?: ExternalRestApiConnectionFilter): Promise<ExternalRestApiConnection[]> {
    const params = new URLSearchParams();

    if (filter?.search) params.append("search", filter.search);
    if (filter?.auth_type && filter.auth_type !== "ALL") {
      params.append("auth_type", filter.auth_type);
    }
    if (filter?.is_active && filter.is_active !== "ALL") {
      params.append("is_active", filter.is_active);
    }
    if (filter?.company_code) {
      params.append("company_code", filter.company_code);
    }

    const url = params.toString() ? `${this.BASE_PATH}?${params}` : this.BASE_PATH;
    const response = await apiClient.get<ApiResponse<ExternalRestApiConnection[]>>(url);

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

    return response.data.data || [];
  }

  /**
   * 연결 상세 조회
   */
  static async getConnectionById(id: number): Promise<ExternalRestApiConnection> {
    const response = await apiClient.get<ApiResponse<ExternalRestApiConnection>>(`${this.BASE_PATH}/${id}`);

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

    return response.data.data!;
  }

  /**
   * 연결 생성
   */
  static async createConnection(data: ExternalRestApiConnection): Promise<ExternalRestApiConnection> {
    const response = await apiClient.post<ApiResponse<ExternalRestApiConnection>>(this.BASE_PATH, data);

    if (!response.data.success) {
      throw new Error(response.data.message || "연결 생성에 실패했습니다.");
    }

    return response.data.data!;
  }

  /**
   * 연결 수정
   */
  static async updateConnection(
    id: number,
    data: Partial<ExternalRestApiConnection>,
  ): Promise<ExternalRestApiConnection> {
    const response = await apiClient.put<ApiResponse<ExternalRestApiConnection>>(`${this.BASE_PATH}/${id}`, data);

    if (!response.data.success) {
      throw new Error(response.data.message || "연결 수정에 실패했습니다.");
    }

    return response.data.data!;
  }

  /**
   * 연결 삭제
   */
  static async deleteConnection(id: number): Promise<void> {
    const response = await apiClient.delete<ApiResponse<void>>(`${this.BASE_PATH}/${id}`);

    if (!response.data.success) {
      throw new Error(response.data.message || "연결 삭제에 실패했습니다.");
    }
  }

  /**
   * 연결 테스트 (테스트 데이터 기반)
   */
  static async testConnection(testRequest: RestApiTestRequest): Promise<RestApiTestResult> {
    const response = await apiClient.post<RestApiTestResult>(`${this.BASE_PATH}/test`, testRequest);
    return response.data;
  }

  /**
   * 연결 테스트 (ID 기반)
   */
  static async testConnectionById(id: number, endpoint?: string): Promise<RestApiTestResult> {
    const response = await apiClient.post<RestApiTestResult>(`${this.BASE_PATH}/${id}/test`, { endpoint });
    return response.data;
  }

  /**
   * REST API 데이터 조회 (화면관리용 프록시)
   */
  static async fetchData(
    connectionId: number,
    endpoint?: string,
    jsonPath?: string,
  ): Promise<{
    rows: any[];
    columns: Array<{ columnName: string; columnLabel: string; dataType: string }>;
    total: number;
    connectionInfo: {
      connectionId: number;
      connectionName: string;
      baseUrl: string;
      endpoint: string;
    };
  }> {
    const response = await apiClient.post<ApiResponse<{
      rows: any[];
      columns: Array<{ columnName: string; columnLabel: string; dataType: string }>;
      total: number;
      connectionInfo: {
        connectionId: number;
        connectionName: string;
        baseUrl: string;
        endpoint: string;
      };
    }>>(`${this.BASE_PATH}/${connectionId}/fetch`, { endpoint, jsonPath });

    if (!response.data.success) {
      throw new Error(response.data.message || "REST API 데이터 조회에 실패했습니다.");
    }

    return response.data.data!;
  }

  /**
   * 지원되는 인증 타입 목록
   */
  static getSupportedAuthTypes(): Array<{ value: string; label: string }> {
    return [
      { value: "none", label: "인증 없음" },
      { value: "api-key", label: "API Key" },
      { value: "bearer", label: "Bearer Token" },
      { value: "basic", label: "Basic Auth" },
      { value: "oauth2", label: "OAuth 2.0" },
      { value: "db-token", label: "DB 토큰" },
    ];
  }
}
