import { forceArgs } from "../cli/forceArgs.ts";
import { cliAlert } from "../cli/prompts.ts";
import { TerminalBlock } from "../cli/TerminalLayout.ts";
import { loadPdfForm } from "util/saveLoadPdf.ts";
import type { ITool } from "../types.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(true);
    [pdfPath] = await forceArgs([pdfPath], [[
      "Please provide path to PDF:",
      (p) => !!p && p.endsWith(".pdf"),
    ]], this.block);

    const form = await loadPdfForm(pdfPath);
    const fields = form.getFields();
    const height = this.block.getRenderHeight() - 1;
    const fieldNames = fields.sort((a, b) => {
      const aRect = a.acroField.getWidgets().find((e) => e.Rect())?.Rect()
        ?.asRectangle();
      const bRect = b.acroField.getWidgets().find((e) => e.Rect())?.Rect()
        ?.asRectangle();

      if (aRect && bRect) {
        if (aRect.x !== bRect.x) {
          return aRect.x - bRect.x; // Sort left to right
        } else {
          return bRect.y - aRect.y; // If x is equal, sort top to bottom
        }
      }
      return a.getName().localeCompare(b.getName());
    }).map((f) => f.getName());
    const maxLength = Math.max(...fieldNames.map((f) => f.length)) + 4;
    const lines = [];
    for (let i = 0; i < height; i++) {
      let line = "";
      for (let j = 0; j < fieldNames.length; j += height) {
        const fieldName = fieldNames[i + j] ?? "";
        line += fieldName.padEnd(maxLength, " ");
      }
      lines.push(line);
    }
    this.block.setLines(lines, [0, 1]);
    await cliAlert("", this.block);
  }
  setBlock(terminalBlock: TerminalBlock) {
    this.block = terminalBlock;
  }
}

export default new ListFormFields();
