/**
 * 회계 컴포넌트 공통 패턴
 *
 * SalesManagement, DepositManagement, WithdrawalManagement, BillManagement 등
 * 회계 목록 컴포넌트에서 반복되는 로직을 추출한 유틸리티 모음
 */

import { toast } from 'sonner';

// ===== 1. 삭제 핸들러 팩토리 (4파일 동일) =====

/**
 * UniversalListPage의 deleteItem 핸들러를 생성합니다.
 *
 * @example
 * deleteItem: createDeleteItemHandler(deleteSale, setSalesData, '매출이 삭제되었습니다.'),
 */
export function createDeleteItemHandler<T extends { id: string }>(
  deleteAction: (id: string) => Promise<{ success: boolean; error?: string }>,
  setData: React.Dispatch<React.SetStateAction<T[]>>,
  successMessage: string
) {
  return async (id: string) => {
    const result = await deleteAction(id);
    if (result.success) {
      setData(prev => prev.filter(item => item.id !== id));
      toast.success(successMessage);
    }
    return { success: result.success, error: result.error };
  };
}

// ===== 2. 거래처 옵션 추출 (5파일 동일) =====

/**
 * 데이터 배열에서 고유한 값을 추출하여 Select 옵션으로 변환합니다.
 *
 * @example
 * const vendorOptions = useMemo(() => extractUniqueOptions(data, 'vendorName'), [data]);
 */
export function extractUniqueOptions<T>(
  data: T[],
  fieldKey: keyof T,
  options?: { includeAll?: boolean; allLabel?: string }
): { value: string; label: string }[] {
  const { includeAll = true, allLabel = '전체' } = options ?? {};

  const uniqueValues = [...new Set(
    data
      .map(item => {
        const val = item[fieldKey];
        return typeof val === 'string' ? val.trim() : '';
      })
      .filter(v => v !== '')
  )];

  const items = uniqueValues.map(v => ({ value: v, label: v }));

  if (includeAll) {
    return [{ value: 'all', label: allLabel }, ...items];
  }
  return items;
}

// ===== 3. 날짜+금액 정렬 팩토리 (5파일 유사) =====

export type SortDirection = 'latest' | 'oldest' | 'amountHigh' | 'amountLow';

/**
 * 날짜+금액 기준 정렬 함수를 생성합니다.
 *
 * @example
 * customSortFn: (items) => createDateAmountSortFn('salesDate', 'totalAmount', sortOption)(items),
 */
export function createDateAmountSortFn<T>(
  dateField: keyof T,
  amountField: keyof T,
  direction: SortDirection
): (items: T[]) => T[] {
  return (items: T[]) => {
    const sorted = [...items];
    switch (direction) {
      case 'oldest':
        sorted.sort((a, b) =>
          new Date(String(a[dateField])).getTime() - new Date(String(b[dateField])).getTime()
        );
        break;
      case 'amountHigh':
        sorted.sort((a, b) =>
          ((b[amountField] as number) ?? 0) - ((a[amountField] as number) ?? 0)
        );
        break;
      case 'amountLow':
        sorted.sort((a, b) =>
          ((a[amountField] as number) ?? 0) - ((b[amountField] as number) ?? 0)
        );
        break;
      default: // latest
        sorted.sort((a, b) =>
          new Date(String(b[dateField])).getTime() - new Date(String(a[dateField])).getTime()
        );
        break;
    }
    return sorted;
  };
}

// ===== 4. 당월 합계 계산 (3파일 동일) =====

/**
 * 데이터 배열에서 현재 월에 해당하는 금액 합계를 계산합니다.
 *
 * @example
 * const monthlyAmount = computeMonthlyTotal(data, 'salesDate', 'totalAmount');
 */
export function computeMonthlyTotal<T>(
  data: T[],
  dateField: keyof T,
  amountField: keyof T
): number {
  const now = new Date();
  const currentMonth = now.getMonth();
  const currentYear = now.getFullYear();

  return data
    .filter(item => {
      const date = new Date(String(item[dateField]));
      return date.getMonth() === currentMonth && date.getFullYear() === currentYear;
    })
    .reduce((sum, item) => sum + (((item[amountField]) as number) ?? 0), 0);
}
