import { useState, useEffect } from 'react';
import { fn } from 'storybook/test';

import { storySourceWithoutNoise } from '../../.storybook/helpers';
import { createSandboxStory, globalScope } from '../../.storybook/components/sandbox/SandboxEditor';
import Switch, { SwitchProps } from './Switch';
import { Field } from '../field/Field';
import { Meta, StoryObj } from '@storybook/react-webpack5';
import { Label } from '../label';

/**
 * **Design guidance**: <a href="https://docs.wise.design/components/switch" target="_blank">wise.design/components/switch</a>
 */
const meta: Meta<typeof Switch> = {
  component: Switch,
  title: 'Actions/Switch',
  args: {
    checked: false,
    disabled: false,
    id: 'switchId',
    className: 'switchClassName',
    'aria-labelledby': undefined,
    'aria-label': 'Toggle switch',
    onClick: fn(),
  },
  argTypes: {
    id: { description: '', table: { category: 'Common' } },
    className: { description: '', table: { category: 'Common' } },
    onClick: { description: '', table: { category: 'Common', type: { summary: 'function' } } },
  },
  parameters: {
    docs: { toc: true },
  },
} satisfies Meta<typeof Switch>;

export default meta;
type Story = StoryObj<typeof Switch>;

export const Playground: Story = storySourceWithoutNoise({
  render: function Render(args: SwitchProps) {
    const [checked, setChecked] = useState(args.checked ?? false);

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

    return (
      <Field id="playground-field" label="Switch label">
        <Switch
          {...args}
          checked={checked}
          onClick={() => setChecked((value: boolean) => !value)}
        />
      </Field>
    );
  },
});

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

  return (
    <Field id="sandbox-field" label="Enable notifications">
      <Switch
        checked={checked}
        onClick={() => setChecked((prev) => !prev)}
      />
    </Field>
  );
};`,
  scope: { ...globalScope, Switch },
});

/**
 * Three labelling patterns: <a href="?path=/docs/forms-label--docs">Label</a>, `aria-labelledby`, and <a href="?path=/docs/forms-field--docs">Field</a>. <br />
 * Use Label for simple label-input pairs. Use `aria-labelledby` to reference existing text as the accessible name. Use Field for form layouts with labels, descriptions, and validation.
 */
export const LabelPatterns: Story = {
  render: function Render({ disabled }: SwitchProps) {
    const [checked1, setCheck1] = useState(true);
    const [checked2, setCheck2] = useState(false);
    const [checked3, setCheck3] = useState(true);

    return (
      <div className="d-flex flex-column" style={{ gap: '1rem' }}>
        <div>
          <Label htmlFor="labelId">Enable two-factor authentication</Label>
          <Switch
            id="labelId"
            checked={checked1}
            disabled={disabled}
            onClick={() => setCheck1(!checked1)}
          />
        </div>

        <div>
          <strong id="ariaId" className="d-block">
            Marketing emails
          </strong>
          <Switch
            aria-labelledby="ariaId"
            checked={checked2}
            disabled={disabled}
            onClick={() => setCheck2(!checked2)}
          />
        </div>

        <Field
          id="fieldId"
          label="Enable notifications"
          description="Get alerts when transfers complete"
        >
          <Switch checked={checked3} disabled={disabled} onClick={() => setCheck3(!checked3)} />
        </Field>
      </div>
    );
  },
  parameters: {
    docs: {
      source: {
        code: `
function Render() {
  const [checked1, setCheck1] = useState(false);
  const [checked2, setCheck2] = useState(true);
  const [checked3, setCheck3] = useState(false);

  return (
    <>
      <Field id="fieldId" label="Using Field component">
        <Switch
          checked={checked1}
          onClick={() => setCheck1(!checked1)}
        />
      </Field>

      <div>
        <Label htmlFor="labelId">Using standalone Label component</Label>
        <Switch
          id="labelId"
          checked={checked2}
          onClick={() => setCheck2(!checked2)}
        />
      </div>

      <div>
        <strong id="ariaId" className="d-block">Using \`aria-labelledby\`</strong>
        <Switch
          aria-labelledby="ariaId"
          checked={checked3}
          onClick={() => setCheck3(!setCheck3)}
        />
      </div>
    </>
  )
}`,
      },
    },
  },
  args: {},
  argTypes: {
    checked: { table: { disable: true } },
    onClick: { table: { disable: true } },
  },
};

export const Disabled: Story = {
  render: function Render() {
    const [checked1, setCheck1] = useState(false);
    const [checked2, setCheck2] = useState(true);

    return (
      <>
        <Field label="Disabled unchecked">
          <Switch checked={checked1} disabled onClick={() => setCheck1(!checked1)} />
        </Field>

        <Field label="Disabled checked">
          <Switch checked={checked2} disabled onClick={() => setCheck2(!checked2)} />
        </Field>
      </>
    );
  },
  parameters: {
    docs: {
      source: {
        code: `
function Render() {
  const [checked1, setCheck1] = useState(false);
  const [checked2, setCheck2] = useState(true);

  return (
    <>
      <Field label="Disabled unchecked">
        <Switch
          checked={checked1}
          disabled
          onClick={() => setCheck1(!checked1)}
        />
      </Field>
      <Field label="Disabled checked">
        <Switch
          checked={checked2}
          disabled
          onClick={() => setCheck2(!checked2)}
        />
      </Field>
    </>
  );
}`,
      },
    },
  },
  args: {
    disabled: true,
  },
  argTypes: {
    disabled: { table: { readonly: true } },
    onClick: { table: { disable: true } },
    checked: { table: { disable: true } },
  },
};
