// src/client/shared/lib/diffHelpers.ts
// Utility functions for comparing objects and detecting changes

/**
 * Сравнивает два объекта и возвращает массив ключей с измененными значениями
 * @param original - Оригинальный объект
 * @param current - Текущий объект
 * @returns Массив ключей, значения которых отличаются
 */
export function getChangedFields<T extends Record<string, any>>(
  original: T,
  current: T
): string[] {
  const changedFields: string[] = [];

  for (const key in current) {
    if (current[key] !== original[key]) {
      changedFields.push(key);
    }
  }

  return changedFields;
}

/**
 * Сравнивает два объекта для черного списка, игнорируя служебные поля
 * @param original - Оригинальный объект записи черного списка
 * @param current - Текущий объект записи черного списка
 * @returns Массив ключей бизнес-полей, значения которых отличаются
 */
export function getBlacklistChangedFields(
  original: Partial<{ name: string; phone: string; bookingEngineCheck: string; comment: string | null }>,
  current: Partial<{ name: string; phone: string; bookingEngineCheck: string; comment: string | null }>
): string[] {
  const businessFields = ['name', 'phone', 'bookingEngineCheck', 'comment'];
  const changedFields: string[] = [];

  for (const field of businessFields) {
    const originalValue = original[field as keyof typeof original];
    const currentValue = current[field as keyof typeof current];

    // Сравниваем значения, учитывая null
    if (originalValue !== currentValue) {
      changedFields.push(field);
    }
  }

  return changedFields;
}

/**
 * Сравнивает два объекта для контрагентов, игнорируя служебные поля
 * @param original - Оригинальный объект записи контрагента
 * @param current - Текущий объект записи контрагента
 * @returns Массив ключей бизнес-полей, значения которых отличаются
 */
export function getContractorChangedFields(
  original: Partial<{
    name: string;
    category: string;
    contractNumber: string | null;
    phone: string;
    email: string | null;
    webLink: string | null;
    managerName: string | null;
    managerPhone: string | null;
    managerEmail: string | null;
    comment: string | null;
  }>,
  current: Partial<{
    name: string;
    category: string;
    contractNumber: string | null;
    phone: string;
    email: string | null;
    webLink: string | null;
    managerName: string | null;
    managerPhone: string | null;
    managerEmail: string | null;
    comment: string | null;
  }>
): string[] {
  const businessFields = ['name', 'category', 'contractNumber', 'phone', 'email', 'webLink', 'managerName', 'managerPhone', 'managerEmail', 'comment'];
  const changedFields: string[] = [];

  for (const field of businessFields) {
    const originalValue = original[field as keyof typeof original];
    const currentValue = current[field as keyof typeof current];

    // Сравниваем значения, учитывая null и пустые строки
    const normalizedOriginal = originalValue === null || originalValue === undefined ? '' : String(originalValue).trim();
    const normalizedCurrent = currentValue === null || currentValue === undefined ? '' : String(currentValue).trim();

    if (normalizedOriginal !== normalizedCurrent) {
      changedFields.push(field);
    }
  }

  return changedFields;
}

/**
 * Проверяет, является ли запись запросом на удаление (для обратной совместимости)
 * @param comment - Комментарий записи
 * @returns true если это запрос на удаление
 */
export function isDeleteRequest(comment: string | null | undefined): boolean {
  return comment?.startsWith('[DELETE_REQUEST]') === true;
}

/**
 * Сравнивает два объекта для инвентаря, игнорируя служебные поля
 * @param original - Оригинальный объект записи инвентаря
 * @param current - Текущий объект записи инвентаря
 * @returns Массив ключей бизнес-полей, значения которых отличаются
 */
export function getInventoryChangedFields(
  original: Partial<{
    name: string;
    category: string;
    quantity: string;
    unit: string | null;
    location: string;
    comment: string | null;
    weightPerUnit: string | null;
    manufacturer: string | null;
    model: string | null;
    serialNumber: string | null;
    orderingLink: string | null;
    articleNumber: string | null;
  }>,
  current: Partial<{
    name: string;
    category: string;
    quantity: string;
    unit: string | null;
    location: string;
    comment: string | null;
    weightPerUnit: string | null;
    manufacturer: string | null;
    model: string | null;
    serialNumber: string | null;
    orderingLink: string | null;
    articleNumber: string | null;
  }>
): string[] {
  const businessFields = ['name', 'category', 'quantity', 'unit', 'location', 'comment', 'weightPerUnit', 'manufacturer', 'model', 'serialNumber', 'orderingLink', 'articleNumber'];
  const changedFields: string[] = [];

  for (const field of businessFields) {
    const originalValue = original[field as keyof typeof original];
    const currentValue = current[field as keyof typeof current];

    // Сравниваем значения, учитывая null и пустые строки
    const normalizedOriginal = originalValue === null || originalValue === undefined ? '' : String(originalValue).trim();
    const normalizedCurrent = currentValue === null || currentValue === undefined ? '' : String(currentValue).trim();

    if (normalizedOriginal !== normalizedCurrent) {
      changedFields.push(field);
    }
  }

  return changedFields;
}
