import { useEffect, useState } from "react";

import { useTheme } from "@methanium/ui";
import { useIsSpeaking } from "@tensamin/call/speakingState";
import { useCall, useInitializeCall } from "@tensamin/call/store";
import { useStorage } from "@tensamin/storage/context";

function createCallTrayIcon(color: string, speaking: boolean) {
  const canvas = document.createElement("canvas");
  canvas.width = 32;
  canvas.height = 32;

  const context = canvas.getContext("2d");
  if (!context) return undefined;

  context.globalAlpha = speaking ? 1 : 0.55;
  context.fillStyle = color;
  context.beginPath();
  context.arc(16, 16, 13, 0, Math.PI * 2);
  context.fill();

  if (speaking) {
    context.globalAlpha = 0.3;
    context.fillStyle = "#ffffff";
    context.fill();
  }

  return canvas.toDataURL("image/png");
}

export default function CallRuntimeInit() {
  const callInvitePopup = useInitializeCall();
  const { load } = useStorage();
  const {
    themeColor,
    themePalette,
    themePrimaryColor,
    themePolarity,
    themeTint,
    themeCustomCss,
  } = useTheme();
  const [localUserId, setLocalUserId] = useState(-1);
  const [primaryColor, setPrimaryColor] = useState("");
  const inCall = useCall((state) => state.state === "open");
  const speaking = useIsSpeaking(localUserId);

  useEffect(() => {
    let active = true;

    load("user_id").then((userId) => {
      if (active) setLocalUserId(userId);
    });

    return () => {
      active = false;
    };
  }, [load]);

  useEffect(() => {
    const frame = requestAnimationFrame(() => {
      setPrimaryColor(
        getComputedStyle(document.documentElement)
          .getPropertyValue("--primary")
          .trim(),
      );
    });

    return () => cancelAnimationFrame(frame);
  }, [
    themeColor,
    themeCustomCss,
    themePalette,
    themePolarity,
    themePrimaryColor,
    themeTint,
  ]);

  useEffect(() => {
    const iconDataUrl = primaryColor
      ? createCallTrayIcon(primaryColor, speaking)
      : undefined;

    void window.tensaminDesktop?.call
      ?.setStatus?.({
        inCall,
        speaking: inCall && speaking,
        iconDataUrl: inCall ? iconDataUrl : undefined,
      })
      .catch((error: unknown) => {
        console.error("Failed to update desktop call status", error);
      });
  }, [inCall, primaryColor, speaking]);

  return callInvitePopup;
}
