import type { Meta, StoryObj } from '@storybook/react-vite'

import { Button } from './button'
import { expect, userEvent, screen } from 'storybook/test'

const meta = {
  title: 'Button',
  component: Button,
  tags: ['autodocs'],
  parameters: {
    layout: 'centered',
  },
  argTypes: {
    variant: {
      control: 'select',
      options: [
        'default',
        'secondary',
        'destructive',
        'outline',
        'ghost',
        'link',
        'outlineInvert',
        'extraGhost',
        'extraGhost2',
        'neutral',
      ],
    },
    size: {
      control: 'select',
      options: ['default', 'xs', 'sm', 'lg', 'xs2', 'icon', 'iconSm', 'smLow', 'max'],
    },
  },
} satisfies Meta<typeof Button>
export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {
  args: { variant: 'default', size: 'default' },
  render: (args) => (
    <Button {...args} onClick={() => window.alert('click event fired')} data-testid="default-button">
      Button
    </Button>
  ),
  play: async () => {
    // Use a simple global spy for window.alert
    const originalAlert = window.alert
    let alertCalled = false
    window.alert = (msg) => {
      if (msg === 'click event fired') alertCalled = true
    }
    const button = screen.getByTestId('default-button')
    await userEvent.click(button)
    expect(alertCalled).toBe(true)
    window.alert = originalAlert
  },
}

export const Variants: Story = {
  render: () => (
    <div className="flex flex-wrap gap-2">
      <Button variant="default">Default</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="destructive">Destructive</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="link">Link</Button>
      <Button variant="outlineInvert">Outline Invert</Button>
      <Button variant="extraGhost">Extra Ghost</Button>
      <Button variant="extraGhost2">Extra Ghost 2</Button>
      <Button variant="neutral">Neutral</Button>
    </div>
  ),
}

export const Sizes: Story = {
  render: () => (
    <div className="flex flex-wrap gap-2 items-center">
      <Button size="xs">Extra Small</Button>
      <Button size="sm">Small</Button>
      <Button size="default">Default</Button>
      <Button size="lg">Large</Button>
      <Button size="xs2">Extra Small 2</Button>
      <Button size="icon">Icon</Button>
      <Button size="iconSm">Icon Small</Button>
      <Button size="smLow">Small Low</Button>
      <Button size="max">Max</Button>
    </div>
  ),
}

export const WithIcon: Story = {
  render: () => (
    <Button>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      >
        <circle cx="12" cy="12" r="10" />
        <path d="m15 9-6 6" />
        <path d="m9 9 6 6" />
      </svg>
      With Icon
    </Button>
  ),
}

export const AsChild: Story = {
  render: () => (
    <Button asChild>
      <a href="https://example.com" target="_blank" rel="noreferrer">
        Link Button
      </a>
    </Button>
  ),
}

export const Disabled: Story = {
  args: {
    children: 'Disabled',
    disabled: true,
  },
  render: (args) => (
    <Button {...args} onClick={() => window.alert('click event fired')} data-testid="disabled-button" />
  ),
  play: async () => {
    // Use a simple global spy for window.alert
    const originalAlert = window.alert
    let alertCalled = false
    window.alert = (msg) => {
      if (msg === 'click event fired') alertCalled = true
    }
    const disabledButton = screen.getByTestId('disabled-button')

    await expect(disabledButton).toHaveAttribute('disabled')
    await expect(disabledButton).toHaveStyle('pointer-events: none')

    await userEvent.click(disabledButton, { pointerEventsCheck: 0 })
    expect(alertCalled).toBe(false)
    window.alert = originalAlert
  },
}
