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

import Banner from './Banner'
import { toast } from '../Toast/Toast'
import { DocsTemplate } from '../../../.storybook'

const meta: Meta<typeof Banner> = {
  title: 'Components/Banner',
  component: Banner,
  parameters: {
    layout: 'fullscreen',
    design: {
      type: 'figma',
      url: 'https://www.figma.com/design/RvhKD82948FMQnh5MyCi0o/Web-Design-System?node-id=121-609&p=f&t=dpvdmOj1lXymCIvb-0',
    },
    docs: {
      page: () => (
        <DocsTemplate
          figmaLink='https://www.figma.com/design/RvhKD82948FMQnh5MyCi0o/Web-Design-System?node-id=121-609&p=f&t=dpvdmOj1lXymCIvb-0'
          description={
            <span>
              The <code>Banner</code> component is a prominent notification that
              appears at the top of a page to convey important messages or
              alerts to users. It is designed to catch the user's attention
              immediately upon visiting the page and remains in place until the
              user dismisses it.
            </span>
          }
          infoBullets={[
            <span key='first-bullet'>
              Use the <code>Banner</code> component to display critical or
              time-sensitive information that requires immediate attention from
              users.
            </span>,
            <span key='second-bullet'>
              Ensure the <code>Banner</code> is dismissible, allowing users to
              close it once they have acknowledged the message.
            </span>,
          ]}
        />
      ),
    },
  },
}
export default meta

type Story = StoryObj<typeof Banner>

const Template: Story = {
  render: (args) => <Banner {...args} />,
}

const args = {
  primaryText: 'This is the primary text',
  secondaryText: 'This is the secondary text',
  type: 'informational' as 'informational' | 'issue',
  buttonProps: {
    children: 'Click Me',
    onClick: () => {
      toast({
        message: 'Button Clicked',
        type: 'success',
      })
    },
  },
}

export const Basic: Story = {
  ...Template,
  args: {
    primaryText: args.primaryText,
    secondaryText: args.secondaryText,
    type: 'informational',
  },
  play: async ({ canvas }) => {
    const banner = canvas.getByTestId('banner')
    await expect(banner).toBeInTheDocument()
    await expect(banner?.className).toContain('informational')

    await expect(
      canvas.getByText('This is the primary text'),
    ).toBeInTheDocument()
    await expect(
      canvas.getByText('This is the secondary text'),
    ).toBeInTheDocument()
    await expect(canvas.getByTestId('icon-info')).toBeInTheDocument()
  },
}

export const WithIssueType: Story = {
  ...Template,
  args: {
    primaryText: args.primaryText,
    secondaryText: args.secondaryText,
    type: 'issue',
  },
  play: async ({ canvas }) => {
    const banner = canvas.getByTestId('banner')
    await expect(banner).toBeInTheDocument()
    await expect(banner?.className).toContain('issue')

    await expect(
      canvas.getByText('This is the primary text'),
    ).toBeInTheDocument()
    await expect(
      canvas.getByText('This is the secondary text'),
    ).toBeInTheDocument()
    await expect(canvas.getByTestId('icon-info')).toBeInTheDocument()
  },
}

export const WithButton: Story = {
  ...Template,
  args,
  play: async ({ canvas, userEvent }) => {
    await expect(
      canvas.getByText('This is the primary text'),
    ).toBeInTheDocument()
    await expect(
      canvas.getByText('This is the secondary text'),
    ).toBeInTheDocument()
    await expect(canvas.getByTestId('icon-info')).toBeInTheDocument()

    const button = canvas.getByRole('button', { name: 'Click Me' })
    await expect(button).toBeInTheDocument()
    await userEvent.click(button)
    await expect(canvas.getByText('Button Clicked')).toBeInTheDocument()
  },
}

export const HideInfoIcon: Story = {
  ...Template,
  args: {
    ...args,
    hideInfoIcon: true,
  },
  play: async ({ canvas, userEvent }) => {
    await expect(
      canvas.getByText('This is the primary text'),
    ).toBeInTheDocument()
    await expect(
      canvas.getByText('This is the secondary text'),
    ).toBeInTheDocument()
    await expect(canvas.queryByTestId('icon-info')).toBeNull()

    const button = canvas.getByRole('button', { name: 'Click Me' })
    await expect(button).toBeInTheDocument()
    await userEvent.click(button)
    await expect(canvas.getByText('Button Clicked')).toBeInTheDocument()
  },
}

export const CloseButton: Story = {
  ...Template,
  args: {
    ...args,
    closeButtonCallout: () => {
      toast({
        message: 'Close Button Clicked',
        type: 'success',
      })
    },
  },
  play: async ({ canvas, userEvent }) => {
    await expect(
      canvas.getByText('This is the primary text'),
    ).toBeInTheDocument()
    await expect(
      canvas.getByText('This is the secondary text'),
    ).toBeInTheDocument()
    await expect(canvas.getByTestId('icon-info')).toBeInTheDocument()

    const button = canvas.getByRole('button', { name: 'Click Me' })
    await expect(button).toBeInTheDocument()
    await userEvent.click(button)
    await expect(canvas.getByText('Button Clicked')).toBeInTheDocument()

    const allXButtons = canvas.getAllByTestId('icon-x')
    const XButton = allXButtons[0] // First X button should be from the alert
    await userEvent.click(XButton)
    await expect(canvas.getByText('Close Button Clicked')).toBeInTheDocument()
  },
}
