thoughts on this? import { DraggableAndResizable } from "../DOM/DraggableAndResizable";
import { Animate } from "../DOM/Animate";
import { Render } from "../Render/Render";
import { FC } from "../Render/Render";
import { Signal } from "../Kinds/Signal";
import { HTML } from "../DOM/HTML";
import { CSS } from "../DOM/CSS";
import { Box } from "../Kinds/Box";
import { IO } from "../Kinds/IO";

interface WindowPosition extends Partial<CSSStyleDeclaration> {
  right: string;
  top: string;
  width: string;
  height: string;
}

interface WindowSettings {
  pos: WindowPosition;
  minimized: boolean;
}

type Noop = null | undefined | void;

const MIN_W = 20;
const MIN_H = 7;

const windowCSS = CSS({
  background: "rgba(59, 34, 76, 1)",
  border: "1px solid rgba(79, 54, 96, 1)",
  display: "flex",
  flexDirection: "column",
  alignItems: "center",
  justifyContent: "center",
  borderRadius: "0.5rem",
  scrollbarWidth: "none",
  position: "fixed",
  right: "37%",
  top: "20%",
  width: "30%",
  height: "50%",
});

const barCSS = CSS({
  paddingLeft: "0.5rem",
  paddingRight: "0.5rem",
  width: "100%",
  height: "1.4rem",
  minHeight: "1.4rem",
  position: "sticky",
  display: "flex",
  gap: "0.3rem",
  alignItems: "center",
  justifyContent: "flex-end",
  borderTopLeftRadius: "0.5rem",
  borderTopRightRadius: "0.5rem",
});

const contentWrapCSS = CSS({
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  justifyContent: "center",
  width: "100%",
  height: "100%",
  overflow: "hidden",
});

const buttonCSS = CSS({
  display: "flex",
  flexDirection: "column",
  justifyContent: "center",
  alignItems: "center",
  background: "#ECCDBA",
  fontSize: "0.9rem",
  color: "rgba(59, 34, 76, 1)",
  width: "0.9rem",
  height: "0.9rem",
  borderRadius: "50%",
  fontFamily: "monospace",
  userSelect: "none",
  pointerEvents: "auto",
});

const buttonAnimations = Animate(
  {
    event: "pointerover",
    styles: {
      filter: "brightness(85%)",
    },
  },
  {
    event: "pointerout",
    styles: {
      filter: "brightness(100%)",
    },
  },
);

const windowShrink = (pos: WindowPosition, mounted: boolean) =>
  Animate({
    frames: [
      { width: pos.width, height: pos.height, offset: 0 },
      {
        width: `${MIN_W}%`,
        height: `${MIN_H}%`,
        offset: 1,
      },
    ],
    opts: { duration: mounted ? 0 : 200, fill: "forwards" },
    scheduler: mounted ? false : true,
  });

const getPosition = (ref: Box<HTMLElement>) => {
  const pos = ref.ref()?.style;
  if (!pos) return;
  return {
    width: pos.width,
    height: pos.height,
    top: pos.top,
    right: pos.right,
  };
};

const save = (id: string, pos: WindowPosition, minimized: boolean) => {
  localStorage.setItem(`${id}: minimized`, String(minimized));
  localStorage.setItem(`${id}: x`, pos.right);
  localStorage.setItem(`${id}: y`, pos.top);
  localStorage.setItem(`${id}: w`, pos.width);
  localStorage.setItem(`${id}: h`, pos.height);
};

const load = (pos: WindowPosition, id?: string) => {
  if (!id) return { pos: pos, minimized: false };
  return {
    minimized:
      JSON.parse(localStorage.getItem(`${id}: minimized`) as any) ?? false,
    pos: {
      right: localStorage.getItem(`${id}: x`) ?? pos.right,
      top: localStorage.getItem(`${id}: y`) ?? pos.top,
      width: localStorage.getItem(`${id}: w`) ?? pos.width,
      height: localStorage.getItem(`${id}: h`) ?? pos.height,
    },
  } as WindowSettings;
};
const Window: FC<{
  id?: string;
  deps?: any[];
  slot: () => Node | Noop;
  pos: WindowPosition;
}> = ({ id, slot, pos, deps }) => {
  const windowRef = Box<HTMLElement>();
  const position = Box(() => load(pos, id).pos);
  const minimized = Signal(load(pos, id).minimized);
  const rerender = Signal(0);

  const windowSetup = IO(() => {
    return windowRef
      .maybe()
      .map((x) => {
        const draggableWindow = DraggableAndResizable(x, {
          dragZone: 20,
        });

        let width = draggableWindow.style.width;

        const mouseup = () => {
          if (width !== draggableWindow.style.width) {
            width = draggableWindow.style.width;
            position.set(() => getPosition(windowRef) ?? pos);
            rerender.set((x) => x + 1);
          }
        };

        document.addEventListener("pointerup", mouseup);

        const saveSettings = () => {
          if (id) save(id, position.ref() ?? pos, minimized.ref());
        };

        document.addEventListener("visibilitychange", saveSettings);

        return () => {
          saveSettings();
          document.removeEventListener("visibilitychange", saveSettings);
          draggableWindow.extract();
          document.removeEventListener("pointerup", mouseup);
        };
      })
      .else(() => () => {});
  });

  return Render(() => {
    if (id) save(id, position.ref() ?? pos, minimized.ref());
    return HTML(
      "main",
      windowRef,
      windowCSS.concat(
        CSS({
          ...position.ref(),
          pointerEvents: minimized.ref() ? "none" : "auto",
        }),
      ),
      !minimized.ref()
        ? null
        : windowShrink(position.ref() ?? pos, rerender.ref() === 0),
      HTML(
        "header",
        barCSS,
        {
          onpointerup: () => position.set(() => getPosition(windowRef) ?? pos),
        },
        HTML(
          "button",
          buttonCSS,
          buttonAnimations,
          minimized?.ref() ? "\u2212" : "\u2715",
          {
            onpointerdown: () => {
              rerender.set((x) => x + 1);
              minimized.set((x) => !x);
              position.set(() => getPosition(windowRef) ?? pos);
            },
          },
        ),
      ),
      HTML(
        "span",
        minimized.ref()
          ? contentWrapCSS.concat(CSS({ zoom: "55%" }))
          : contentWrapCSS,
        slot() ?? null,
      ),
    );
  }, [windowSetup, minimized, rerender, ...(deps ?? [])]);
};

export { Window };