// src/client/entities/contractor/model/mergeHelpers.ts
// Smart merge helper functions for contractor entries

import type { ContractorEntry } from '@shared/contracts/contractors';
import type { ContractorPendingEntryResponse } from '../../../shared/api/repositories/ContractorsRepository';

/**
 * Patch entries array: update existing items or add new ones
 */
export function patchEntries(
  currentEntries: ContractorEntry[],
  newEntries: ContractorEntry[]
): ContractorEntry[] {
  const map = new Map(currentEntries.map(e => [e.id, e]));
  
  for (const entry of newEntries) {
    map.set(entry.id, entry);
  }
  
  // Convert back to array and sort by createdAt
  return Array.from(map.values()).sort(
    (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
  );
}

/**
 * Patch pending entries array
 */
export function patchPendingEntries(
  currentPending: ContractorPendingEntryResponse[],
  newPending: ContractorPendingEntryResponse[]
): ContractorPendingEntryResponse[] {
  const map = new Map(currentPending.map(e => [e.id, e]));
  
  for (const entry of newPending) {
    map.set(entry.id, entry);
  }
  
  return Array.from(map.values()).sort(
    (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
  );
}

/**
 * Smart patch for a single entry (handles moving between lists)
 * CRITICAL: Removes entry from pending list if it becomes approved
 */
export function patchEntry(
  entries: ContractorEntry[],
  pendingEntries: ContractorPendingEntryResponse[],
  entry: any // Accepting any to handle both types and backend responses
): { entries: ContractorEntry[], pendingEntries: ContractorPendingEntryResponse[] } {
  let newEntries = [...entries];
  let newPending = [...pendingEntries];

  // Проверяем, является ли запись "ожидающей" (pending/to_delete или есть targetId)
  // Backend может вернуть status='pending' или status='to_delete'
  const isPending = entry.status === 'pending' || entry.status === 'to_delete' || entry.targetId;

  if (isPending) {
    // 1. Это Pending запись: обновляем/добавляем в pendingEntries
    const index = newPending.findIndex(e => e.id === entry.id);
    if (index !== -1) {
      newPending[index] = entry;
    } else {
      newPending.push(entry);
    }
    // В entries мы её НЕ трогаем, unifiedList сам скроет оригинал по targetId
  } else {
    // 2. Это Одобренная запись (Approved):
    // а) Обновляем/Добавляем в entries
    const index = newEntries.findIndex(e => e.id === entry.id);
    if (index !== -1) {
      newEntries[index] = entry;
    } else {
      newEntries.push(entry);
    }

    // б) КРИТИЧНО: Удаляем из pendingEntries, если она там была (например, после аппрува)
    // Ищем по id или по targetId (если это был черновик редактирования)
    // Это и есть фикс "дублей" после согласования
    newPending = newPending.filter(p => p.id !== entry.id && p.targetId !== entry.id);
  }

  return { entries: newEntries, pendingEntries: newPending };
}

/**
 * Remove entry from both lists
 */
export function removeEntry(
  entries: ContractorEntry[],
  pendingEntries: ContractorPendingEntryResponse[],
  id: string
): { entries: ContractorEntry[], pendingEntries: ContractorPendingEntryResponse[] } {
  // Удаляем из entries
  const newEntries = entries.filter(e => e.id !== id);
  
  // Удаляем из pendingEntries (и по ID, и по targetId, если мы удалили оригинал)
  const newPending = pendingEntries.filter(p => p.id !== id && p.targetId !== id);

  return { entries: newEntries, pendingEntries: newPending };
}
