import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import {
  Maximize2Icon,
  Minimize2Icon,
  PlusIcon,
  TerminalIcon,
  XIcon,
} from "lucide-react";
import {
  DropdownMenu as DropdownMenuPrimitive,
  Tabs as TabsPrimitive,
} from "radix-ui";
import { type ReactNode, type Ref, useEffect, useId, useState } from "react";
import {
  DialogLayout,
  isConstraintLayout,
  type RectWindow,
} from "simple-window";
import {
  RectWindowHeader,
  RectWindowWrapper,
  useRectWindow,
} from "simple-window/react";
import "./css.polifill";

export interface FloatingWindowTabProps {
  id: number | string;
  title: ReactNode;
  status?: ReactNode;
  onClose?: (id: number | string) => void;
}

export function FloatingWindowV2({
  title,
  tab,
  tabs,
  beforeTabs,
  onTabChange,
  onNewTab,
  newTabOptions,
  children,
  onClose,
  ref,
}: {
  title: ReactNode;
  tab?: number | string;
  beforeTabs?: ReactNode;
  tabs?: FloatingWindowTabProps[];
  onTabChange?: (tabId: number | string) => void;
  onNewTab?: (id: string) => void;
  newTabOptions: { label: ReactNode; value: string }[];
  children: ReactNode;
  onClose?: () => void;
  ref?: Ref<RectWindow<any> | null>;
}) {
  const id = useId();
  const tabIds = tabs?.map((item) => item.id) ?? [];

  return (
    <RectWindowWrapper
      ref={ref}
      windowProps={undefined}
      role="dialog"
      className={cn("rounded-lg shadow-black/40 shadow-lg")}
      aria-labelledby={`${id}-title`}
    >
      <Header id={id} title={title} onClose={onClose} />
      {tabs?.length && (
        <Tabs tab={tab} tabIds={tabIds} onTabChange={onTabChange}>
          {beforeTabs}
          {tabs.map((tab) => (
            <Tab key={tab.id} {...tab} />
          ))}
          {onNewTab && newTabOptions.length === 1 && (
            <button
              className="transition-colors text-muted-foreground hover:text-foreground cursor-pointer"
              onClick={() => onNewTab(newTabOptions[0].value)}
            >
              <PlusIcon className="size-3" />
            </button>
          )}
          {onNewTab && newTabOptions.length > 1 && (
            <DropdownMenu>
              <DropdownMenuPrimitive.Trigger asChild>
                <button className="transition-colors text-muted-foreground hover:text-foreground cursor-pointer">
                  <PlusIcon className="size-3" />
                </button>
              </DropdownMenuPrimitive.Trigger>
              <DropdownMenuContent>
                {newTabOptions.map((option) => (
                  <DropdownMenuItem
                    key={option.value}
                    onSelect={() => {
                      onNewTab(option.value);
                    }}
                  >
                    {option.label}
                  </DropdownMenuItem>
                ))}
              </DropdownMenuContent>
            </DropdownMenu>
          )}
        </Tabs>
      )}
      <div className="w-full h-[calc(100%-56px)] rounded-b-lg border border-t-0 overflow-hidden relative">
        {children}
      </div>
      <WindowEvents />
    </RectWindowWrapper>
  );
}

function Header({
  id,
  title,
  onClose,
}: {
  id: string;
  title: ReactNode;
  onClose?: () => void;
}) {
  const window = useRectWindow();
  const [fullMode, setFullMode] = useState(false);

  const onToggleFullMode = () => {
    if (window) {
      if (fullMode) {
        window.setLayout(undefined);
        setFullMode(false);
      } else {
        window.setLayout(new DialogLayout());
        setFullMode(true);
      }
    }
  };

  return (
    <RectWindowHeader
      window={window}
      className="h-[32px] bg-accent/75 backdrop-blur-xs w-full rounded-t-lg overflow-hidden relative"
    >
      <div
        className="flex items-center justify-center gap-1 w-full h-full text-xs font-bold text-muted-foreground"
        id={`${id}-title`}
      >
        <TerminalIcon className="size-4" />
        {title}
      </div>
      <div className="w-full h-full flex gap-2 px-2 items-center justify-end absolute right-0 top-0">
        {window && (
          <button
            className="cursor-pointer outline-hidden text-muted-foreground hover:text-foreground transition-colors"
            type="button"
            onClick={onToggleFullMode}
          >
            {fullMode ? (
              <Minimize2Icon className="size-4" />
            ) : (
              <Maximize2Icon className="size-4" />
            )}
          </button>
        )}
        {onClose && (
          <button
            className="cursor-pointer outline-hidden text-muted-foreground hover:text-destructive transition-colors"
            type="button"
            onClick={onClose}
          >
            <XIcon className="size-4" />
          </button>
        )}
      </div>
    </RectWindowHeader>
  );
}

function Tabs({
  tab,
  tabIds,
  onTabChange,
  children,
}: {
  tab?: number | string;
  tabIds: Array<number | string>;
  onTabChange?: (tabId: number | string) => void;
  children: ReactNode;
}) {
  const lookup = new Map(tabIds.map((tabId) => [String(tabId), tabId]));

  return (
    <TabsPrimitive.Root
      className="bg-accent/75 backdrop-blur-xs w-full"
      value={String(tab)}
      onValueChange={(value) => onTabChange?.(lookup.get(value) ?? value)}
    >
      <TabsPrimitive.List className="px-2 flex gap-2 flex-nowrap w-full overflow-x-auto">
        {children}
      </TabsPrimitive.List>
    </TabsPrimitive.Root>
  );
}

function Tab({ id, status, title, onClose }: FloatingWindowTabProps) {
  return (
    <TabsPrimitive.TabsTrigger
      value={String(id)}
      className="group/tab text-xs py-1 px-4 rounded-t-lg border-t border-x border-transparent font-semibold text-muted-foreground transition-colors hover:text-foreground hover:bg-white hover:border-border aria-selected:text-foreground aria-selected:bg-white aria-selected:border-border whitespace-nowrap"
    >
      {status}
      {title}
      {onClose && (
        <XIcon
          role="button"
          aria-label="close tab"
          className="size-3 ml-2 inline-flex transition-all opacity-50 hover:opacity-100 cursor-pointer"
          onClick={(ev) => {
            onClose(id);
            ev.stopPropagation();
          }}
        />
      )}
    </TabsPrimitive.TabsTrigger>
  );
}

function WindowEvents() {
  const window = useRectWindow();

  useEffect(() => {
    if (window) {
      let lastElement: Element | null = null;
      const handleDraggingOrResizeStart = () => {
        if (lastElement) {
          lastElement?.classList.remove("bg-rose-200/20");
        }
        const layout = window.parent.layout;
        if (isConstraintLayout(layout)) {
          if (layout.boundingElement) {
            lastElement = layout.boundingElement;
            lastElement.classList.add("bg-rose-200/20");
            return;
          }
        }
        lastElement?.classList.remove("bg-rose-200/20");
        lastElement = null;
      };
      const handleDraggingOrResizeEnd = () => {
        if (lastElement) {
          lastElement?.classList.remove("bg-rose-200/20");
        }
      };

      window.on("resize:start", handleDraggingOrResizeStart);
      window.on("resize:end", handleDraggingOrResizeEnd);
      window.on("drag:start", handleDraggingOrResizeStart);
      window.on("drag:end", handleDraggingOrResizeEnd);

      return () => {
        window.off("resize:start", handleDraggingOrResizeStart);
        window.off("resize:end", handleDraggingOrResizeEnd);
        window.off("drag:start", handleDraggingOrResizeStart);
        window.off("drag:end", handleDraggingOrResizeEnd);
      };
    }
  }, [window]);

  return null;
}
