import client from './client';

export interface PluginDataRecord {
  id: string;
  data: Record<string, unknown>;
  created_at?: string;
  updated_at?: string;
  version?: number;
}

interface PaginatedDataResponse {
  data: PluginDataRecord[];
  total: number;
  page: number;
  page_size: number;
  total_pages: number;
}

export interface PluginDataListOptions {
  filter?: Record<string, string>;
  search?: string;
  sort_by?: string;
  sort_order?: 'asc' | 'desc';
}

export async function listPluginData(
  pluginId: string,
  entity: string,
  page = 1,
  pageSize = 20,
  options?: PluginDataListOptions,
) {
  const params: Record<string, string> = {
    page: String(page),
    page_size: String(pageSize),
  };
  if (options?.filter) params.filter = JSON.stringify(options.filter);
  if (options?.search) params.search = options.search;
  if (options?.sort_by) params.sort_by = options.sort_by;
  if (options?.sort_order) params.sort_order = options.sort_order;

  const { data } = await client.get<{ success: boolean; data: PaginatedDataResponse }>(
    `/plugins/${pluginId}/${entity}`,
    { params },
  );
  return data.data;
}

export async function getPluginData(pluginId: string, entity: string, id: string) {
  const { data } = await client.get<{ success: boolean; data: PluginDataRecord }>(
    `/plugins/${pluginId}/${entity}/${id}`,
  );
  return data.data;
}

export async function createPluginData(
  pluginId: string,
  entity: string,
  recordData: Record<string, unknown>,
) {
  const { data } = await client.post<{ success: boolean; data: PluginDataRecord }>(
    `/plugins/${pluginId}/${entity}`,
    { data: recordData },
  );
  return data.data;
}

export async function updatePluginData(
  pluginId: string,
  entity: string,
  id: string,
  recordData: Record<string, unknown>,
  version: number,
) {
  const { data } = await client.put<{ success: boolean; data: PluginDataRecord }>(
    `/plugins/${pluginId}/${entity}/${id}`,
    { data: recordData, version },
  );
  return data.data;
}

export async function deletePluginData(
  pluginId: string,
  entity: string,
  id: string,
) {
  await client.delete(`/plugins/${pluginId}/${entity}/${id}`);
}

export async function countPluginData(
  pluginId: string,
  entity: string,
  options?: { filter?: Record<string, string>; search?: string },
) {
  const params: Record<string, string> = {};
  if (options?.filter) params.filter = JSON.stringify(options.filter);
  if (options?.search) params.search = options.search;

  const { data } = await client.get<{ success: boolean; data: number }>(
    `/plugins/${pluginId}/${entity}/count`,
    { params },
  );
  return data.data;
}

export interface AggregateItem {
  key: string;
  count: number;
}

export async function aggregatePluginData(
  pluginId: string,
  entity: string,
  groupBy: string,
  filter?: Record<string, string>,
) {
  const params: Record<string, string> = { group_by: groupBy };
  if (filter) params.filter = JSON.stringify(filter);

  const { data } = await client.get<{ success: boolean; data: AggregateItem[] }>(
    `/plugins/${pluginId}/${entity}/aggregate`,
    { params },
  );
  return data.data;
}

// ── 批量操作 ──

export async function batchPluginData(
  pluginId: string,
  entity: string,
  req: { action: string; ids: string[]; data?: Record<string, unknown> },
) {
  const { data } = await client.post<{ success: boolean; data: unknown }>(
    `/plugins/${pluginId}/${entity}/batch`,
    req,
  );
  return data.data;
}

// ── 部分更新 ──

export async function patchPluginData(
  pluginId: string,
  entity: string,
  id: string,
  req: { data: Record<string, unknown>; version: number },
) {
  const { data } = await client.patch<{ success: boolean; data: PluginDataRecord }>(
    `/plugins/${pluginId}/${entity}/${id}`,
    req,
  );
  return data.data;
}

// ── 时间序列 ──

export async function getPluginTimeseries(
  pluginId: string,
  entity: string,
  params: {
    time_field: string;
    time_grain: string;
    start?: string;
    end?: string;
  },
) {
  const { data } = await client.get<{ success: boolean; data: unknown }>(
    `/plugins/${pluginId}/${entity}/timeseries`,
    { params },
  );
  return data.data;
}

// ─── 跨插件引用 API ──────────────────────────────────────────────────

export interface ResolveLabelsResult {
  labels: Record<string, Record<string, string | null>>;
  meta: Record<string, {
    target_plugin: string;
    target_entity: string;
    label_field: string;
    plugin_installed: boolean;
  }>;
}

export async function resolveRefLabels(
  pluginId: string,
  entity: string,
  fields: Record<string, string[]>,
): Promise<ResolveLabelsResult> {
  const { data } = await client.post<{ success: boolean; data: ResolveLabelsResult }>(
    `/plugins/${pluginId}/${entity}/resolve-labels`,
    { fields },
  );
  return data.data;
}

export interface PublicEntity {
  manifest_id: string;
  plugin_id: string;
  entity_name: string;
  display_name: string;
}

export async function getPluginEntityRegistry(): Promise<PublicEntity[]> {
  const { data } = await client.get<{ success: boolean; data: PublicEntity[] }>(
    '/plugin-registry/entities',
  );
  return data.data;
}

// ─── 数据导入导出 API ──────────────────────────────────────────────────

export interface ExportOptions {
  filter?: Record<string, string>;
  search?: string;
  sort_by?: string;
  sort_order?: 'asc' | 'desc';
  format?: 'json' | 'csv' | 'xlsx';
}

export async function exportPluginData(
  pluginId: string,
  entity: string,
  options?: ExportOptions,
): Promise<Record<string, unknown>[]> {
  const params: Record<string, string> = {};
  if (options?.filter) params.filter = JSON.stringify(options.filter);
  if (options?.search) params.search = options.search;
  if (options?.sort_by) params.sort_by = options.sort_by;
  if (options?.sort_order) params.sort_order = options.sort_order;

  const { data } = await client.get<{ success: boolean; data: Record<string, unknown>[] }>(
    `/plugins/${pluginId}/${entity}/export`,
    { params },
  );
  return data.data;
}

export async function exportPluginDataAsBlob(
  pluginId: string,
  entity: string,
  format: 'csv' | 'xlsx',
  options?: Omit<ExportOptions, 'format'>,
): Promise<Blob> {
  const params: Record<string, string> = { format };
  if (options?.filter) params.filter = JSON.stringify(options.filter);
  if (options?.search) params.search = options.search;
  if (options?.sort_by) params.sort_by = options.sort_by;
  if (options?.sort_order) params.sort_order = options.sort_order;

  const response = await client.get(
    `/plugins/${pluginId}/${entity}/export`,
    { params, responseType: 'blob' },
  );
  return response.data as Blob;
}

export interface ImportRowError {
  row: number;
  errors: string[];
}

export interface ImportResult {
  success_count: number;
  error_count: number;
  errors: ImportRowError[];
}

export async function importPluginData(
  pluginId: string,
  entity: string,
  rows: Record<string, unknown>[],
): Promise<ImportResult> {
  const { data } = await client.post<{ success: boolean; data: ImportResult }>(
    `/plugins/${pluginId}/${entity}/import`,
    { rows },
  );
  return data.data;
}
