import { useState, useEffect } from 'react';
import { fn } from 'storybook/test';
import { Meta, StoryObj } from '@storybook/react-webpack5';

import { storySourceWithoutNoise } from '../../.storybook/helpers';
import { createSandboxStory, globalScope } from '../../.storybook/components/sandbox/SandboxEditor';
import CheckboxButton, { type CheckboxButtonProps } from './CheckboxButton';
import { Label } from '../label/Label';

/**
 * Use <a href="?path=/docs/forms-checkbox--docs">Checkbox</a> component instead when pairing with a label. Only use CheckboxButton when you need a standalone checkbox (e.g. settings matrix) and provide an `aria-label`.
 *
 * **Design guidance**: <a href="https://docs.wise.design/components/checkbox" target="_blank">wise.design/components/checkbox</a>
 */
export default {
  component: CheckboxButton,
  title: 'Actions/CheckboxButton',
  args: {
    'aria-label': 'Toggle checkbox',
    checked: true,
    disabled: false,
    indeterminate: false,
    onBlur: fn(),
    onChange: fn(),
    onClick: fn(),
    onFocus: fn(),
  },
  argTypes: {
    'aria-label': {
      description: 'Provides the accessible name when the control has no visible text label.',
    },
    checked: {
      description: 'Controls whether the checkbox is checked.',
    },
    disabled: {
      description: 'Toggles the disabled state.',
    },
    name: {
      description: 'Name submitted with the form when the checkbox is checked.',
    },
    value: {
      description: 'Value submitted with the form when the checkbox is checked.',
    },
    onChange: {
      description: 'Called when the checked state changes.',
    },
    indeterminate: {
      description:
        'Sets the native mixed state — used when some (not all) child items are selected. Clicking resolves to checked; clear `indeterminate` in `onChange` to reflect the transition.',
    },
    defaultChecked: { table: { category: 'Common' } },
    id: { table: { category: 'Common' } },
    className: { table: { category: 'Common' } },
    onBlur: { table: { category: 'Common' } },
    onClick: { table: { category: 'Common' } },
    onFocus: { table: { category: 'Common' } },
  },
  parameters: {
    docs: { toc: true },
  },
} satisfies Meta<typeof CheckboxButton>;

type Story = StoryObj<typeof CheckboxButton>;

const withColumnLayout = (Story: () => JSX.Element) => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
    <Story />
  </div>
);

/** Interactive single checkbox — use the Controls panel to toggle `disabled` and `indeterminate`. */
export const Playground: Story = storySourceWithoutNoise({
  render: function Render(args: CheckboxButtonProps) {
    const [checked, setChecked] = useState(args.checked ?? true);

    useEffect(() => {
      setChecked(args.checked ?? true);
    }, [args.checked]);

    return (
      <CheckboxButton
        {...args}
        checked={checked}
        onChange={(e) => {
          setChecked(e.currentTarget.checked);
          args.onChange?.(e);
        }}
      />
    );
  },
});

export const Sandbox = createSandboxStory({
  code: `const App = () => {
  const [checked, setChecked] = React.useState(true);

  return (
    <CheckboxButton
      aria-label="Toggle email updates"
      checked={checked}
      onChange={(event) => setChecked(event.currentTarget.checked)}
    />
  );
};`,
  scope: globalScope,
});

/** Disabled state — checked and unchecked. */
export const Disabled: Story = {
  decorators: [withColumnLayout],
  render: (args) => (
    <>
      <div>
        <Label htmlFor="disabled-unchecked">Disabled unchecked</Label>
        <CheckboxButton
          id="disabled-unchecked"
          aria-label="Disabled unchecked"
          checked={false}
          disabled
          onChange={() => {}}
        />
      </div>
      <div>
        <Label htmlFor="disabled-checked">Disabled checked</Label>
        <CheckboxButton
          id="disabled-checked"
          aria-label="Disabled checked"
          checked
          disabled
          onChange={() => {}}
        />
      </div>
    </>
  ),
};

/** Indeterminate state — checked and unchecked. */
export const Indeterminate: Story = {
  decorators: [withColumnLayout],
  render: (args) => (
    <>
      <div>
        <Label htmlFor="indeterminate-unchecked">Indeterminate (unchecked)</Label>
        <CheckboxButton
          id="indeterminate-unchecked"
          aria-label="Indeterminate unchecked"
          checked={false}
          indeterminate
          onChange={() => {}}
        />
      </div>
      <div>
        <Label htmlFor="indeterminate-checked">Indeterminate (checked)</Label>
        <CheckboxButton
          id="indeterminate-checked"
          aria-label="Indeterminate checked"
          checked
          indeterminate
          onChange={() => {}}
        />
      </div>
    </>
  ),
};
