import { useShallow } from "zustand/shallow";
import useColorStore from "../stores/colorStore";
import domUtil from "../utils/domUtil";
import storageApi, { StorageUploadPayload } from "../apis/storageApi";
import coloredApi, { UpsertPayload } from "../apis/coloredApi";

export default function useColor() {
  const [getWrapper, getCanvas, fullZoom, fitZoom, replaceIsSaved] =
    useColorStore(
      useShallow((state) => [
        state.getWrapper,
        state.getCanvas,
        state.fullZoom,
        state.fitZoom,
        state.replaceIsSaved,
      ])
    );

  const createColoredPreview = async (colored: string) => {
    const wrapper = getWrapper();
    const image = wrapper.querySelector(
      "#illustration"
    ) as HTMLImageElement | null;
    if (!image) throw new Error("Illustration image not found");
    const layers = [image.src, colored];
    return domUtil.combinePngs(layers);
  };

  const createColoredPhoto = async () => {
    fullZoom();
    const canvas = getCanvas();
    const file = await domUtil.canvasToPng(canvas);
    fitZoom();
    return file;
  };

  const saveColored = async (pageId: number, done?: VoidFunction) => {
    const photoResult = await createColoredPhoto();
    const previewResult = await createColoredPreview(photoResult.dataUri);
    const files = [photoResult.file, previewResult.file];
    const upload = (file: File) => {
      const payload: StorageUploadPayload = { file };
      return storageApi.upload(payload);
    };
    const [photo, preview] = await Promise.all(files.map(upload));
    if (!photo || !preview) {
      if (done) done();
      return null;
    }
    const payload: UpsertPayload = {
      pageId,
      photo: photo.url,
      preview: preview.url,
    };
    const result = await coloredApi.upsert(payload);
    if (!result) {
      if (done) done();
      return null;
    }
    replaceIsSaved(true);
    return { photo: photoResult, preview: previewResult, colored: result };
  };

  return { saveColored };
}
