import axios from 'axios';
import { API_BASE_URL } from './apiConfig';

const base = `${API_BASE_URL}/db-explorer`;

export interface DbExplorerConnection {
  id: string;
  label: string;
  kind: string;
  jdbcMasked?: string;
  createdAt?: string;
  lastAccessAt?: string;
}

export interface DbExplorerTable {
  name: string;
  approxSizeKb?: number | null;
  tableRowsApprox?: number | null;
}

export interface DbExplorerColumn {
  name: string;
  dataType: string;
  nullable: string;
}

export interface DbExplorerRowsResponse {
  columnNames: string[];
  rows: Record<string, unknown>[];
  total: number;
  page: number;
  size: number;
}

export interface ConnectBody {
  label: string;
  host: string;
  port: number;
  database: string;
  username: string;
  password: string;
  useSsl?: boolean;
  allowPublicKeyRetrieval?: boolean;
}

function errMessage(e: unknown): string {
  const ax = e as {
    response?: { status?: number; data?: { message?: string; error?: string } };
    message?: string;
  };
  const data = ax?.response?.data;
  const m = typeof data === 'object' && data !== null ? data.message || data.error : undefined;
  return m || ax?.message || '요청 실패';
}

export const dbExplorerApi = {
  listConnections: async (): Promise<DbExplorerConnection[]> => {
    const { data } = await axios.get<DbExplorerConnection[]>(`${base}/connections`);
    return data;
  },

  connect: async (body: ConnectBody): Promise<DbExplorerConnection> => {
    const { data } = await axios.post<DbExplorerConnection>(`${base}/connections`, body);
    return data;
  },

  disconnect: async (connectionId: string): Promise<void> => {
    await axios.delete(`${base}/connections/${encodeURIComponent(connectionId)}`);
  },

  listTables: async (connectionId: string): Promise<DbExplorerTable[]> => {
    const { data } = await axios.get<DbExplorerTable[]>(
      `${base}/connections/${encodeURIComponent(connectionId)}/tables`
    );
    return data;
  },

  listColumns: async (connectionId: string, tableName: string): Promise<DbExplorerColumn[]> => {
    const { data } = await axios.get<DbExplorerColumn[]>(
      `${base}/connections/${encodeURIComponent(connectionId)}/tables/${encodeURIComponent(tableName)}/columns`
    );
    return data;
  },

  fetchRows: async (
    connectionId: string,
    tableName: string,
    params: {
      page?: number;
      size?: number;
      sortColumn?: string;
      sortDir?: 'ASC' | 'DESC';
      searchColumn?: string;
      search?: string;
    }
  ): Promise<DbExplorerRowsResponse> => {
    const { data } = await axios.get<DbExplorerRowsResponse>(
      `${base}/connections/${encodeURIComponent(connectionId)}/tables/${encodeURIComponent(tableName)}/rows`,
      { params }
    );
    return data;
  },

  errMessage,
};
