import { h } from '../core/dom';
import { icon } from './icons';

export interface DropzoneOptions {
  accept?: string; // e.g. 'application/pdf' or 'image/*'
  multiple?: boolean;
  label?: string;
  hint?: string;
  compact?: boolean;
  onFiles: (files: File[]) => void;
}

/** A drag-and-drop + click-to-browse file target styled as glass. */
export function dropzone(opts: DropzoneOptions): HTMLElement {
  const input = h('input', {
    type: 'file',
    accept: opts.accept ?? '',
    multiple: !!opts.multiple,
    style: { display: 'none' },
    onchange: () => {
      if (input.files && input.files.length) opts.onFiles(Array.from(input.files));
      input.value = '';
    },
  }) as HTMLInputElement;

  const zone = h(
    `div.dropzone${opts.compact ? ' dropzone-compact' : ''}`,
    { tabindex: '0', role: 'button' },
    h('div.dropzone-icon', icon('upload', opts.compact ? 24 : 34)),
    h('div.dropzone-label', opts.label ?? 'Drop a PDF here or click to browse'),
    opts.hint ? h('div.dropzone-hint', opts.hint) : null,
    input,
  );

  const open = () => input.click();
  zone.addEventListener('click', open);
  zone.addEventListener('keydown', (e) => {
    if ((e as KeyboardEvent).key === 'Enter' || (e as KeyboardEvent).key === ' ') {
      e.preventDefault();
      open();
    }
  });
  let depth = 0;
  zone.addEventListener('dragenter', (e) => { e.preventDefault(); depth++; zone.classList.add('drag'); });
  zone.addEventListener('dragover', (e) => e.preventDefault());
  zone.addEventListener('dragleave', () => { if (--depth <= 0) { depth = 0; zone.classList.remove('drag'); } });
  zone.addEventListener('drop', (e) => {
    const ev = e as DragEvent;
    ev.preventDefault();
    depth = 0;
    zone.classList.remove('drag');
    const files = ev.dataTransfer?.files;
    if (files && files.length) {
      let list: File[] = Array.from(files);
      if (opts.accept?.includes('pdf')) list = list.filter((f) => /\.pdf$/i.test(f.name) || f.type === 'application/pdf');
      if (list.length) opts.onFiles(opts.multiple ? list : [list[0]]);
    }
  });
  return zone;
}

/** Promise-based file picker (no visible element needed). */
export function pickFiles(accept = '', multiple = false): Promise<File[]> {
  return new Promise((resolve) => {
    const input = h('input', { type: 'file', accept, multiple, style: { display: 'none' } }) as HTMLInputElement;
    input.addEventListener('change', () => {
      resolve(input.files ? Array.from(input.files) : []);
      input.remove();
    });
    // Some browsers need it in the DOM
    document.body.appendChild(input);
    input.click();
  });
}
