import type { JSX } from "solid-js";
import { splitProps } from "solid-js";
import { createControllableSignal } from "../../primitives/create-controllable-signal";

export interface SwitchProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
  /** Controlled checked state. */
  checked?: boolean;
  /** Default checked state (uncontrolled). @default false */
  defaultChecked?: boolean;
  /** Called when checked state changes. */
  onCheckedChange?: (checked: boolean) => void;
  /** Native form field name — renders a hidden checkbox input. */
  name?: string;
  /** Value submitted with the form when checked. @default "on" */
  value?: string;
  required?: boolean;
  children?: JSX.Element;
}

/**
 * An on/off control. Semantically equivalent to a checkbox but visually
 * represents a binary switch. Uses role="switch" and aria-checked.
 */
export function Switch(props: SwitchProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "checked",
    "defaultChecked",
    "onCheckedChange",
    "disabled",
    "required",
    "name",
    "value",
    "children",
    "onClick",
  ]);

  const [isChecked, setChecked] = createControllableSignal<boolean>({
    value: () => local.checked,
    defaultValue: () => local.defaultChecked ?? false,
    onChange: local.onCheckedChange,
  });

  return (
    <button
      type="button"
      role="switch"
      aria-checked={isChecked()}
      aria-required={local.required || undefined}
      data-state={isChecked() ? "checked" : "unchecked"}
      disabled={local.disabled}
      {...rest}
      onClick={() => {
        if (!local.disabled) setChecked(!isChecked());
      }}
    >
      {local.children}
      {local.name && (
        <input
          type="checkbox"
          aria-hidden="true"
          tabIndex={-1}
          name={local.name}
          value={local.value ?? "on"}
          checked={isChecked()}
          style={{ display: "none" }}
        />
      )}
    </button>
  );
}
