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

import { expect } from 'storybook/test'

import { MaterialIcon } from '../Icons/MaterialIcon'
import { IconButton } from './IconButton'
import { config } from './variants'

const meta: Meta<typeof IconButton> = {
  title: 'Components/IconButton',
  component: IconButton,
  argTypes: {
    onPress: {
      table: {
        disable: true,
      },
    },
    children: {
      table: {
        disable: true,
      },
    },
    theme: {
      control: 'select',
      options: Object.keys(config.variants.theme),
      table: {
        defaultValue: {
          summary: config.defaultVariants.theme,
        },
        type: {
          summary: 'string',
          detail: Object.keys(config.variants.theme).join(' | '),
        },
      },
    },
    style: {
      control: 'select',
      options: Object.keys(config.variants.style),
      table: {
        defaultValue: {
          summary: config.defaultVariants.style,
        },
        type: {
          summary: 'string',
          detail: Object.keys(config.variants.style).join(' | '),
        },
      },
      description:
        'The style variant is only applied on certain variants. The examples below shows the possible combinations of variants and style variants.',
    },
  },
}

const globalStoryPropsInverted = {
  backgrounds: { value: 'scandicPrimaryDark' },
}
export default meta

type Story = StoryObj<typeof IconButton>

export const Default: Story = {
  args: {
    onPress: () => alert('Icon button pressed!'),
    children: <MaterialIcon icon="search" size={24} color="CurrentColor" />,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const Primary: Story = {
  args: {
    ...Default.args,
    theme: 'Primary',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const PrimaryDisabled: Story = {
  args: {
    ...Primary.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const Inverted: Story = {
  args: {
    ...Default.args,
    children: (
      <MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
    ),
    theme: 'Inverted',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const InvertedDisabled: Story = {
  args: {
    ...Inverted.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const InvertedElevated: Story = {
  args: {
    ...Inverted.args,
    style: 'Elevated',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const InvertedElevatedDisabled: Story = {
  args: {
    ...InvertedElevated.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const InvertedMuted: Story = {
  globals: globalStoryPropsInverted,
  args: {
    ...Inverted.args,
    children: <MaterialIcon icon="close" size={24} color="CurrentColor" />,
    style: 'Muted',
  },

  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const InvertedMutedDisabled: Story = {
  globals: globalStoryPropsInverted,
  args: {
    ...InvertedMuted.args,
    isDisabled: true,
  },

  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const InvertedFaded: Story = {
  args: {
    ...Inverted.args,
    style: 'Faded',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const InvertedFadedDisabled: Story = {
  args: {
    ...InvertedFaded.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const TertiaryElevated: Story = {
  args: {
    ...Default.args,
    children: <MaterialIcon icon="arrow_back" size={24} color="CurrentColor" />,
    theme: 'Tertiary',
    style: 'Elevated',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const TertiaryDisabled: Story = {
  args: {
    ...TertiaryElevated.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}

export const BlackMuted: Story = {
  args: {
    ...Default.args,
    children: <MaterialIcon icon="close" size={24} color="CurrentColor" />,
    theme: 'Black',
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(1)
  },
}

export const BlackMutedDisabled: Story = {
  args: {
    ...BlackMuted.args,
    isDisabled: true,
  },
  play: async ({ canvas, userEvent, args }) => {
    await userEvent.click(canvas.getByRole('button'))
    expect(args.onPress).toHaveBeenCalledTimes(0)
  },
}
