import { Meta } from '@storybook/blocks'
import { tokens } from '@channel.io/bezier-tokens/beta'
import { useState } from 'react'

import globalColor from '../../../bezier-tokens/src/beta/global/color.json'
import lightThemeColor from '../../../bezier-tokens/src/beta/semantic/light-theme/color.json'
import darkThemeColor from '../../../bezier-tokens/src/beta/semantic/dark-theme/color.json'

import {
  LightThemeProvider,
  DarkThemeProvider,
} from '~/src/components/ThemeProvider'
import { HStack, VStack } from '~/src/components/Stack'

<Meta title="foundation/Color" />

export const formatTitle = (title) =>
  title
    .split('-')
    .map((word) => (word ? word[0].toUpperCase() + word.slice(1) : word))
    .join(' ')

export const isTokenLeaf = (value) =>
  Boolean(value && typeof value.value === 'string')

export const normalizeTokenName = (name) =>
  name.endsWith('-normal') ? name.slice(0, -'-normal'.length) : name

export const getTokenName = (path) =>
  normalizeTokenName(`color-${path.join('-')}`)

export const sortNumericLeafEntries = (entries) => {
  const allNumericKeys = entries.every(([key]) => /^\d+$/.test(key))

  if (!allNumericKeys) {
    return entries
  }

  return [...entries].sort((a, b) => Number(a[0]) - Number(b[0]))
}

export const ColorSwatch = ({ name, value, reference }) => {
  const [isHovered, setIsHovered] = useState(false)
  const cssVar = `--${name}`
  const color = isHovered
    ? `var(${cssVar}-hovered, var(${cssVar}))`
    : `var(${cssVar})`
  const displayValue = reference || value
  const isReferenced = Boolean(reference)

  return (
    <VStack spacing={6} style={{ width: 160 }}>
      <div
        style={{
          width: '100%',
          height: 24,
          borderRadius: 6,
          backgroundColor: color,
          border: '1px solid var(--color-border-neutral, #e5e5e5)',
        }}
        onMouseEnter={() => {
          setIsHovered(true)
        }}
        onMouseLeave={() => {
          setIsHovered(false)
        }}
      />
      <div style={{ fontSize: 11, color: 'var(--color-text-neutral, #1a1a1a)' }}>
        {name}
      </div>
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 4,
          fontSize: 10,
          color: 'var(--color-text-neutral-light, #666)',
        }}
      >
        {isReferenced ? 'var' : ''}
        <span
          style={{
            display: 'inline-flex',
            fontSize: 'inherit',
            lineHeight: 'inherit',
            padding: '1px 2px',
            backgroundColor: 'var(--color-fill-neutral-light, #f2f2f2)',
            borderRadius: 3,
            border: '1px solid var(--color-border-neutral, #e5e5e5)',
          }}
        >
          {displayValue}
        </span>
      </div>
    </VStack>
  )
}

export const TokenGroup = ({
  title,
  data,
  path,
  source,
  depth,
  columns,
}) => {
  const entries = Object.entries(data)
  const leafEntries = sortNumericLeafEntries(
    entries.filter(([, value]) => isTokenLeaf(value))
  )
  const groupEntries = entries.filter(([, value]) => !isTokenLeaf(value))
  const headingSize = depth === 0 ? 20 : depth === 1 ? 16 : 14

  return (
    <VStack spacing={10} style={{ marginTop: depth === 0 ? 8 : 16 }}>
      <div
        style={{
          fontSize: headingSize,
          fontWeight: 600,
          color: 'var(--color-text-neutral, #1a1a1a)',
        }}
      >
        {formatTitle(title)}
      </div>
      {leafEntries.length > 0 && (
        <div
          style={
            columns
              ? {
                  display: 'grid',
                  gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
                  gap: 12,
                }
              : { display: 'flex', flexWrap: 'wrap', gap: 12 }
          }
        >
          {leafEntries.map(([key, value]) => {
            const tokenName = getTokenName([...path, key])
            const token =
              source[tokenName] ||
              source[`${tokenName}-normal`] ||
              {}

            return (
              <ColorSwatch
                key={tokenName}
                name={tokenName}
                value={token.value || value.value}
                reference={token.ref}
              />
            )
          })}
        </div>
      )}
      {groupEntries.map(([key, value]) => (
        <TokenGroup
          key={key}
          title={key}
          data={value}
          path={[...path, key]}
          source={source}
          depth={depth + 1}
          columns={columns}
        />
      ))}
    </VStack>
  )
}

export const GlobalSection = () => (
  <VStack spacing={16}>
    <div style={{ fontSize: 24, fontWeight: 700 }}>Global</div>
    {Object.entries(globalColor.color).map(([key, value]) => (
      <TokenGroup
        key={key}
        title={key}
        data={value}
        path={[key]}
        source={tokens.global.color}
        depth={0}
        columns={6}
      />
    ))}
  </VStack>
)

export const SemanticSection = ({
  title,
  colorData,
  source,
  titleColor,
  columns,
}) => (
  <VStack spacing={16} style={{ flex: 1 }}>
    <div
      style={{
        fontSize: 24,
        fontWeight: 700,
        color: titleColor || 'var(--color-text-neutral, #1a1a1a)',
      }}
    >
      {title}
    </div>
    {Object.entries(colorData.color).map(([key, value]) => (
      <TokenGroup
        key={key}
        title={key}
        data={value}
        path={[key]}
        source={source}
        depth={0}
        columns={columns}
      />
    ))}
  </VStack>
)

export const Primary = () => (
  <VStack spacing={32}>
    <GlobalSection />

    <HStack spacing={40} align="flex-start">
      <LightThemeProvider>
        <div style={{ flex: 1, padding: 16 }}>
          <SemanticSection
            title="Light"
            colorData={lightThemeColor}
            source={tokens.lightTheme.color}
            columns={1}
          />
        </div>
      </LightThemeProvider>

      <DarkThemeProvider>
        <div
          style={{
            flex: 1,
            padding: 16,
            backgroundColor: 'var(--color-surface, #1d1d20)',
            borderRadius: 12,
          }}
        >
          <SemanticSection
            title="Dark"
            titleColor="var(--color-text-neutral, #ffffcc)"
            colorData={darkThemeColor}
            source={tokens.darkTheme.color}
            columns={1}
          />
        </div>
      </DarkThemeProvider>
    </HStack>
  </VStack>
)

# Color

<Primary />

