import { PDFDocument } from '@pdfme/pdf-lib';
import type {
  DocumentLibraryBrand,
  DocumentLibraryProductType,
} from '@/features/foundation/document-library/types';
import type { AssemblySourcePolicy, ResolvedAssemblySource } from '../types';

export function normalizeAssemblyBrand(
  value: string | null | undefined,
): DocumentLibraryBrand {
  const normalized = String(value ?? '')
    .trim()
    .toLowerCase();

  if (normalized === 'alla') {
    return 'alla';
  }

  if (normalized === 'onvalla') {
    return 'onvalla';
  }

  return 'generic';
}

export function normalizeAssemblyProductType(
  value: string | null | undefined,
): DocumentLibraryProductType {
  const normalized = String(value ?? '')
    .trim()
    .toLowerCase();

  if (normalized === 'crane') {
    return 'crane';
  }

  if (normalized === 'dockdoor' || normalized === 'dock_door') {
    return 'dock_door';
  }

  if (normalized === 'solarcell' || normalized === 'solar') {
    return 'solar';
  }

  if (normalized === 'service') {
    return 'service';
  }

  return 'all';
}

export function validateAssemblySourceOrdering(sources: AssemblySourcePolicy[]) {
  const seenOrders = new Set<number>();

  for (const source of sources) {
    if (seenOrders.has(source.order)) {
      throw new Error(`Duplicate assembly source order: ${source.order}`);
    }

    seenOrders.add(source.order);
  }
}

export async function getPdfPageCount(buffer: Buffer, label: string) {
  try {
    const document = await PDFDocument.load(buffer);
    return document.getPageCount();
  } catch {
    throw new Error(`${label} is not a readable PDF document.`);
  }
}

export async function mergePdfBuffers(sources: ResolvedAssemblySource[]) {
  const merged = await PDFDocument.create();

  for (const source of sources) {
    const document = await PDFDocument.load(source.buffer);
    const pages = await merged.copyPages(
      document,
      document.getPageIndices(),
    );

    for (const page of pages) {
      merged.addPage(page);
    }
  }

  return Buffer.from(await merged.save());
}
