import { useBasedTranslation } from '@based/i18n'
import {
  Badge,
  CodeBlock,
  Icon,
  IconButton,
  Menu,
  Tabs,
  Text,
  capitalize,
  colors,
  radius,
  useTheme,
} from '@based/ui'
import { styled } from 'inlines'
import { type CSSProperties, useState } from 'react'
import { useRouter } from 'react-router5'
import { handleCopy } from '../helpers'
import type { TranslationsType } from '../i18n'
import { useTypedRoute } from '../router'
import { Preview } from './preview'
import { Title } from './title'

export const Block = ({
  componentName,
  blocks,
  name,
  id,
  type,
  style,
  description,
  render,
  code,
}: Based.UI.Playground.Content.Block) => {
  const t = useBasedTranslation<TranslationsType>()
  const { toggleTheme, theme: globalTheme } = useTheme()
  const { params } = useTypedRoute()
  const { section, component, state, view } = params
  const router = useRouter()
  const isComponents = type === 'component'
  const isColors = type === 'color'
  const isTypography = type === 'typography'
  const isFullscreen = view === 'fullscreen'
  const isCompact = !isFullscreen
  const renderString = render?.toString() ?? ''
  const [internalState, setInternalState] = useState<typeof state>(state)
  const isPreview = internalState === 'preview'
  const isCode = internalState === 'code'
  const isDarkMode = globalTheme === 'dark'
  const themeTooltip = isDarkMode
    ? t('navbar.buttons.theme.tooltip.light')
    : t('navbar.buttons.theme.tooltip.dark')
  const blockStyle: typeof style = {
    theme: 'dark',
    size: 'medium',
    frame: true,
    ...style,
  }
  const isBlockDarkMode = blockStyle.theme === 'dark'
  const isStatic = blockStyle.badge === 'static'

  const handleChangeBlock = (block: string) =>
    router.navigate('views', {
      section,
      component,
      block,
      state: 'preview',
      view,
    })

  const handleState = (
    block: string,
    newState: typeof state,
    view: 'fullscreen' | 'compact' = 'compact',
  ) => {
    setInternalState(newState)

    router.navigate('views', {
      section,
      component,
      block,
      state: newState,
      view,
    })
  }

  const blockBackgroundStyle = () => {
    if (isColors) {
      if (isStatic) {
        return isBlockDarkMode ? colors.black100 : colors.white100
      }
      return isBlockDarkMode ? colors.neutralInverted100 : colors.neutral100
    }

    if (isComponents) {
      return colors.neutralInverted100
    }
  }

  const getSize = () => {
    switch (blockStyle.size) {
      case 'small':
        return 200
      case 'medium':
        return 600
      case 'big':
        return 900
      default:
        return blockStyle.size
    }
  }

  const styles: { [key: string]: CSSProperties } = isCompact
    ? {
        container: {
          marginTop: 72,
          marginBottom: 72,
        },
        controls: {
          width: '100%',
          padding: 16,
          borderRadius: radius[16],
          border: `1px solid ${colors.neutral20Adjusted}`,
          background: blockBackgroundStyle(),
        },
        buttons: {
          display: 'flex',
          flexDirection: 'row',
          gap: 8,
          marginBottom: 16,
        },
        previewCode: {
          width: '100%',
          height: isPreview ? getSize() : '100%',
          borderRadius: radius[16],
          border: blockStyle.frame
            ? `1px solid ${colors.neutral20Adjusted}`
            : undefined,
          ...(blockStyle.flex && { display: 'flex', ...blockStyle.flex }),
          overflow: blockStyle.frame ? 'hidden' : undefined,
        },
        previewNonCode: {
          width: '100%',
          borderRadius: radius[8],
          overflow: 'hidden',
          position: 'relative',
          minHeight: 122,
        },
      }
    : {
        container: {
          height: '100%',
        },
        controls: {
          width: '100%',
          height: '100%',
        },
        buttons: {
          display: 'flex',
          flexDirection: 'row',
          gap: 8,
          paddingTop: 15,
          paddingBottom: 16,
          paddingLeft: 20,
          paddingRight: 20,
          borderBottom: `1px solid ${colors.neutral20Adjusted}`,
        },
        previewCode: {
          width: '100%',
          height: 'calc(100svh - 68px)',
          ...(blockStyle.flex && { display: 'flex', ...blockStyle.flex }),
        },
        previewNonCode: {
          width: '100%',
          height: '100%',
          overflow: 'auto',
          position: 'relative',
          minHeight: 192,
        },
      }

  const componentsTabs = [
    {
      value: 'preview',
      label: t('content.blocks.components.tabs.preview'),
    },
    {
      value: 'code',
      label: t('content.blocks.components.tabs.code'),
    },
  ]

  return (
    <div style={styles.container}>
      {isCompact && (
        <div
          style={{
            display: 'flex',
            flexDirection: 'column',
            gap: 8,
            marginBottom: 16,
          }}
        >
          <div
            style={{
              display: 'flex',
              flexDirection: 'row',
              alignItems: 'center',
              gap: 8,
            }}
          >
            <Text variant="subheading-bold">{name}</Text>
            {blockStyle.badge && (
              <Badge color="neutral-subtle">
                {capitalize(blockStyle.badge)}
              </Badge>
            )}
          </div>
          <Text variant="display-regular" color="neutral60">
            {description}
          </Text>
        </div>
      )}

      <div style={styles.controls}>
        {isComponents && (
          <div style={styles.buttons}>
            <div
              style={{
                display: 'flex',
                flex: 1,
                flexDirection: 'row',
                alignItems: 'center',
                gap: 8,
              }}
            >
              {isFullscreen && (
                <div
                  style={{
                    display: 'flex',
                    flexDirection: 'row',
                    alignItems: 'center',
                    gap: 16,
                    marginRight: 8,
                  }}
                >
                  <Title variant="title-bold-small">{componentName}</Title>
                  <Menu>
                    <Menu.Trigger>
                      {({ open }) => (
                        <styled.div
                          data-open={open}
                          style={{
                            display: 'flex',
                            alignItems: 'center',
                            gap: 8,
                            padding: '4px 8px 4px 10px',
                            margin: '0 -8px 0 -6px',
                            borderRadius: radius[8],
                            height: 36,
                            cursor: 'pointer',
                            '&:hover,&[data-open=true]': {
                              background: colors.neutral10Adjusted,
                            },
                          }}
                        >
                          <Text variant="display-medium">{name}</Text>
                          <Icon variant="chevron-down" />
                        </styled.div>
                      )}
                    </Menu.Trigger>
                    <Menu.Items>
                      {blocks?.map((block) => (
                        <Menu.Item
                          key={block.id}
                          leadIcon={
                            name === block.name ? 'checkmark' : undefined
                          }
                          indentContent={true}
                          onClick={() => handleChangeBlock(block.id)}
                        >
                          {block.name}
                        </Menu.Item>
                      ))}
                    </Menu.Items>
                  </Menu>
                </div>
              )}
              <Tabs
                tabs={componentsTabs}
                value={internalState}
                onChange={(value) =>
                  handleState(id, value as typeof state, view)
                }
              />
            </div>

            <div
              style={{
                display: 'flex',
                flexDirection: 'row',
                gap: 8,
              }}
            >
              {isFullscreen && (
                <IconButton
                  onClick={toggleTheme}
                  icon="boolean"
                  tooltip={themeTooltip}
                />
              )}
              <IconButton
                icon="copy"
                onClick={() => handleCopy(code || renderString)}
                tooltip={t('content.blocks.icons.copy.tooltip.code')}
              />
              <IconButton
                icon={isFullscreen ? 'full-screen-off' : 'full-screen'}
                onClick={() => {
                  handleState(
                    id,
                    internalState,
                    isFullscreen ? 'compact' : 'fullscreen',
                  )
                }}
                tooltip={
                  isFullscreen
                    ? t('content.blocks.icons.fullscreen.tooltip.off')
                    : t('content.blocks.icons.fullscreen.tooltip.on')
                }
              />
            </div>
          </div>
        )}

        {isComponents && (
          <div style={styles.previewCode}>
            {isPreview && <Preview code={renderString} />}
            {isCode && (
              <CodeBlock
                copy={false}
                border={false}
                language="tsx"
                code={code || renderString}
              />
            )}
          </div>
        )}

        {(isColors || isTypography) && (
          <div style={styles.previewNonCode}>
            <Preview code={renderString} />
          </div>
        )}
      </div>
    </div>
  )
}
