import type { Meta, StoryObj } from '@storybook/react'
import { tokens } from '../../theme/tokens/tokens'
import { viewports } from '../../utils/viewports'
import { colorVariants } from './foregroundColors'
import { Typography } from './Typography'
import { allVariants, typographyVariants } from './variants'

const colorVariantsKeys = Object.keys(colorVariants)
const variantsKeys = Object.keys(allVariants)

const findTokenValue = (tokenName: string) => {
  for (const category of Object.values(tokens)) {
    if (category[tokenName]) {
      return {
        light: category[tokenName].light.replace('var(--', '').replace(')', ''),
        dark: category[tokenName].dark.replace('var(--', '').replace(')', ''),
      }
    }
  }
  return null
}

const meta: Meta<typeof Typography> = {
  component: Typography,
  title: 'Typography/Typography',
  parameters: {
    chromatic: { viewports: [viewports.all] },
  },
  argTypes: {
    variant: {
      description:
        'Defines the style of the text, such as header, body, code, or display. <br />Available variants:',
      control: {
        type: 'select',
        labels: variantsKeys,
      },
      value: 'body',
      options: variantsKeys,
      table: {
        type: { summary: variantsKeys.join(' | ') },
        defaultValue: { summary: 'body' },
      },
    },
    children: {
      control: 'text',
      description:
        'The content to be rendered. Can be a string, or a React element when `asChild` is true.',
      table: {
        type: { summary: 'string | React.ReactNode' },
      },
    },
    color: {
      description:
        'Allows you to set the text color. The values for this prop correspond to blocks design system tokens. <br /> Available colors:',
      control: {
        type: 'select',
        labels: colorVariantsKeys,
      },
      value: 'foreground',
      options: colorVariantsKeys,
      table: {
        type: { summary: colorVariantsKeys.join(' | ') },
        defaultValue: { summary: 'foreground' },
      },
    },
    asChild: {
      description:
        'Renders the Typography component as the specified child element, allowing more control over the rendered HTML element.',
      control: false,
      table: {
        type: { summary: 'boolean' },
        defaultValue: { summary: 'false' },
      },
    },
  },
}

export default meta

type Story = StoryObj<typeof Typography>

export const Default: Story = {
  args: {
    children: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  },
}

export const Display: Story = {
  render: (_args) => (
    <div>
      <Typography variant="display-xl">Display XL</Typography>
      <Typography variant="display-l">Display L</Typography>
      <Typography variant="display">Display M</Typography>
      <Typography variant="display-s">Display S</Typography>
      <Typography variant="display-xs">Display XS</Typography>
    </div>
  ),
}

export const Headers: Story = {
  render: (_args) => (
    <div>
      <Typography variant="h1">TypographyH1</Typography>
      <Typography variant="h2">TypographyH2</Typography>
      <Typography variant="h3">TypographyH3</Typography>
      <Typography variant="h4">TypographyH4</Typography>
      <Typography variant="h5">TypographyH5</Typography>
      <Typography variant="h6">TypographyH6</Typography>
    </div>
  ),
}

export const Body: Story = {
  render: (_args) => (
    <div>
      <Typography variant="body-xl">Body XL</Typography>
      <Typography variant="body-semi-xl">Body Semi XL</Typography>
      <Typography variant="body-l">Body L</Typography>
      <Typography variant="body-semi-l">Body Semi L</Typography>
      <Typography variant="body">Body M</Typography>
      <Typography variant="body-semi">Body Semi M</Typography>
      <Typography variant="body-s">Body S</Typography>
      <Typography variant="body-semi-s">Body Semi S</Typography>
      <Typography variant="body-xs">Body XS</Typography>
      <Typography variant="body-semi-xs">Body Semi XS</Typography>
    </div>
  ),
}

export const Code: Story = {
  render: (_args) => (
    <div>
      <Typography variant="code-xxl">Code XXL</Typography>
      <Typography variant="code-xl">Code XL</Typography>
      <Typography variant="code-l">Code L</Typography>
      <Typography variant="code">Code</Typography>
      <Typography variant="code-s">Code S</Typography>
      <Typography variant="code-xs">Code XS</Typography>
    </div>
  ),
}

export const Composition = (_args: any) => (
  <div className="flex flex-col gap-4">
    <Typography variant="h2" asChild>
      <span>This is a h2 styled span using the asChild prop</span>
    </Typography>
    <span className={typographyVariants({ variant: 'h2' })}>
      This is a h2 styled span using the typographyVariants helper
    </span>
    <Typography variant="code-s" asChild>
      <button type="button">
        This is a code-s styled button using the asChild prop
      </button>
    </Typography>
    <button className={typographyVariants({ variant: 'code-s' })}>
      This is a code-s styled button using the typographyVariants helper
    </button>
    <Typography variant="body-xl" color="link" asChild>
      <a href="#demo">
        This is a body-xl styled link colored anchor tag using the asChild prop
      </a>
    </Typography>
    <a
      className={typographyVariants({ variant: 'body-xl', color: 'link' })}
      href="#demo"
    >
      This is a body-xl styled link colored anchor tag using the
      typographyVariants helper
    </a>
  </div>
)

export const Colors = (_args: any) => (
  <>
    <Typography color="foreground">Foreground</Typography>
    <Typography color="link">Link</Typography>
    <Typography color="brand">Brand</Typography>
    <Typography color="muted">Muted</Typography>
    <Typography color="muted-more">Muted More</Typography>
    <Typography color="success">Success</Typography>
    <Typography color="error">Error</Typography>
    <Typography color="warning">Warning</Typography>
    <Typography color="progress">Progress</Typography>
  </>
)

export const AllColors = (_args: any) => (
  <div className="flex flex-col gap-8 bg-background p-8">
    {Object.entries(colorVariants).map(([key, value]) => {
      const tokenName = value.replace('text-', '')
      const tokenValue = findTokenValue(tokenName)

      if (!tokenValue) {
        return null
      }

      return (
        <div key={key} className="flex flex-col gap-1">
          <Typography variant="h4" color="foreground">
            {key}
          </Typography>
          <Typography variant="body" color="muted">
            --{tokenName}
          </Typography>
          {tokenValue && (
            <div className="grid max-w-[500px] grid-cols-2 gap-8">
              <div className="flex flex-col gap-1 rounded-lg bg-muted p-4">
                <Typography
                  className="text-5xl font-semibold"
                  color={key as keyof typeof colorVariants}
                >
                  Light
                </Typography>
                <Typography variant="body">{tokenValue.light}</Typography>
              </div>

              <div className="dark flex flex-col gap-1 rounded-lg bg-muted p-4">
                <Typography
                  className="dark text-5xl font-semibold"
                  color={key as keyof typeof colorVariants}
                >
                  Dark
                </Typography>
                <Typography variant="body">{tokenValue.dark}</Typography>
              </div>
            </div>
          )}
        </div>
      )
    })}
  </div>
)

Colors.parameters = {
  themes: {
    defaultTheme: 'light',
    disable: true,
  },
}

export const Muted: Story = {
  args: {
    ...Default.args,
    color: 'muted',
    children: 'This is a muted paragraph.',
  },
}

export const AsDiv: Story = {
  args: {
    ...Default.args,
    asChild: true,
    variant: 'h5',
    children: <div>16</div>,
  },
}

export const AsSpan: Story = {
  args: {
    ...Default.args,
    asChild: true,
    children: (
      <span>This looks like a paragraph, but it is actually a span.</span>
    ),
  },
}

export const AllVariants: Story = {
  render: (_args) => (
    <div className="flex flex-col gap-4">
      <Typography variant="h1">TypographyH1</Typography>
      <Typography variant="h2">TypographyH2</Typography>
      <Typography variant="h3">TypographyH3</Typography>
      <Typography variant="h4">TypographyH4</Typography>
      <Typography variant="h5">TypographyH5</Typography>
      <Typography variant="h6">TypographyH6</Typography>
      <Typography variant="body-xl">Body XL</Typography>
      <Typography variant="body-semi-xl">Body Semi XL</Typography>
      <Typography variant="body-l">Body L</Typography>
      <Typography variant="body-semi-l">Body Semi L</Typography>
      <Typography variant="body">Body M</Typography>
      <Typography variant="body-semi">Body Semi M</Typography>
      <Typography variant="body-s">Body S</Typography>
      <Typography variant="body-semi-s">Body Semi S</Typography>
      <Typography variant="body-xs">Body XS</Typography>
      <Typography variant="body-semi-xs">Body Semi XS</Typography>
      <Typography variant="code-xxl">Code XXL</Typography>
      <Typography variant="code-xl">Code XL</Typography>
      <Typography variant="code-l">Code L</Typography>
      <Typography variant="code">Code</Typography>
      <Typography variant="code-s">Code S</Typography>
      <Typography variant="code-xs">Code XS</Typography>
    </div>
  ),
}
