import { cn } from "~/lib/utils";
import React, { useEffect, useMemo, useRef } from "react";
import ActionButton from "./action-button";
import { FiX } from "react-icons/fi";
import FileIcon from "./file-icon";

export type Tab = {
  title: string;
  icon?: React.ReactNode;
  render?: () => React.ReactNode;
};

type Props = {
  tabs: Tab[];
  current?: number;
  onChange?: (idx: number) => void;
  onClose?: (idx: number) => void;
};

const Tabs = ({ tabs, current = 0, onChange, onClose }: Props) => {
  const tabContainerRef = useRef<HTMLDivElement>(null);

  const onWheel = (e: WheelEvent) => {
    e.cancelable && e.preventDefault();
    if (tabContainerRef.current) {
      tabContainerRef.current.scrollLeft += e.deltaY + e.deltaX;
    }
  };

  useEffect(() => {
    if (!tabs.length || !tabContainerRef.current) {
      return;
    }

    const container = tabContainerRef.current;
    container.addEventListener("wheel", onWheel);
    return () => {
      container.removeEventListener("wheel", onWheel);
    };
  }, [tabs]);

  useEffect(() => {
    if (!tabs.length) {
      return;
    }

    const container = tabContainerRef.current;
    const tabEl: any = container?.querySelector(`[data-idx="${current}"]`);
    if (!container || !tabEl) {
      return;
    }

    const containerRect = container.getBoundingClientRect();
    const scrollX = tabEl.offsetLeft - containerRect.left;
    container.scrollTo({ left: scrollX, behavior: "smooth" });
  }, [tabs, current]);

  const tabView = useMemo(() => {
    const tab = tabs[current];
    const element = tab?.render ? tab.render() : null;
    return element;
  }, [tabs, current]);

  return (
    <div className="w-full h-full flex flex-col items-stretch bg-slate-800">
      {tabs.length > 0 ? (
        <nav
          ref={tabContainerRef}
          className="flex items-stretch overflow-x-auto w-full h-10 min-h-10 hide-scrollbar"
        >
          {tabs.map((tab, idx) => (
            <TabItem
              key={idx}
              index={idx}
              title={tab.title}
              icon={tab.icon}
              isActive={idx === current}
              onSelect={() => onChange && onChange(idx)}
              onClose={() => onClose && onClose(idx)}
            />
          ))}
        </nav>
      ) : null}

      <main className="flex-1 overflow-hidden">{tabView}</main>
    </div>
  );
};

type TabItemProps = {
  index: number;
  title: string;
  icon?: React.ReactNode;
  isActive?: boolean;
  onSelect: () => void;
  onClose: () => void;
};

const TabItem = ({
  index,
  title,
  isActive,
  onSelect,
  onClose,
}: TabItemProps) => {
  const lastDotFile = title.lastIndexOf(".");
  const ext = title.substring(lastDotFile);
  const filename = title.substring(0, lastDotFile);

  return (
    <div
      data-idx={index}
      className={cn(
        "group border-b-2 border-transparent truncate flex-shrink-0 text-white/70 transition-all hover:text-white text-center max-w-[140px] md:max-w-[180px] text-sm flex items-center gap-0 relative z-[1]",
        isActive ? "border-slate-500 text-white" : ""
      )}
      onClick={onSelect}
    >
      <button className="pl-4 pr-0 truncate flex items-center self-stretch">
        <FileIcon
          file={{ isDirectory: false, filename: title }}
          className="mr-1"
        />
        <span className="truncate">{filename}</span>
        <span>{ext}</span>
      </button>
      <ActionButton
        icon={FiX}
        className="opacity-0 group-hover:opacity-100 transition-colors"
        onClick={onClose}
      />
    </div>
  );
};

export default Tabs;