import { PDFDocument } from '@cantoo/pdf-lib';
import { registerFeature } from '../registry';
import { featureModal, pdfSource, footerButtons, deliver, type LoadedFile } from '../common';
import { bufferOf, baseName, parsePageRanges } from '../../core/util';
import { field, textInput } from '../../ui/controls';
import { toast } from '../../ui/toast';
import { h } from '../../core/dom';

registerFeature({
  id: 'remove-pages',
  title: 'Delete pages',
  desc: 'Remove selected pages from a PDF.',
  icon: 'trash',
  category: 'organize',
  run(ctx) {
    let file: LoadedFile | null = null;
    let total = 0;

    const m = featureModal('Delete pages', 'Remove pages you don’t need — nothing is uploaded.', 'trash', 520);

    const countLine = h('p.hint', 'Load a PDF to see its page count.');
    const specField = h('div', { style: { display: 'none' } });

    let spec = '';
    const input = textInput({
      placeholder: 'e.g. 2, 4-6',
      oninput: (v) => { spec = v; updateState(); },
    });
    specField.append(field('Pages to remove', input, 'Use page numbers and ranges, like “2, 4-6”.'));

    m.body.append(
      pdfSource(ctx, {
        multiple: false,
        onChange: async (files) => {
          file = files[0] ?? null;
          total = 0;
          if (file) {
            try {
              const doc = await PDFDocument.load(bufferOf(file.bytes), { ignoreEncryption: true });
              total = doc.getPageCount();
              countLine.textContent = `This PDF has ${total} page${total === 1 ? '' : 's'}.`;
              specField.style.display = '';
            } catch (e) {
              console.error(e);
              countLine.textContent = 'Couldn’t read that PDF — it may be damaged.';
              file = null;
              specField.style.display = 'none';
            }
          } else {
            countLine.textContent = 'Load a PDF to see its page count.';
            specField.style.display = 'none';
          }
          updateState();
        },
      }),
      countLine,
      specField,
    );

    function updateState() {
      if (!file || total === 0) { primary.disabled = true; return; }
      const remove = parsePageRanges(spec, total);
      primary.disabled = remove.length === 0 || remove.length >= total;
    }

    const { primary } = footerButtons(m, 'Remove & download', async () => {
      if (!file || total === 0) return;
      const remove = new Set(parsePageRanges(spec, total));
      if (remove.size === 0) {
        toast('No valid pages to remove.', { type: 'error' });
        return;
      }
      if (remove.size >= total) {
        toast('That would remove every page — keep at least one.', { type: 'error' });
        return;
      }
      const keep: number[] = [];
      for (let i = 0; i < total; i++) if (!remove.has(i)) keep.push(i);

      m.setBusy(true, 'Removing pages…');
      try {
        const src = await PDFDocument.load(bufferOf(file.bytes), { ignoreEncryption: true });
        const out = await PDFDocument.create();
        const pages = await out.copyPages(src, keep);
        pages.forEach((p) => out.addPage(p));
        const bytes = await out.save({ useObjectStreams: true });
        m.close();
        deliver(bytes, baseName(file.name) + '-pages-removed.pdf');
      } catch (e) {
        m.setBusy(false);
        toast('Couldn’t remove pages — the file may be damaged.', { type: 'error' });
        console.error(e);
      }
    }, 'trash');
    primary.disabled = true;
  },
});
