/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
/// <reference lib="dom" />

import { pdfConverter } from "../scrapbox-pdftoimage/mod.ts";
import { upload as uploadFile } from "../scrapbox-file-uploader/mod.ts";
import { getGyazoToken } from "jsr:@cosense/std@0.29/rest";
import { upload } from "jsr:@takker/gyazo@0.4";
import { range } from "jsr:@core/iterutil@0.9/range";
import { map } from "jsr:@core/iterutil@0.9/async/map";
import { pooledMap } from "jsr:@std/async@1/pool";
import { getUnixTime } from "npm:date-fns@4/getUnixTime";
import { isErr, unwrapErr, unwrapOk } from "npm:option-t@51/plain_result";

export interface Props {
  title?: string;
  refererURL?: string;
  /** @default {300} */
  printResolution?: number;
  /** @default {1} */
  start?: number;
};

export async function* uploadPDF(props: Props): AsyncGenerator<{ index: number; count: number; }> {
  // 読み込み
  const file = await uploadFile({ accept: "application/pdf, *.pdf"});
  if (!file) throw new Error("no file specified");
  
  // access token取得
  const result = await getGyazoToken();
  if (isErr(result)) throw new Error(JSON.stringify(unwrapErr(result)));
  const accessToken = unwrapOk(result);
  if (!accessToken) throw new Error("Could not get the access token");
  
  // 画像に変換する
  const { convert, count } = await pdfConverter(new Uint8Array(await file.arrayBuffer()));
  yield* map(
    range(props?.start ?? 1, count),
    async (index: number) => {
      const image = await convert(index, {
        mimeType: "image/jpeg",
        printResolution: props?.printResolution ?? 300,
        quality: 0.95,
      });
      const res = await upload(image, {
        created: getUnixTime(new Date()),
        accessToken,
        description: `${file.name} ${index}`,
        ...props,
      });
      if (!res.ok) throw new Error("gyazo error", { cause: res });
      return { index, count, ...(await res.json())};
  });
}