import apiClient from "./api";

/**
 * Fetch column definitions for a DataTable resource (key, header, type, searchable, filterable, defaultVisible).
 * GET /api/datatables/{resourceKey}/columns.
 *
 * @param {string} resourceKey - e.g. 'companies', 'users', 'companies-contact-persons'
 * @param {import('axios').AxiosRequestConfig} [config] - optional axios config (e.g. abort signal)
 * @returns {Promise<Array<{ key: string, header: string, type: string, searchable: boolean, filterable: boolean, defaultVisible: boolean }>>}
 */
export async function getDataTableColumns(resourceKey, config = {}) {
  const encoded = encodeURIComponent(resourceKey);
  const { data } = await apiClient.get(
    `/datatables/${encoded}/columns`,
    config,
  );
  return data;
}

/**
 * DataTable API: POST to /api/datatables/{resourceKey} with pagination, sort, filters, globalSearch.
 * Uses the same apiClient as tableStateService (auth, cookies, baseURL).
 *
 * @param {string} resourceKey - e.g. 'companies', 'users', 'roles'
 * @param {object} payload - { tableKey?, pagination: { page, limit }, sort?, visibleColumns?, filters?, globalSearch? }
 * @param {import('axios').AxiosRequestConfig} [config] - optional axios config (e.g. abort signal)
 * @returns {Promise<{ data: any[], meta: { page, limit, total, sort } }>}
 */
export async function fetchDataTable(resourceKey, payload, config = {}) {
  const encoded = encodeURIComponent(resourceKey);
  const { data } = await apiClient.post(
    `/datatables/${encoded}`,
    payload,
    config,
  );
  return data;
}

/**
 * DataTable export (async): POST to /api/datatables/{resourceKey}/export. Starts background job; returns export id for polling.
 *
 * @param {string} resourceKey - e.g. 'companies', 'users', 'roles', 'sectors'
 * @param {object} payload - { tableKey?, visibleColumns, columnOrder?, filters?, globalSearch?, sort? }
 * @returns {Promise<{ id: string, status: string, resourceKey: string, pollingIntervalHintMs?: number }>}
 */
export async function exportDataTable(resourceKey, payload) {
  const encoded = encodeURIComponent(resourceKey);
  const { data } = await apiClient.post(
    `/datatables/${encoded}/export`,
    payload,
  );
  return data;
}

/**
 * Get status of an async DataTable export. Used for polling until status is 'completed' or 'failed'.
 *
 * @param {string} exportId - UUID from exportDataTable response
 * @returns {Promise<{ id: string, status: string, resourceKey: string, downloadUrl?: string, errorMessage?: string }>}
 */
export async function getDataTableExportStatus(exportId) {
  const encoded = encodeURIComponent(exportId);
  const { data } = await apiClient.get(`/datatables/exports/${encoded}`);
  return data;
}

/**
 * List current user's DataTable exports (pending, processing, completed with download, failed).
 * Used by the header to show "download ready" notifications and allow download from there.
 *
 * @returns {Promise<{ data: Array<{ id: string, resourceKey: string, resourceLabel?: string, status: string, createdAt?: string, downloadUrl?: string, errorMessage?: string }> }>}
 */
export async function listDataTableExports() {
  const { data } = await apiClient.get("/datatables/exports");
  return data;
}

/**
 * Download a specific DataTable export as a CSV file.
 * Uses the same apiClient (withCredentials, baseURL) so the existing session is reused.
 *
 * @param {string} exportId
 * @param {string} [suggestedName] - optional name hint (e.g. resourceKey) for the downloaded file
 */
export async function downloadDataTableExport(exportId, suggestedName) {
  const encoded = encodeURIComponent(exportId);
  const response = await apiClient.get(
    `/datatables/exports/${encoded}/download`,
    {
      responseType: "blob",
    },
  );

  // Try to extract filename from Content-Disposition header; fall back to suggestedName or generic.
  const disposition =
    response.headers["content-disposition"] ||
    response.headers["Content-Disposition"];
  let filename = "export.csv";
  if (disposition && typeof disposition === "string") {
    const match = disposition.match(/filename="?([^"]+)"?/i);
    if (match && match[1]) {
      filename = match[1];
    }
  } else if (suggestedName) {
    filename = `export-${suggestedName}.csv`;
  }

  const blob = response.data;
  const url = window.URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  window.URL.revokeObjectURL(url);
}

/**
 * Clear all ready exports for the current user: deletes files on the server and marks them completed.
 * Used by the header \"clear all\" button.
 *
 * @returns {Promise<{ cleared: number, filesDeleted: number }>}
 */
export async function clearReadyDataTableExports() {
  const { data } = await apiClient.post("/datatables/exports/clear-ready");
  return data;
}
