"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import styles from "./switch.module.css";
import { motion } from "framer-motion";

/**
 * A generic button component.
 * @type {React.FC<React.ButtonHTMLAttributes<HTMLButtonElement> & {
 *    value: boolean;
 *    height: number;
 *    width: number;
 *    onChange: Function;
 *    color: {
 *        on: string;
 *        off: string;
 *    };
 *    disabled?: boolean;
 *    title?: string;
 * }>}
 */
const Switch = (props) => {
  const [value, setValue] = useState(props.value || false);

  const role = useMemo(
    () => ({
      color_on: props.color?.on || "#4085b3",
      color_off: props.color?.off || "#6c6c6c",
      ball_height: props.height ? (props.height * 3) / 4 : 15,
      ball_width: props.height ? (props.height * 3) / 4 : 15,
      rail_height: props.height ? props.height : 20,
      rail_width: props.width ? props.width : 30,
    }),
    [props]
  );

  useEffect(() => {
    setValue(props.value);
  }, [props]);

  const setValueData = useCallback(
    (data) => {
      if (props.disabled) return;
      const onChangeAvailable =
        props.onChange && typeof props.onChange === "function";
      if (typeof data === "function") {
        setValue((prev) => {
          const newValue = data(prev);
          if (onChangeAvailable) props.onChange(newValue);
          return newValue;
        });
        return;
      }

      setValue(data);
      if (onChangeAvailable) props.onChange(data);
    },
    [props]
  );

  return (
    <div
      title={props.title}
      className={`${styles.switch} ${props?.disabled ? styles.disabled : ""}`}
      onClick={() => setValueData(!value)}
      style={{
        height: `${role.rail_height}px`,
        width: `${role.rail_width}px`,
      }}>
      <div
        className={styles.rail2}
        style={{
          backgroundColor: value ? role.color_on : role.color_off,
        }}>
        <motion.div
          initial={
            value
              ? { x: role.rail_width - role.ball_height, y: "-50%" }
              : { x: 0, y: "-50%" }
          }
          animate={
            value
              ? { x: role.rail_width - role.ball_height, y: "-50%" }
              : { x: 0, y: "-50%" }
          }
          className={styles.switch_button}
          style={{
            borderRadius: props.width ? `${props.width}px` : "40px",
            backgroundColor: value ? role.color_on : role.color_off,
            height: `${role.ball_height}px`,
            width: `${role.ball_width}px`,
          }}></motion.div>
      </div>
    </div>
  );
};

export default Switch;
