import { ReactElement } from 'react';
import { Freeze, People, Travel } from '@transferwise/icons';
import { action } from 'storybook/actions';
import { fn } from 'storybook/test';
import ActionPrompt from './ActionPrompt';
import { Body, Title } from '../..';
import { StoryObj } from '@storybook/react-webpack5';
import { allModes } from '../../../.storybook/modes';
import { withVariantConfig } from '../../../.storybook/helpers';
import { lorem10 } from '../../test-utils';

const withComponentGrid =
  ({ gap = '1rem' } = {}) =>
  (Story: () => ReactElement) => (
    <div style={{ display: 'flex', flexDirection: 'column', gap }}>
      <Story />
    </div>
  );

export default {
  title: 'Prompts/ActionPrompt/Tests',
  component: ActionPrompt,
  tags: ['!manifest', '!autodocs', 'new'],
};

type Story = StoryObj<typeof ActionPrompt>;

export const VariousA11yFeatures: Story = {
  name: 'Various a11y features',
  render: () => {
    return (
      <Body>
        <Title type="title-body">Neutral Prompt with Avatar Image and Custom label for media</Title>
        <ActionPrompt
          className="m-b-2"
          sentiment="neutral"
          media={{
            'aria-label': 'Henry Profile Photo',
            avatar: { imgSrc: '../../avatar-square-dude.webp' },
          }}
          title="Henry requested 30 USD"
          description="Lunch date"
          action={{
            label: 'Sent',
            onClick: () => {
              action('send');
            },
          }}
          actionSecondary={{
            label: 'Decline',
            onClick: () => {
              action('decline');
            },
          }}
          onDismiss={() => action('dismiss')}
        />

        <Title type="title-body">Warning Prompt</Title>
        <ActionPrompt
          className="m-b-2"
          sentiment="warning"
          media={{
            'aria-label': 'Image of beautiful Business Wise Card',
            imgSrc: '../../wise-card.svg',
          }}
          title="Your Wise Card expires soon"
          description="Renew your card to keep spending"
          action={{
            label: 'Renew card',
            onClick: () => {
              action('renew');
            },
          }}
          actionSecondary={{
            label: 'Notify later',
            onClick: () => {
              action('notifyLater');
            },
          }}
          onDismiss={() => action('dismiss')}
        />

        <Title type="title-body">Warning Prompt Avatar Icon</Title>
        <ActionPrompt
          className="m-b-2"
          sentiment="warning"
          media={{ avatar: { asset: <Freeze /> } }}
          title="Your Wise Card expires soon"
          description="Renew your card to keep spending"
          action={{
            label: 'Renew card',
            onClick: () => {
              action('renew');
            },
          }}
          onDismiss={() => {
            action('dismiss');
          }}
        />

        <Title type="title-body">Proposition Prompt Avatar Icon</Title>
        <ActionPrompt
          className="m-b-2"
          sentiment="proposition"
          media={{ avatar: { asset: <People /> } }}
          title="Sync contacts for a faster experience"
          description="Find contacts on Wise — it’s simple, secure and you pick who you add."
          action={{
            label: 'Sync contacts',
            onClick: () => {
              action('sync');
            },
          }}
          onDismiss={() => {
            action('dismiss');
          }}
        />

        <Title type="title-body">Negative Prompt Avatar Icon + muted media</Title>
        <ActionPrompt
          className="m-b-2"
          sentiment="negative"
          media={{ avatar: { asset: <People /> }, 'aria-hidden': true }}
          title="Sync contacts for a faster experience"
          description="Find contacts on Wise — it’s simple, secure and you pick who you add."
          action={{
            label: 'Sync contacts',
            onClick: () => {
              action('sync');
            },
          }}
          onDismiss={() => {
            action('dismiss');
          }}
        />

        <Title type="title-body">
          Negative Prompt + override content with custom message via aria-label
        </Title>
        <ActionPrompt
          className="m-b-2"
          aria-label="hey customer, here is custom message"
          sentiment="negative"
          media={{ avatar: { asset: <People /> } }}
          title="Sync contacts for a faster experience"
          description="Find contacts on Wise — it's simple, secure and you pick who you add."
          action={{
            label: 'Sync contacts',
            onClick: () => {
              action('sync');
            },
          }}
          onDismiss={() => {
            action('dismiss');
          }}
        />
      </Body>
    );
  },
};

/**
 * ActionPrompt can be shown with or without a description.
 */
export const WithoutDescription: Story = {
  render: () => {
    return (
      <>
        <ActionPrompt
          sentiment="warning"
          title="Session expiring soon"
          action={{ label: 'Stay logged in', onClick: fn() }}
          actionSecondary={{ label: 'Log out', onClick: fn() }}
        />
        <ActionPrompt
          sentiment="success"
          title="Payment successful"
          action={{ label: 'View details', onClick: fn() }}
        />
        <ActionPrompt title="Quick action" action={{ label: 'Continue', onClick: fn() }} />
      </>
    );
  },
  decorators: [withComponentGrid()],
};

export const AllThemesAndSentiments: Story = {
  render: () => {
    return (
      <>
        {(['negative', 'warning', 'neutral', 'success', 'proposition'] as const).map(
          (sentiment) => (
            <ActionPrompt
              key={sentiment}
              sentiment={sentiment}
              title={`${sentiment.charAt(0).toUpperCase() + sentiment.slice(1)} action`}
              description="This demonstrates the prompt appearance in different themes."
              action={{ label: 'Primary', onClick: fn() }}
              actionSecondary={{ label: 'Secondary', onClick: fn() }}
              onDismiss={fn()}
            />
          ),
        )}
      </>
    );
  },
  decorators: [withComponentGrid({ gap: '1.5rem' })],
  parameters: {
    padding: '16px',
    variants: ['default', 'dark', 'bright-green', 'forest-green'],
    chromatic: {
      dark: allModes.dark,
      brightGreen: allModes.brightGreen,
      forestGreen: allModes.forestGreen,
    },
  },
};

export const TinyScreen: Story = {
  render: () => (
    <ActionPrompt
      sentiment="warning"
      title="Complete your profile"
      description="Add your business details to unlock all features and start sending money internationally."
      action={{ label: 'Complete profile', onClick: fn() }}
      actionSecondary={{ label: 'Remind me later', onClick: fn() }}
      onDismiss={fn()}
    />
  ),
  ...withVariantConfig(['400%']),
};

/**
 * ActionPrompt adapts its layout based on available width. At narrow widths (mobile),
 * the buttons stack vertically. At wider widths (desktop), they appear side by side.
 */
export const Responsiveness: Story = {
  render: (args) => (
    <div
      style={{
        display: 'grid',
        gridTemplateColumns: '320px 480px',
        gap: '1rem',
        alignItems: 'start',
      }}
    >
      <ActionPrompt
        sentiment="proposition"
        title="Stacked (320px)"
        description={lorem10}
        media={{ avatar: { asset: <Travel /> } }}
        action={{ label: 'Primary action', onClick: fn() }}
        actionSecondary={{ label: 'Secondary', onClick: fn() }}
        onDismiss={fn()}
      />
      <ActionPrompt
        sentiment="proposition"
        title="Side-by-side (480px)"
        description={lorem10}
        media={{ avatar: { asset: <Travel /> } }}
        action={{ label: 'Primary action', onClick: fn() }}
        actionSecondary={{ label: 'Secondary', onClick: fn() }}
        onDismiss={fn()}
      />
    </div>
  ),
  parameters: {
    docs: {
      canvas: {
        sourceState: 'hidden',
      },
    },
  },
};
