import { forceArgs } from "../cli/forceArgs.ts";
import { TerminalBlock } from "../cli/TerminalLayout.ts";
import { loadPdfForm } from "util/saveLoadPdf.ts";
import type { ITool } from "../types.ts";
import { InputManager } from "../cli/InputManager.ts";

export class ListFormFields implements ITool {
  name = "listformfields";
  description = "Lists fields in a PDF form";
  block?: TerminalBlock;
  async run(pdfPath: string = "") {
    if (!this.block) {
      this.block = new TerminalBlock();
    }
    this.block.setPreserveHistory(false);
    [pdfPath] = await forceArgs([pdfPath], [[
      "Please provide path to PDF:",
      (p) => !!p && p.endsWith(".pdf"),
    ]], this.block);
    const lines = [pdfPath];
    let rLines: string[] = [];

    const form = await loadPdfForm(pdfPath);
    const fields = form.getFields();
    const fieldNames = fields.map((f) => f.getName());

    let offset = 0;

    const buildRLines = () => {
      rLines = fieldNames.slice(offset, this.block!.getRenderHeight());
      this.block!.setLines(lines.concat(rLines), [0, 1]);
    };
    buildRLines();

    await new Promise<void>((res) => {
      const im = InputManager.getInstance();
      const up = () => {
        if (fieldNames.length < this.block!.getRenderHeight() - 1) return;
        offset = Math.max(0, offset - 1);
        buildRLines();
      };
      const down = () => {
        if (fieldNames.length < this.block!.getRenderHeight() - 1) return;
        offset = Math.min(fieldNames.length, offset + 1);
        buildRLines();
      };
      const enter = () => {
        res();
        im.removeEventListener("arrow-up", up);
        im.removeEventListener("arrow-down", down);
        im.removeEventListener("enter", enter);
      };
      im.addEventListener("arrow-up", up);
      im.addEventListener("arrow-down", down);
      im.addEventListener("enter", enter);
    });
  }
  setBlock(terminalBlock: TerminalBlock) {
    this.block = terminalBlock;
  }
}

export default new ListFormFields();
