import fs from 'fs';
import path from 'path';

const today = '22 de junio de 2026';

const docs = [
  {
    outPath: path.resolve('PRECONVERSION_OEPM_FARMAFINDER.pdf'),
    title: 'DOCUMENTO DE PRECONVERSION',
    subtitle: 'Hoja de preparacion para expediente de patente',
    pages: [
      [
        { type: 'cover' },
      ],
      [
        { type: 'heading', text: '1. Identificacion del expediente' },
        { type: 'paragraph', text: 'Solicitante: Antoni Nuñez Romeu' },
        { type: 'paragraph', text: 'NIF/NIE/DNI: 45858029P' },
        { type: 'paragraph', text: 'Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221' },
        { type: 'paragraph', text: 'Titulo de la invencion: Sistema y procedimiento implementados por ordenador para la identificacion de necesidades terapeuticas mediante escaneo de tarjeta sanitaria individual, contraste con stock farmacutico geolocalizado y generacion de acciones de suministro.' },
        { type: 'heading', text: '2. Objeto de este documento' },
        { type: 'paragraph', text: 'Este documento se emite como hoja interna de preparacion y control del expediente antes de su presentacion ante la Oficina Española de Patentes y Marcas (OEPM). Su finalidad es reunir en un unico soporte los datos de identificacion, la referencia del objeto tecnico y la declaracion de que la documentacion principal del expediente ha sido preparada para su presentacion.' },
        { type: 'heading', text: '3. Contenido del expediente' },
        { type: 'bullet', text: 'Solicitud de patente.' },
        { type: 'bullet', text: 'Memoria descriptiva.' },
        { type: 'bullet', text: 'Reivindicaciones.' },
        { type: 'bullet', text: 'Resumen.' },
        { type: 'bullet', text: 'Anexo de dibujos.' },
        { type: 'bullet', text: 'Solicitud de reduccion de tasas para persona fisica.' },
        { type: 'heading', text: '4. Declaracion' },
        { type: 'paragraph', text: 'El solicitante declara que la documentacion aportada se corresponde con una unica invencion, que la descripcion y las reivindicaciones han sido redactadas de forma coherente y que el material adjunto se presenta a efectos de tramitacion ante la OEPM.' },
        { type: 'heading', text: '5. Firma' },
        { type: 'paragraph', text: `En Terrassa, a ${today}.` },
        { type: 'paragraph', text: 'Fdo.: Antoni Nuñez Romeu' },
        { type: 'paragraph', text: 'DNI/NIF: 45858029P' },
        { type: 'paragraph', text: 'Documento de apoyo interno. Revisar con agente de propiedad industrial antes de presentar.' },
      ],
    ],
  },
  {
    outPath: path.resolve('REDUCCION_TASAS_OEPM_PERSONA_FISICA.pdf'),
    title: 'SOLICITUD DE REDUCCION DE TASAS',
    subtitle: 'Persona fisica',
    pages: [
      [
        { type: 'cover' },
      ],
      [
        { type: 'heading', text: '1. Datos del solicitante' },
        { type: 'paragraph', text: 'Nombre y apellidos: Antoni Nuñez Romeu' },
        { type: 'paragraph', text: 'DNI/NIF: 45858029P' },
        { type: 'paragraph', text: 'Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221' },
        { type: 'heading', text: '2. Expediente al que se refiere' },
        { type: 'paragraph', text: 'Titulo de la invencion: Sistema y procedimiento implementados por ordenador para la identificacion de necesidades terapeuticas mediante escaneo de tarjeta sanitaria individual, contraste con stock farmacutico geolocalizado y generacion de acciones de suministro.' },
        { type: 'heading', text: '3. Solicitud' },
        { type: 'paragraph', text: 'Por medio del presente escrito, el solicitante, en su condicion de persona fisica, solicita que se le aplique la reduccion de tasas que resulte procedente conforme a la normativa vigente de la Oficina Española de Patentes y Marcas (OEPM) para personas fisicas.' },
        { type: 'paragraph', text: 'A tal efecto, manifiesta que la solicitud de patente se presenta a su nombre como persona fisica y pide que la oficina tramite esta peticion de conformidad con los requisitos y porcentajes de reduccion establecidos en la normativa aplicable al momento de la presentacion.' },
        { type: 'heading', text: '4. Declaracion responsable' },
        { type: 'paragraph', text: 'El solicitante declara bajo su responsabilidad que los datos consignados en este documento son ciertos y que aportara, en su caso, la documentacion adicional que la OEPM pudiera requerir para acreditar la condicion de persona fisica y la procedencia de la reduccion solicitada.' },
        { type: 'heading', text: '5. Firma' },
        { type: 'paragraph', text: `En Terrassa, a ${today}.` },
        { type: 'paragraph', text: 'Fdo.: Antoni Nuñez Romeu' },
        { type: 'paragraph', text: 'DNI/NIF: 45858029P' },
        { type: 'paragraph', text: 'Nota: revisar con agente o con la OEPM el formulario exacto y los requisitos vigentes antes de presentar.' },
      ],
    ],
  },
];

const PAGE_W = 595.28;
const PAGE_H = 841.89;
const MARGIN_L = 56;
const MARGIN_R = 56;
const MARGIN_T = 58;
const MARGIN_B = 52;
const CONTENT_W = PAGE_W - MARGIN_L - MARGIN_R;

function esc(s) {
  return String(s).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
}

function wrapText(text, maxChars) {
  const words = String(text).split(/\s+/);
  const lines = [];
  let line = '';
  for (const word of words) {
    const candidate = line ? `${line} ${word}` : word;
    if (candidate.length > maxChars && line) {
      lines.push(line);
      line = word;
    } else {
      line = candidate;
    }
  }
  if (line) lines.push(line);
  return lines;
}

function buildPdf({ title, subtitle, pages, outPath }) {
  const objects = [''];
  const pagesObjNums = [];
  const contentObjNums = [];

  function addObject(bodyText) {
    objects.push(bodyText);
    return objects.length - 1;
  }

  const f1 = addObject('<< /Type /Font /Subtype /Type1 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >>');
  const f2 = addObject('<< /Type /Font /Subtype /Type1 /BaseFont /Times-Bold /Encoding /WinAnsiEncoding >>');
  const f3 = addObject('<< /Type /Font /Subtype /Type1 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >>');

  function renderPage(pageNo, items, isCover = false) {
    const ops = [];
    let y = PAGE_H - MARGIN_T;
    let numbering = 1;

    const write = (txt, x, size, font = 'F1') => {
      ops.push(`BT /${font} ${size} Tf ${x} ${y} Td (${esc(txt)}) Tj ET`);
      y -= size * 1.28;
    };

    const drawLine = () => {
      y -= 4;
      ops.push(`0.2 w ${MARGIN_L} ${y} m ${PAGE_W - MARGIN_R} ${y} l S`);
      y -= 10;
    };

    if (isCover) {
      write(title, MARGIN_L + 70, 18, 'F2');
      y -= 6;
      write('Oficina Española de Patentes y Marcas (OEPM)', MARGIN_L + 55, 12, 'F1');
      y -= 16;
      write(subtitle, MARGIN_L + 80, 12, 'F3');
      y -= 12;
      ops.push(`0.8 w ${MARGIN_L} ${y - 66} ${CONTENT_W} 66 re S`);
      write('Solicitante: Antoni Nuñez Romeu', MARGIN_L + 10, 11, 'F1');
      write('DNI/NIF: 45858029P', MARGIN_L + 10, 11, 'F1');
      write('Domicilio: C/ Font Vella 12, 1, Terrassa, Barcelona, 08221', MARGIN_L + 10, 11, 'F1');
      write('Inventor: Antoni Nuñez Romeu', MARGIN_L + 10, 11, 'F1');
      y -= 8;
      write('Documento de apoyo para expediente de patente', MARGIN_L + 70, 10, 'F3');
      return ops.join('\n');
    }

    for (const item of items) {
      if (item.type === 'heading') {
        write(item.text, MARGIN_L, 13, 'F2');
        drawLine();
        continue;
      }
      if (item.type === 'paragraph') {
        const lines = wrapText(item.text, 82);
        for (const line of lines) write(line, MARGIN_L, 11.2, 'F1');
        y -= 1;
        continue;
      }
      if (item.type === 'bullet') {
        const lines = wrapText(item.text, 78);
        let first = true;
        for (const line of lines) {
          write((first ? '• ' : '  ') + line, MARGIN_L + 8, 11.1, 'F1');
          first = false;
        }
        continue;
      }
      if (item.type === 'number') {
        const lines = wrapText(item.text, 76);
        let first = true;
        for (const line of lines) {
          write((first ? `${numbering}. ` : '   ') + line, MARGIN_L + 8, 11.1, 'F1');
          first = false;
        }
        numbering += 1;
        continue;
      }
    }

    write(`Pagina ${pageNo}`, PAGE_W - 100, 9, 'F1');
    return ops.join('\n');
  }

  const pageContents = pages.map((items, idx) => renderPage(idx + 1, items, idx === 0 && items.length === 1 && items[0].type === 'cover'));

  for (const content of pageContents) {
    const stream = `<< /Length ${Buffer.byteLength(content, 'latin1')} >>\nstream\n${content}\nendstream`;
    contentObjNums.push(addObject(stream));
  }

  const pagesTree = addObject('');
  for (let i = 0; i < pageContents.length; i++) {
    const pageObj = addObject(`<< /Type /Page /Parent ${pagesTree} 0 R /MediaBox [0 0 ${PAGE_W} ${PAGE_H}] /Resources << /Font << /F1 ${f1} 0 R /F2 ${f2} 0 R /F3 ${f3} 0 R >> >> /Contents ${contentObjNums[i]} 0 R >>`);
    pagesObjNums.push(pageObj);
  }
  objects[pagesTree] = `<< /Type /Pages /Kids [${pagesObjNums.map(n => `${n} 0 R`).join(' ')}] /Count ${pagesObjNums.length} >>`;
  const catalog = addObject(`<< /Type /Catalog /Pages ${pagesTree} 0 R >>`);

  let pdf = '%PDF-1.4\n';
  const offsets = [0];
  for (let i = 1; i < objects.length; i++) {
    offsets[i] = Buffer.byteLength(pdf, 'latin1');
    pdf += `${i} 0 obj\n${objects[i]}\nendobj\n`;
  }
  const xref = Buffer.byteLength(pdf, 'latin1');
  pdf += `xref\n0 ${objects.length}\n`;
  pdf += '0000000000 65535 f \n';
  for (let i = 1; i < objects.length; i++) {
    pdf += `${String(offsets[i]).padStart(10, '0')} 00000 n \n`;
  }
  pdf += `trailer << /Size ${objects.length} /Root ${catalog} 0 R >>\nstartxref\n${xref}\n%%EOF\n`;
  fs.writeFileSync(outPath, Buffer.from(pdf, 'latin1'));
}

for (const doc of docs) {
  buildPdf(doc);
  console.log(`Wrote ${doc.outPath}`);
}
