import React, { ChangeEvent, ChangeEventHandler, forwardRef } from "react";
import * as RadixSwitch from "@radix-ui/react-switch";
import type { SwitchProps as RadixSwitchProps } from "@radix-ui/react-switch";
import { twJoin } from "tailwind-merge";

import { InputLabel } from "../inputLabel/InputLabel";
import { ReactComponent as CheckmarkExtrabold } from "../../../resources/toggles/checkmark-extrabold.svg";
import { ReactComponent as XmarkExtrabold } from "../../../resources/toggles/xmark-extrabold.svg";
import { twMerge } from "../../../tailwind.config";

export interface SwitchProps
  extends Omit<RadixSwitchProps, "onChange" | "className"> {
  label?: string | React.ReactNode;
  size?: "small" | "medium";
  onChange?: ChangeEventHandler<HTMLInputElement>;
  ESCAPE_className?: string;
}

export const Switch = forwardRef<HTMLButtonElement, SwitchProps>(
  (
    {
      id,
      size = "medium",
      label,
      disabled = false,
      onChange,
      onCheckedChange,
      ESCAPE_className,
      ...restProps
    },
    ref
  ) => (
    <>
      {typeof label === "string" ? (
        <InputLabel htmlFor={id}>{label}</InputLabel>
      ) : (
        label
      )}
      <RadixSwitch.Root
        className={twMerge(
          "group relative m-[5px] cursor-pointer rounded-full border-none p-2 transition-colors",
          disabled
            ? "bg-N20A text-N50"
            : "bg-N90 text-N0 hover:bg-N70 aria-checked:bg-B400 aria-checked:hover:bg-B500",
          "outline-none ring-B400FR ring-offset-2 focus-visible:ring-3",
          size === "medium" ? "h-24 w-48" : "h-20 w-40",
          ESCAPE_className
        )}
        id={id}
        ref={ref}
        disabled={disabled}
        onCheckedChange={(newChecked) => {
          onCheckedChange?.(newChecked);
          onChange?.({
            target: { checked: newChecked },
          } as ChangeEvent<HTMLInputElement>);
        }}
        {...restProps}
      >
        <CheckmarkExtrabold
          className={twJoin(
            "absolute left-4 top-2 box-content p-2",
            size === "medium" ? "h-16 w-16" : "h-12 w-12"
          )}
        />
        <XmarkExtrabold
          className={twJoin(
            "absolute right-4 top-2 box-content p-2",
            size === "medium" ? "h-16 w-16" : "h-12 w-12"
          )}
        />
        <RadixSwitch.Thumb
          className={twJoin(
            "mx-4 block h-full rounded-full bg-current transition-transform duration-300",
            "-translate-x-4 group-aria-checked:translate-x-full",
            size === "medium" ? "w-20" : "w-16"
          )}
        />
      </RadixSwitch.Root>
    </>
  )
);

Switch.displayName = "Switch";
