import { useBasedTranslation } from '@based/i18n'
import {
  Badge,
  IconButton,
  type IconProps,
  TEXT_VARIANT_STYLES,
  Tabs,
  type TabsProps,
  Text,
  type TextVariant,
  capitalize,
  radius,
  useToast,
} from '@based/ui'
import { colors } from '@based/ui'
import { type CSSProperties, useEffect, useState } from 'react'
import { getColorVariables, handleCopy } from '../helpers'
import type { TranslationsType } from '../i18n'
import { useTypedRoute } from '../router'

export const ColorItem = ({
  colorInfo,
  iconBadge,
  copyLabel,
  colorMode,
  isDarkMode,
  isStatic,
  onCLick,
}: Based.UI.Playground.Content.ColorItem): JSX.Element => {
  const [isHovered, setIsHovered] = useState(false)
  const borderColor = () => {
    if (isStatic) {
      return isDarkMode ? colors.white20 : colors.black20
    }
    return isDarkMode ? colors.neutral20Adjusted : colors.neutralInverted20
  }
  const textColor = () => {
    if (isStatic) {
      return isDarkMode ? 'white60' : 'black60'
    }
    return isDarkMode ? 'neutral60' : 'neutralInverted60'
  }

  return (
    <div
      style={{
        flexShrink: 1,
        width: '100%',
        minWidth: 72,
        height: 122,
        display: 'flex',
        flexDirection: 'column',
        position: 'relative',
        cursor: 'pointer',
        gap: 10,
      }}
      onClick={() => onCLick(colorInfo)}
      onKeyDown={() => onCLick(colorInfo)}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      {isHovered && (
        <div
          style={{
            position: 'absolute',
            width: '100%',
            height: 96,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            background: colors.neutralInverted60,
            borderRadius: radius[8],
          }}
        >
          <Badge color="neutral-fill" leadIcon={iconBadge}>
            {copyLabel}
          </Badge>
        </div>
      )}
      <span
        style={{
          flexShrink: 1,
          display: 'block',
          width: '100%',
          height: 96,
          background: colorInfo.hex,
          borderWidth: 1,
          borderStyle: 'solid',
          borderColor: borderColor(),
          borderRadius: radius[8],
        }}
      />
      <Text variant="subtext-mono" color={textColor()}>
        {colorInfo[colorMode] || colorInfo.name}
      </Text>
    </div>
  )
}

export const ColorRender = ({
  id,
  theme = 'dark',
  tag,
}: Based.UI.Playground.Content.Colors): JSX.Element => {
  const t = useBasedTranslation<TranslationsType>()
  const { params } = useTypedRoute()
  const toast = useToast()
  const { component } = params
  const isDarkMode = theme === 'dark'
  const isStatic = tag === 'static'
  const colorMode = component as keyof Based.UI.Playground.Content.Color
  const [copyLabel, setCopyLabel] = useState(
    t('content.blocks.icons.copy.button.copy'),
  )
  const [iconBadge, setIconBadge] = useState<IconProps['variant']>('copy')
  const [colorVariables, setColorVariables] = useState<
    Based.UI.Playground.Content.Color[]
  >([])

  useEffect(() => {
    const rafId = requestAnimationFrame(() => {
      setColorVariables(getColorVariables(colors, id))
    })

    return () => cancelAnimationFrame(rafId)
  }, [id])

  const handleCopied = (colorInfo: Based.UI.Playground.Content.Color) => {
    handleCopy(colorInfo[colorMode] || colorInfo.name)
    setIconBadge('checkmark')
    setCopyLabel(t('content.blocks.icons.copy.button.copied'))
    toast(
      `${colorInfo.name} ${t('content.blocks.icons.copy.button.copied').toLowerCase()}!`,
    )

    setTimeout(() => {
      setIconBadge('copy')
      setCopyLabel(t('content.blocks.icons.copy.button.copy'))
    }, 1000)
  }

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'row',
        gap: 16,
      }}
    >
      {colorVariables.map((colorInfo, index) => (
        <ColorItem
          key={`${index}-${colorInfo.name}`}
          colorInfo={colorInfo}
          iconBadge={iconBadge}
          copyLabel={copyLabel}
          colorMode={colorMode}
          isDarkMode={isDarkMode}
          isStatic={isStatic}
          onCLick={handleCopied}
        />
      ))}
    </div>
  )
}

export const TypographyRender = ({
  id,
  text,
}: Based.UI.Playground.Content.Typography): JSX.Element => {
  const t = useBasedTranslation<TranslationsType>()
  const toast = useToast()
  const [internalState, setInternalState] = useState('regular')

  const handleCopied = (cssInfo: string) => {
    handleCopy(cssInfo)
    toast(
      `${capitalize(id)} ${t('content.blocks.icons.copy.button.copied').toLowerCase()}!`,
    )
  }

  const getFontStylesByPrefix = (
    prefix: string,
  ): Record<TextVariant, CSSProperties> => {
    const result = {} as Record<TextVariant, CSSProperties>

    for (const [key, value] of Object.entries(TEXT_VARIANT_STYLES)) {
      if (key.startsWith(prefix)) {
        const suffix = key.replace(`${prefix}-`, '') as TextVariant
        result[suffix] = value
      }
    }

    return result
  }

  const buildTabsByStyle = (
    input: Record<TextVariant, CSSProperties>,
  ): TabsProps['tabs'] => {
    return Object.keys(input).map((key) => ({
      value: key,
      label: capitalize(key),
    }))
  }

  const typographyStyles = getFontStylesByPrefix(id)
  const typographyTabs = buildTabsByStyle(typographyStyles)
  const selectedVariant = `${id}-${internalState}` as TextVariant
  const css = JSON.stringify(
    typographyStyles[internalState as TextVariant],
  ).replace(/\\/g, '')

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: 16,
      }}
    >
      <div
        style={{
          display: 'flex',
          flexDirection: 'row',
          gap: 8,
        }}
      >
        <div
          style={{
            flex: 1,
          }}
        >
          <Tabs
            tabs={typographyTabs}
            value={internalState}
            onChange={setInternalState}
          />
        </div>

        <div
          style={{
            display: 'flex',
            flexDirection: 'row',
            gap: 8,
          }}
        >
          <IconButton
            icon="copy"
            onClick={() => handleCopied(css)}
            tooltip={t('content.blocks.icons.copy.tooltip.code')}
          />
        </div>
      </div>
      <div
        style={{
          height: 160,
          display: 'flex',
          alignItems: 'center',
        }}
      >
        <Text variant={selectedVariant}>
          {text || t('content.blocks.typography.defaultText')}
        </Text>
      </div>
      <Text variant="display-mono" color="neutral60">
        {css}
      </Text>
    </div>
  )
}

export const generateChartsRandomData = (): any => {
  const months = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
  ]
  const randomValue = () => Math.floor(Math.random() * 9001) + 1000

  return months.map((month) => ({
    month,
    Subscriptions: randomValue(),
    Sponsorship: randomValue(),
    'Ad revenue': randomValue(),
  }))
}
