import { CriteriaDTO, normalizeCriteriaDTO } from '@erp/core';
import { useDataSource } from "@erp/core/hooks";
import { DefaultError, QueryClient, QueryKey, useQuery } from "@tanstack/react-query";
import { CustomerSummary, CustomersPage } from '../schemas';

export const CUSTOMERS_LIST_KEY = ["customers", "list"] as const

export const getCustomersListQueryKey = (criteria: CriteriaDTO) =>
  [...CUSTOMERS_LIST_KEY, normalizeCriteriaDTO(criteria)] satisfies QueryKey;

type CustomerListQueryOptions = {
  enabled?: boolean;
  criteria?: CriteriaDTO
};

// Obtener todos los clientes
export const useCustomerListQuery = (options?: CustomerListQueryOptions) => {
  const dataSource = useDataSource();
  const enabled = options?.enabled ?? true;
  const criteria = options?.criteria ?? {};

  return useQuery<CustomersPage, DefaultError>({
    queryKey: getCustomersListQueryKey(criteria),
    queryFn: async ({ signal }) => {
      return await dataSource.getList<CustomersPage>("customers", { signal, ...criteria });
    },
    enabled,
    placeholderData: (previousData, previousQuery) => previousData, // Mantener datos previos mientras se carga nueva datos (antiguo `keepPreviousData`)
  });
};

export function cancelCustomerListQueries(qc: QueryClient) {
  return qc.cancelQueries({ queryKey: CUSTOMERS_LIST_KEY });
}


export function invalidateCustomerListCache(qc: QueryClient) {
  return qc.invalidateQueries({ queryKey: CUSTOMERS_LIST_KEY });
}

export function getAllCustomerListQueryKeys(qc: QueryClient): QueryKey[] {
  // Nota: `getQueriesData` devuelve pares [key, data]
  const entries = qc.getQueriesData<CustomersPage>({ queryKey: [CUSTOMERS_LIST_KEY] });
  return entries.map(([key]) => key);
}

// Inserta o reemplaza un customer en todas las páginas donde aparezca
export function upsertCustomerIntoListCaches(qc: QueryClient, customer: CustomerSummary) {
  const keys = getAllCustomerListQueryKeys(qc);
  for (const key of keys) {

    const page = qc.getQueryData<CustomersPage>(key);
    if (!page) continue;

    const idx = page.items.findIndex((c) => c.id === customer.id);
    if (idx === -1) continue;

    const nextItems = page.items.slice();
    nextItems[idx] = { ...page.items[idx], ...customer };

    qc.setQueryData<CustomersPage>(key, { ...page, items: nextItems });
  }
}

export function deleteCustomerIntoListCaches(qc: QueryClient, customerId: string): {
  snapshots: Array<{ key: QueryKey; page?: CustomersPage }>;
} {
  const snapshots = getAllCustomerListQueryKeys(qc).map((key) => ({
    key,
    page: qc.getQueryData<CustomersPage>(key),
  }));

  for (const { key, page } of snapshots) {
    if (!page) continue;
    qc.setQueryData<CustomersPage>(key, {
      ...page,
      items: page.items.filter((c) => c.id !== customerId),
      total_items: Math.max(0, page.total_items - 1),
    });
  }
  return { snapshots: snapshots as Array<{ key: QueryKey; page?: CustomersPage }> };
}