import { PDFDocument, degrees } 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 { toast } from '../../ui/toast';
import { field, segmented, textInput } from '../../ui/controls';
import { h } from '../../core/dom';

registerFeature({
  id: 'rotate-pages',
  title: 'Rotate pages',
  desc: 'Turn pages 90, 180 or 270 degrees.',
  icon: 'rotate',
  category: 'organize',
  run(ctx) {
    let files: LoadedFile[] = [];
    let scope: 'all' | 'custom' = 'all';
    let ranges = '';
    let angle = 90;

    const m = featureModal('Rotate pages', 'Turn pages in place — nothing is uploaded.', 'rotate', 520);

    const rangeInput = textInput({
      placeholder: 'e.g. 1-3, 5, 8-10',
      oninput: (v) => { ranges = v; },
    });
    const rangeField = field('Which pages', rangeInput, 'Use page numbers starting at 1.');
    rangeField.style.display = 'none';

    const scopeControl = segmented({
      options: [
        { value: 'all', label: 'All pages' },
        { value: 'custom', label: 'Custom' },
      ],
      value: 'all',
      onchange: (v) => {
        scope = v as 'all' | 'custom';
        rangeField.style.display = scope === 'custom' ? '' : 'none';
      },
    });

    const angleControl = segmented({
      options: [
        { value: '90', label: '90°' },
        { value: '180', label: '180°' },
        { value: '270', label: '270°' },
      ],
      value: '90',
      onchange: (v) => { angle = parseInt(v, 10); },
    });

    m.body.append(
      pdfSource(ctx, { multiple: false, onChange: (f) => { files = f; primary.disabled = files.length === 0; } }),
      field('Which pages', scopeControl),
      rangeField,
      field('Rotate by', angleControl),
    );

    const { primary } = footerButtons(m, 'Rotate & download', async () => {
      if (files.length === 0) return;
      m.setBusy(true, 'Rotating…');
      try {
        const file = files[0];
        const doc = await PDFDocument.load(bufferOf(file.bytes), { ignoreEncryption: true });
        const pages = doc.getPages();
        const total = pages.length;

        let targets: number[];
        if (scope === 'custom') {
          targets = parsePageRanges(ranges, total);
          if (targets.length === 0) {
            m.setBusy(false);
            toast('No valid pages in that range.', { type: 'error' });
            return;
          }
        } else {
          targets = pages.map((_, i) => i);
        }

        for (const i of targets) {
          const page = pages[i];
          const cur = page.getRotation().angle;
          page.setRotation(degrees((cur + angle) % 360));
        }

        const bytes = await doc.save({ useObjectStreams: true });
        m.close();
        deliver(bytes, baseName(file.name) + '-rotated.pdf');
      } catch (e) {
        m.setBusy(false);
        toast('Rotate failed — the file may be damaged.', { type: 'error' });
        console.error(e);
      }
    }, 'rotate');
    primary.disabled = true;
  },
});
