"use client";

import React, { createContext, useContext, ReactNode, FC } from "react";
import clsx from "clsx";

// Context
type TabsContextType<T extends string> = {
  value: T;
  onChange: (val: T) => void;
};
const TabsContext = createContext<TabsContextType<any> | null>(null);

function useTabs<T extends string>() {
  const ctx = useContext(TabsContext);
  if (!ctx) throw new Error("Tab components must be used inside <Tabs>");
  return ctx as TabsContextType<T>;
}

// Tabs Root
type TabsProps<T extends string> = {
  value: T;
  onChange: (val: T) => void;
  children: ReactNode;
  className?: string;
};
export function Tabs<T extends string>({
  value,
  onChange,
  children,
  className,
}: TabsProps<T>) {
  return (
    <TabsContext.Provider value={{ value, onChange }}>
      <div className={clsx("w-full", className)}>{children}</div>
    </TabsContext.Provider>
  );
}

// TabList
export const TabList: FC<{ children: ReactNode; className?: string }> = ({
  children,
  className,
}) => <div className={clsx("flex", className)}>{children}</div>;

// Tab
type TabProps<T extends string> = {
  value: T;
  children: ReactNode;
  className?: string;
  activeClassName?: string;
};
export function Tab<T extends string>({
  value,
  children,
  className,
  activeClassName,
}: TabProps<T>) {
  const { value: active, onChange } = useTabs();
  const isActive = active === value;

  return (
    <button
      onClick={() => onChange(value)}
      className={clsx(
        "px-2 sm:px-4 text-sm font-medium cursor-pointer",
        isActive
          ? "border-b-2 border-dark-blue-800 text-dark-blue-1100"
          : "text-gray-1000",
        className,
        isActive && activeClassName
      )}
    >
      {children}
    </button>
  );
}

// Panels Wrapper
export const TabPanels: FC<{ children: ReactNode; className?: string }> = ({
  children,
  className,
}) => <div className={clsx("p-4", className)}>{children}</div>;

// Single Panel
type TabPanelProps<T extends string> = {
  value: T;
  children: ReactNode;
  className?: string;
};
export function TabPanel<T extends string>({
  value,
  children,
  className,
}: TabPanelProps<T>) {
  const { value: active } = useTabs();
  if (active !== value) return null;
  return <div className={clsx("text-gray-700", className)}>{children}</div>;
}
