import { isNotNil } from 'es-toolkit';
import { Component, createEffect, createMemo, createSignal, mergeProps, Show } from 'solid-js';

interface SwitchProps {
  name?: string;
  checked?: boolean;
  disabled?: boolean;
  onChange?: (checked: boolean) => void;
}

const Switcher: Component<SwitchProps> = (props) => {
  const mProps = mergeProps<SwitchProps[]>(
    {
      disabled: false,
    },
    props,
  );

  const originalChecked = createMemo(() => mProps.checked);
  const [internalChecked, setInternalChecked] = createSignal<boolean | undefined>(undefined);

  createEffect(() => {
    if (isNotNil(originalChecked()) && originalChecked() !== internalChecked()) {
      setInternalChecked(originalChecked());
    }
  });

  const handleClick = () => {
    if (mProps.disabled) {
      return;
    }
    setInternalChecked((prev) => !prev);
    mProps.onChange?.(internalChecked());
  };

  return (
    <div
      aria-disabled={mProps.disabled}
      class="inline-flex items-center gap-[1em] cursor-pointer rounded-sm aria-disabled:cursor-not-allowed group"
      classList={{ 'bg-primary/38 aria-disabled:bg-on-surface/8': internalChecked() }}>
      <div
        class="relative h-[1em] w-[1.75em] border border-solid border-primary group-aria-disabled:border-on-surface/8 rounded-sm before:absolute before:translate-x-[2px] before:translate-y-[2px] before:h-[calc(1em-6px)] before:aspect-square before:rounded-xs before:bg-primary before:transition before:duration-200 before:ease-in-out group-aria-disabled:before:bg-on-surface/18"
        classList={{ 'before:translate-x-[calc(0.75em+2px)]': internalChecked() }}
        onClick={handleClick}
      />
      <Show when={isNotNil(mProps.name)}>
        <input type="hidden" name={mProps.name} value={internalChecked() ? 'true' : 'false'} />
      </Show>
    </div>
  );
};

export default Switcher;
