const EMPTY_TABLE_FALLBACK = [['-']];

function normalizeNumber(
  amount: number | string | null | undefined
): number | null {
  if (typeof amount === 'number' && Number.isFinite(amount)) {
    return amount;
  }

  if (typeof amount === 'string') {
    const normalized = Number(amount.replaceAll(',', '').trim());
    return Number.isFinite(normalized) ? normalized : null;
  }

  return null;
}

export function formatPdfDate(
  dateString: string | Date | null | undefined,
  language: 'th' | 'en' = 'en'
): string {
  if (!dateString) {
    return '-';
  }

  const date = dateString instanceof Date ? dateString : new Date(dateString);

  if (Number.isNaN(date.getTime())) {
    return '-';
  }

  if (language === 'th') {
    return date.toLocaleDateString('th-TH', {
      day: 'numeric',
      month: 'short',
      year: 'numeric',
      calendar: 'buddhist'
    });
  }

  return date.toLocaleDateString('en-US', {
    day: 'numeric',
    month: 'short',
    year: 'numeric'
  });
}

export function formatPdfCurrency(
  amount: number | string | null | undefined,
  currencyCode = 'THB'
): string {
  const numericAmount = normalizeNumber(amount);

  if (numericAmount === null) {
    return '-';
  }

  const normalizedCode = currencyCode.toUpperCase();
  const symbols: Record<string, string> = {
    THB: 'THB ',
    USD: '$',
    EUR: 'EUR '
  };
  const symbol = symbols[normalizedCode] ?? `${normalizedCode} `;
  const formatted = new Intl.NumberFormat('en-US', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(numericAmount);

  return `${symbol}${formatted}`.trim();
}

export function formatTopicItems(topic?: {
  items?: Array<{ content?: string | null; sortOrder?: number | null }> | string[];
}): string[][] {
  if (!topic?.items?.length) {
    return EMPTY_TABLE_FALLBACK;
  }

  const rows = [...topic.items]
    .sort((left, right) => {
      if (typeof left === 'string' || typeof right === 'string') {
        return 0;
      }

      return (left.sortOrder ?? Number.MAX_SAFE_INTEGER) - (right.sortOrder ?? Number.MAX_SAFE_INTEGER);
    })
    .map((item) => {
      if (typeof item === 'string') {
        return item.trim() || '-';
      }

      return item?.content?.trim() || '-';
    })
    .filter(Boolean)
    .map((content) => [content]);

  return rows.length ? rows : EMPTY_TABLE_FALLBACK;
}

export function normalizePdfmeTable(
  value: unknown,
  columns?: Array<{ sourceField: string; formatMask?: string | null }>
): string[][] {
  if (!Array.isArray(value) || value.length === 0) {
    return EMPTY_TABLE_FALLBACK;
  }

  if (value.every((row) => Array.isArray(row))) {
    const normalizedRows = value.map((row) =>
      (row as unknown[]).map((cell) => {
        const stringValue = String(cell ?? '').trim();
        return stringValue || '-';
      })
    );

    return normalizedRows.length ? normalizedRows : EMPTY_TABLE_FALLBACK;
  }

  if (!columns?.length) {
    return value.map((row) => [String(row ?? '').trim() || '-']) || EMPTY_TABLE_FALLBACK;
  }

  const rows = value.map((row) => {
    const rowRecord = row as Record<string, unknown>;

    return columns.map((column) => {
      const cell = rowRecord[column.sourceField];

      if (typeof cell === 'number' || typeof cell === 'string') {
        return String(cell).trim() || '-';
      }

      if (cell === null || cell === undefined) {
        return '-';
      }

      return String(cell).trim() || '-';
    });
  });

  return rows.length ? rows : EMPTY_TABLE_FALLBACK;
}
