import QRCode from "qrcode";

type QrParticipant = {
  registrationReference: string;
  firstName: string;
  middleName: string | null;
  lastName: string;
  company: string | null;
  participantCategory: string;
};

type QrCredential = {
  id: string;
  tokenHash: string;
  issuedAt: Date;
};

export function participantName(participant: QrParticipant) {
  return [participant.firstName, participant.middleName, participant.lastName].filter(Boolean).join(" ");
}

export function qrPayload(participant: QrParticipant, credential: QrCredential) {
  return JSON.stringify({
    type: "PMAP_AC2026_PARTICIPANT_QR",
    reference: participant.registrationReference,
    credentialId: credential.id,
    tokenHash: credential.tokenHash,
    issuedAt: credential.issuedAt.toISOString()
  });
}

function escapeSvgText(value: string) {
  return value
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll("\"", "&quot;");
}

function addReferenceLabel(svg: string, reference: string) {
  const viewBox = svg.match(/viewBox="0 0 ([\d.]+) ([\d.]+)"/);
  const width = Number(viewBox?.[1] ?? 65);
  const height = Number(viewBox?.[2] ?? 65);
  const labelHeight = 13;
  const labeledHeight = height + labelHeight;
  const labeledSvg = svg
    .replace(/width="420"\s+height="420"/, "width=\"420\" height=\"500\"")
    .replace(/viewBox="0 0 ([\d.]+) ([\d.]+)"/, `viewBox="0 0 ${width} ${labeledHeight}"`);
  const label = [
    `<rect x="0" y="${height}" width="${width}" height="${labelHeight}" fill="#ffffff"/>`,
    `<text x="${width / 2}" y="${height + 8.5}" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="4.2" font-weight="700" fill="#0f172a">${escapeSvgText(reference)}</text>`
  ].join("");
  return labeledSvg.replace("</svg>", `${label}</svg>`);
}

export async function createQrSvg(participant: QrParticipant, credential: QrCredential) {
  const svg = await QRCode.toString(qrPayload(participant, credential), {
    type: "svg",
    errorCorrectionLevel: "M",
    margin: 2,
    width: 420
  });
  return addReferenceLabel(svg, participant.registrationReference);
}
