import React, { Component } from 'react'
import { ActivityIndicator, View } from 'react-native'
import { decode } from 'he'
import styled from 'styled-components/native'
import Image from 'react-native-fast-image'
import TruncatedHTML from '../TruncatedHTML'
import BlockItemIcon from '../BlockItemIcon'
import { TouchableHighlight } from '../UI/Layout'
import BlockModalMenu from '../BlockModalMenu'
import { openModal } from '../Modal'
import navigationService from '../../utilities/navigationService'
import { Typography, Units, lineHeightFor } from '../../constants/Style'
import { baseStyles } from '../../constants/HtmlView'
import { getLayout } from '../../utilities/screenSize'
import { StyledText } from '../StyledText'

export const BLOCK_METADATA_HEIGHT = Units.scale[4] + Units.base

export const BLOCK_SIZES = () => ({
  '1-up': Units.window.width() - Units.scale[4] * 2,
  '2-up': Units.window.width() / 2 - Units.scale[1] * 3,
  '3-up': Units.window.width() / 3 - Units.scale[1] * 4,
  '4-up': Units.window.width() / 4 - Units.scale[1] * 5,
})

interface IContainerProps {
  size: TBlockItemSize
  onPress: () => void
  onLongPress: () => void
}

const Container = styled<IContainerProps>(TouchableHighlight)`
  width: ${x => BLOCK_SIZES()[x.size]};
  height: ${x => BLOCK_SIZES()[x.size] + BLOCK_METADATA_HEIGHT};
`

interface IOutlineProps {
  hasImage: boolean
  size: TBlockItemSize
}

const Outline = styled.View<IOutlineProps>`
  width: 100%;
  height: ${x => BLOCK_SIZES()[x.size]};
  border-width: ${({ theme, hasImage, size }) => (hasImage && size === '2-up' ? 0 : theme.borderWidth)};
  border-color: ${({ theme }) => theme.borderColor};
  overflow: hidden;
`

interface IThumbnailProps {
  cache: string
  source: {
    uri: string
    cache: string
  }
  resizeMode: string
}

const Thumbnail = styled<IThumbnailProps>(Image).attrs({
  resizeMode: 'contain',
})`
  width: 100%;
  height: 100%;
`
const Metadata = styled.View<IMetadataProps>`
  height: ${BLOCK_METADATA_HEIGHT};
  padding-top: ${Units.scale[2]};
`

const MetadataTitle = styled.View`
  flex-direction: row;
  align-items: center;
  justify-content: center;
`

interface ITitleProps {
  size: TBlockItemSize
}

const Title = styled(StyledText)<ITitleProps>`
  color: ${({ theme }) => theme.labels};
  font-size: ${x => Typography.fontSize[x.size === '1-up' ? 'base' : 'small']};
  line-height: ${x => lineHeightFor(x.size === '1-up' ? 'base' : 'small')};
  max-width: 90%;
  flex-basis: auto;
  text-align: center;
`

const ProcessingIndicator = styled(ActivityIndicator)`
  height: 100%;
`

export type TBlockItemSize = '4-up' | '3-up' | '2-up' | '1-up'

interface IBlockItemProps {
  size?: TBlockItemSize
  block: any
  channel?: any
  style?: any
}

export default class BlockItem extends Component<IBlockItemProps, {}> {
  onPress = () => {
    const { state } = this.props.block
    state === 'available' &&
      navigationService.navigate('block', {
        id: this.props.block.id,
        title: this.props.block.title,
      })
  }

  onLongPress = () => {
    const { block, channel } = this.props
    openModal({
      children: <BlockModalMenu block={block} channel={channel} />,
    })
  }

  render() {
    const {
      size,
      block,
      block: {
        state,
        kind: { __typename },
      },
      ...rest
    } = this.props
    const title = block.title ? decode(block.title) : null
    let inner
    switch (__typename) {
      case 'Attachment':
      case 'Embed':
      case 'Link':
      case 'Image':
        if (block.kind.image_url) {
          inner = (
            <Thumbnail
              cache="force-cache"
              source={{
                uri: block.kind.image_url,
              }}
            />
          )
        } else {
          inner = <View />
        }
        break
      case 'Text':
        inner = (
          <TruncatedHTML size={size} value={block.kind.content} numberOfFadedLines={1} stylesheet={baseStyles()} />
        )
        break
      default:
        inner = <StyledText>{block.title}</StyledText>
        break
    }
    if (state !== 'available' && state !== 'failed') {
      inner = <ProcessingIndicator />
    }
    return (
      <Container size={size} onPress={this.onPress} onLongPress={this.onLongPress} {...rest}>
        <Outline hasImage={!!block.kind.image_url} size={size}>
          {inner}
        </Outline>

        <Metadata size={size}>
          <MetadataTitle>
            {title && (
              <Title size={size} numberOfLines={1}>
                {title}
              </Title>
            )}

            <BlockItemIcon type={__typename} />
          </MetadataTitle>
        </Metadata>
      </Container>
    )
  }

  static defaultProps = {
    size: getLayout(['2-up', '3-up', '4-up']),
    channel: null,
  }
}

interface IMetadataProps {
  size: TBlockItemSize
}
