import { useCallback, useContext, useMemo } from "react";
import { IOConnectDesktop } from "@interopio/desktop";
import { IOConnectContext } from "@interopio/react-hooks";
import {
  Dropdown,
  Icon,
  IconProps,
  Separator,
} from "@interopio/components-react";

const PLATFORM_UTILITY_PAGES = {
  ABOUT: "about",
  HOTKEYS: "hotkeys",
  FEEDBACK: "feedback",
} as const;

const PLATFORM_APPS = {
  DOWNLOAD_MANAGER: "io-connect-download-manager",
} as const;

type PageKey = keyof typeof PLATFORM_UTILITY_PAGES;
type PageName = (typeof PLATFORM_UTILITY_PAGES)[PageKey];
type AppKey = keyof typeof PLATFORM_APPS;
type AppName = (typeof PLATFORM_APPS)[AppKey];

function MainContextMenu() {
  const io = useContext(IOConnectContext) as IOConnectDesktop.API;

  const startPage = useCallback(
    async (pageName: PageName) => {
      if (!io) {
        console.warn("IOConnectContext not available");
        return;
      }

      try {
        await io.interop.invoke("T42.GD.Execute", {
          command: "open-utility-page",
          args: { name: pageName },
        });
      } catch (error) {
        console.warn("Failed to open utility page", pageName, error);
      }
    },
    [io]
  );

  const startApp = useCallback(
    async (appName: AppName) => {
      if (!io) {
        console.warn("IOConnectContext not available");
        return;
      }

      try {
        const app = io.appManager.application(appName);
        if (!app) {
          throw new Error(`Cannot find app with name "${appName}"`);
        }
        await app.start();
      } catch (error) {
        console.warn("Failed to start app", appName, error);
      }
    },
    [io]
  );

  const openDownloads = useCallback(() => {
    startApp(PLATFORM_APPS.DOWNLOAD_MANAGER);
  }, [startApp]);

  const openFeedback = useCallback(() => {
    startPage(PLATFORM_UTILITY_PAGES.FEEDBACK);
  }, [startPage]);

  const openHotkeys = useCallback(() => {
    startPage(PLATFORM_UTILITY_PAGES.HOTKEYS);
  }, [startPage]);

  const handleMinimize = useCallback(async () => {
    if (!io) {
      console.warn("IOConnectContext not available");
      return;
    }

    const myWindow = io.windows.my();

    if (!myWindow) {
      return;
    }

    try {
      await myWindow.minimize();
    } catch (error) {
      console.error("Failed to minimize window", error);
    }
  }, [io]);

  const handleRestart = useCallback(async () => {
    if (!io) {
      console.warn("IOConnectContext not available");
      return;
    }

    try {
      await io.appManager.restart({
        autoSave: true,
        showDialog: true,
      });
    } catch (error) {
      console.error("Failed to restart io.Connect Desktop", error);
    }
  }, [io]);

  const handleShutdown = useCallback(async () => {
    if (!io) {
      console.warn("IOConnectContext not available");
      return;
    }

    try {
      await io.appManager.exit({
        autoSave: true,
        showDialog: true,
      });
    } catch (error) {
      console.error("Failed to shutdown io.Connect Desktop", error);
    }
  }, [io]);

  const menuItems = useMemo(
    () => [
      {
        label: "Pin Launchpad",
        icon: "pin",
        onClick: () => null,
        disabled: true,
      },
      { label: "Dock Launchpad", onClick: () => null, disabled: true },
      { separator: true },
      {
        label: "Platform Preferences",
        icon: "cog",
        onClick: () => null,
        disabled: true,
      },
      {
        label: "Notification Settings",
        icon: "bell",
        onClick: () => null,
        disabled: true,
      },
      {
        label: "Intent Resolver Settings",
        icon: "list-ul",
        onClick: () => null,
        disabled: true,
      },
      { separator: true },
      { label: "Profile", icon: "user", onClick: () => null, disabled: true },
      { separator: true },
      { label: "Downloads", onClick: openDownloads },
      { separator: true },
      { label: "Feedback", icon: "feedback", onClick: openFeedback },
      { label: "Keyboard Shortcuts", icon: "keyboard", onClick: openHotkeys },
      { separator: true },
      { label: "Minimize", icon: "minimize-down", onClick: handleMinimize },
      { label: "Restart", icon: "rotate-right", onClick: handleRestart },
      { label: "Shut Down", icon: "power-off", onClick: handleShutdown },
    ],
    [
      openDownloads,
      openFeedback,
      openHotkeys,
      handleMinimize,
      handleRestart,
      handleShutdown,
    ]
  );

  return (
    <div className="launchpad-header-actions">
      <Dropdown>
        <Dropdown.ButtonIcon
          variant="circle"
          icon="ellipsis-vertical"
          title="More"
        />
        <Dropdown.Content>
          <Dropdown.List>
            {menuItems.map((item, idx) =>
              item.separator ? (
                <Separator key={`sep-${idx}`} />
              ) : (
                <Dropdown.Item
                  key={item.label}
                  prepend={<Icon variant={item.icon as IconProps["variant"]} />}
                  onClick={item.onClick}
                  disabled={item.disabled}
                >
                  {item.label}
                </Dropdown.Item>
              )
            )}
          </Dropdown.List>
        </Dropdown.Content>
      </Dropdown>
    </div>
  );
}

export default MainContextMenu;
