import { Meta, StoryObj } from '@storybook/react-webpack5';
import SentimentSurface from './SentimentSurface';
import { storyConfig } from '../test-utils';
import type { Sentiment, Emphasis } from './SentimentSurface.types';

const withContainer = (Story: () => JSX.Element) => (
  <div style={{ display: 'flex', justifyContent: 'center', padding: '2rem' }}>
    <Story />
  </div>
);

const withComponentGrid = (Story: () => JSX.Element) => (
  <div
    style={{
      width: '100%',
      display: 'flex',
      flexDirection: 'column',
      gap: '1rem',
      maxWidth: '800px',
    }}
  >
    <Story />
  </div>
);

/**
 * SentimentSurface is a polymorphic container component that applies contextual background colours
 * and text styling based on sentiment types.
 */
const meta: Meta<typeof SentimentSurface> = {
  component: SentimentSurface,
  title: 'Content/SentimentSurface',
  argTypes: {
    sentiment: {
      control: 'select',
      options: ['negative', 'warning', 'neutral', 'success', 'proposition'],
      description: 'The sentiment type that determines the colour scheme',
    },
    emphasis: {
      control: 'select',
      options: ['base', 'elevated'],
      description: 'The emphasis level affecting background and text contrast',
      table: {
        defaultValue: { summary: 'base' },
      },
    },
    as: {
      control: 'text',
      description: 'The underlying HTML element to render',
      table: {
        defaultValue: { summary: 'div' },
      },
    },
    children: {
      control: 'text',
      description: 'Content to render inside the surface',
    },
    className: {
      control: 'text',
      description: 'Additional CSS classes',
    },
    id: {
      control: 'text',
      description: 'Unique identifier for the component',
    },
    testId: {
      control: 'text',
      description: 'Test ID for React Testing Library',
    },
  },
  args: {
    sentiment: 'neutral',
    emphasis: 'base',
    children: 'This is a sentiment surface',
  },
  decorators: [withContainer],
  parameters: {
    docs: {
      toc: true,
    },
  },
};

export default meta;

type Story = StoryObj<typeof SentimentSurface>;

/**
 * The Playground story allows you to experiment with all the props of the SentimentSurface component.
 * Use the controls below to customise the sentiment type, emphasis level, and content.
 */
export const Playground: Story = {
  args: {
    sentiment: 'negative',
    emphasis: 'base',
    children: (
      <div
        style={{
          padding: '24px',
          backgroundColor: 'var(--color-sentiment-background-surface)',
          color: 'var(--color-sentiment-content-primary)',
        }}
      >
        This is a custom div demostrating a sentiment surface.
      </div>
    ),
  },
};

/**
 * Each sentiment type has two emphasis levels – base and elevated – to provide different levels of visual prominence.
 */
export const EmphasisLevels: Story = {
  render: (args) => (
    <>
      <SentimentSurface {...args} sentiment="negative" emphasis="base">
        <div
          style={{
            padding: '24px',
            backgroundColor: 'var(--color-sentiment-background-surface)',
            color: 'var(--color-sentiment-content-primary)',
          }}
        >
          Negative - Base emphasis
        </div>
      </SentimentSurface>
      <SentimentSurface {...args} sentiment="negative" emphasis="elevated">
        <div
          style={{
            padding: '24px',
            backgroundColor: 'var(--color-sentiment-background-surface)',
            color: 'var(--color-sentiment-content-primary)',
          }}
        >
          Negative - Elevated emphasis
        </div>
      </SentimentSurface>
      <SentimentSurface {...args} sentiment="success" emphasis="base">
        <div
          style={{
            padding: '24px',
            backgroundColor: 'var(--color-sentiment-background-surface)',
            color: 'var(--color-sentiment-content-primary)',
          }}
        >
          Success - Base emphasis
        </div>
      </SentimentSurface>
      <SentimentSurface {...args} sentiment="success" emphasis="elevated">
        <div
          style={{
            padding: '24px',
            backgroundColor: 'var(--color-sentiment-background-surface)',
            color: 'var(--color-sentiment-content-primary)',
          }}
        >
          Success - Elevated emphasis
        </div>
      </SentimentSurface>
    </>
  ),
  parameters: {
    controls: { disable: true },
  },
  decorators: [withComponentGrid],
};

const sentiments: Sentiment[] = ['negative', 'warning', 'neutral', 'success', 'proposition'];
const emphasisLevels: Emphasis[] = ['base', 'elevated'];
const tokenCategories = [
  {
    name: 'Content',
    tokens: [
      '--color-sentiment-content-primary',
      '--color-sentiment-content-primary-hover',
      '--color-sentiment-content-primary-active',
    ],
  },
  {
    name: 'Interactive Primary',
    tokens: [
      '--color-sentiment-interactive-primary',
      '--color-sentiment-interactive-primary-hover',
      '--color-sentiment-interactive-primary-active',
    ],
  },
  {
    name: 'Interactive Secondary',
    tokens: [
      '--color-sentiment-interactive-secondary',
      '--color-sentiment-interactive-secondary-hover',
      '--color-sentiment-interactive-secondary-active',
    ],
  },
  {
    name: 'Interactive Control',
    tokens: [
      '--color-sentiment-interactive-control',
      '--color-sentiment-interactive-control-hover',
      '--color-sentiment-interactive-control-active',
    ],
  },
  {
    name: 'Background Surface',
    tokens: [
      '--color-sentiment-background-surface',
      '--color-sentiment-background-surface-hover',
      '--color-sentiment-background-surface-active',
    ],
  },
];

const TokenSwatch = ({ token }: { token: string }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '4px' }}>
    <div
      style={{
        width: '32px',
        height: '32px',
        borderRadius: '4px',
        backgroundColor: `var(${token})`,
        border: '1px solid rgba(0,0,0,0.1)',
        flexShrink: 0,
      }}
    />
    <code style={{ fontSize: '12px', color: 'var(--color-sentiment-content-primary)' }}>
      {token}
    </code>
  </div>
);

/**
 * Visual demonstration of the CSS custom properties (tokens) set by each sentiment and emphasis combination.
 * These tokens enable child components to automatically adapt their styling to the sentiment context.
 */
export const Tokens: Story = {
  render: () => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '32px', maxWidth: '100%' }}>
      {sentiments.map((sentiment) =>
        emphasisLevels.map((emphasis) => (
          <SentimentSurface
            key={`${sentiment}-${emphasis}`}
            sentiment={sentiment}
            emphasis={emphasis}
            style={{
              padding: '24px',
              borderRadius: '16px',
              backgroundColor: 'var(--color-sentiment-background-surface)',
              color: 'var(--color-sentiment-content-primary)',
            }}
          >
            <div style={{ marginBottom: '16px' }}>
              <strong
                style={{
                  fontSize: '16px',
                  textTransform: 'capitalize',
                }}
              >
                {sentiment} - {emphasis}
              </strong>
            </div>
            <div
              style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
                gap: '24px',
              }}
            >
              {tokenCategories.map((category) => (
                <div key={category.name}>
                  <div
                    style={{
                      fontSize: '12px',
                      fontWeight: 600,
                      marginBottom: '8px',
                      textTransform: 'uppercase',
                      letterSpacing: '0.5px',
                      opacity: 0.7,
                    }}
                  >
                    {category.name}
                  </div>
                  {category.tokens.map((token) => (
                    <TokenSwatch key={token} token={token} />
                  ))}
                </div>
              ))}
            </div>
          </SentimentSurface>
        )),
      )}
    </div>
  ),
  parameters: {
    controls: { disable: true },
  },
  decorators: [
    (Story: () => JSX.Element) => (
      <div style={{ padding: '2rem', maxWidth: '1200px' }}>
        <Story />
      </div>
    ),
  ],
};
