import {
  TouchableOpacity,
  View,
  Text,
  Image,
  StyleSheet,
  StyleProp,
  ImageStyle,
} from 'react-native'
import React from 'react'
import Icon from 'react-native-vector-icons/MaterialIcons'
import { actionTypes } from '@adalo/constants'
import { useDispatch } from 'react-redux'
import { getStore } from 'ducks'
import { executeAction } from 'utils/actions'
import { isURL } from 'utils/formats'
import { BottomButtons } from './buttons'
import {
  ActiveActionsType,
  BottomButtonActionType,
  ButtonActionType,
  InactiveActionsType,
  InputType,
  ListItemProps,
  HeaderActionType,
  ToggleBinding,
} from './types'

export const renderIcon = (
  value: string,
  size: number,
  color: string,
  style?: StyleProp<ImageStyle>
): JSX.Element => {
  if (!isURL(value)) {
    const name = value.replace(/_/g, '-')
    return <Icon name={name} size={size} color={color} style={style} />
  } else {
    return (
      <Image
        source={{ uri: value }}
        style={[{ width: size, height: size, tintColor: color }, style]}
      />
    )
  }
}

export const ListItem = (props: ListItemProps) => {
  const {
    background,
    header,
    content,
    bottomText,
    id,
    _meta: meta,
    object,
    getDatasources,
  } = props
  const { color, border, borderColor, borderWidth, borderRadius, padding } =
    background
  const {
    profilePicture,
    text1,
    text2,
    text3,
    rightIcon1Enabled,
    rightIcon1,
    rightIcon1Color,
    rightIcon2Enabled,
    rightIcon2,
    rightIcon2Color,
    styles: { text1: text1Styles, text2: text2Styles, text3: text3Styles },
  } = header
  const {
    topCaption,
    contentImage,
    styles: { topCaption: topCaptionStyles },
  } = content
  const {
    leftText,
    rightText,
    enabled: bottomTextEnabled,
    styles: { leftText: leftTextStyles, rightText: rightTextStyles },
  } = bottomText
  const backgroundStyles = {
    backgroundColor: color,
    borderWidth: border ? borderWidth : 0,
    borderColor,
    borderRadius,
    marginBottom: 4 + padding,
    paddingBottom: 14 + padding,
    paddingTop: 4 + padding,
  }
  const headerStyles = {
    paddingHorizontal: 4 + padding,
    marginBottom: 4 + padding,
  }
  const headerIconStyles = { margin: 4 + padding }
  const contentImageStyles = { marginTop: 4 + padding }
  const bottomTextContainerStyles = {
    paddingTop: 9 + padding,
    paddingHorizontal: 4 + padding,
  }

  const { datasourceId, tableId, collectionId } = meta

  const dispatch = useDispatch()

  const getBinding = (id: string): Record<string, any> | null => {
    if (id === object.attributes.items?.id) {
      return meta.record
    }

    return null
  }

  const bindingsKey = `${datasourceId}.${tableId || collectionId}`
  const getBindings = () => ({ [bindingsKey]: id })

  const runButtonAction = (actionString: BottomButtonActionType) => {
    const action =
      object.attributes?.buttons && object.attributes.buttons[actionString]

    if (action && object.actions) {
      const { actionId } = action
      executeAction(object.actions[actionId], {
        ...props,
        dispatch,
        getDatasources,
        getStore,
        getBinding,
        getBindings,
      })
    }
  }

  const runHeaderAction = (actionString: HeaderActionType) => {
    const action =
      object.attributes?.buttons && object.attributes.header[actionString]

    if (action && object.actions && object.actions[action?.actionId]) {
      const { actionId } = action
      executeAction(object.actions[actionId], {
        ...props,
        dispatch,
        getDatasources,
        getStore,
        getBinding,
        getBindings,
      })
    }
  }

  const runClickAction = () => {
    const action = object.attributes?.clickActions

    if (action && object.actions) {
      const { actionId } = action
      executeAction(object.actions[actionId], {
        ...props,
        dispatch,
        getDatasources,
        getStore,
        getBinding,
        getBindings,
      })
    }
  }

  const toggleAction = (val: boolean, prop?: ToggleBinding): void => {
    if (!prop) {
      return
    }

    const { source } = prop
    const action = {
      id: 'syntheticAction',
      actionType: val
        ? actionTypes.CREATE_ASSOCIATION
        : actionTypes.DELETE_ASSOCIATION,
      options: {
        fieldId: source?.source?.fieldId,
        object1: source?.source?.source,
        object2: source?.value,
        datasourceId,
        tableId,
      },
    }

    executeAction(
      { actions: [action] },
      { ...props, dispatch, getDatasources, getStore, getBinding, getBindings }
    )
  }

  const iconButtonAction = (
    type: 'icon' | 'toggle',
    val: boolean,
    setIconState: (state: boolean) => void,
    button: 'leftIcon1' | 'leftIcon2' | 'rightIcon'
  ): void => {
    const inputString = `${button}Input` as InputType
    const property =
      object.attributes?.buttons && object.attributes.buttons[inputString]

    if (type === 'icon') {
      const actionString = `onPress${
        button.charAt(0).toUpperCase() + button.slice(1)
      }` as ButtonActionType

      runButtonAction(actionString)
    } else {
      toggleAction(val, property)

      const actionString = val
        ? (`${button}ActiveActions` as ActiveActionsType)
        : (`${button}InactiveActions` as InactiveActionsType)

      runButtonAction(actionString)
      setIconState(val)
    }
  }

  return (
    <TouchableOpacity
      style={[styles.item, backgroundStyles]}
      onPress={runClickAction}
    >
      <View style={[styles.header, headerStyles]}>
        <View style={styles.headerLeft}>
          {profilePicture && (
            <Image source={profilePicture} style={styles.profilePicture} />
          )}
          <View style={styles.headerText}>
            {text1 && (
              <Text numberOfLines={1} ellipsizeMode="tail" style={text1Styles}>
                {text1}
              </Text>
            )}
            {text2 && (
              <Text numberOfLines={1} ellipsizeMode="tail" style={text2Styles}>
                {text2}
              </Text>
            )}
            {text3 && (
              <Text numberOfLines={1} ellipsizeMode="tail" style={text3Styles}>
                {text3}
              </Text>
            )}
          </View>
        </View>
        <View style={styles.headerIconsContainer}>
          {rightIcon1Enabled && rightIcon1 && (
            <TouchableOpacity
              onPress={() => runHeaderAction('onPressRightIcon1')}
            >
              {renderIcon(rightIcon1, 24, rightIcon1Color, [
                styles.headerIcon,
                headerIconStyles,
              ])}
            </TouchableOpacity>
          )}
          {rightIcon2Enabled && rightIcon2 && (
            <TouchableOpacity
              onPress={() => runHeaderAction('onPressRightIcon2')}
            >
              {renderIcon(rightIcon2, 24, rightIcon2Color, [
                styles.headerIcon,
                headerIconStyles,
              ])}
            </TouchableOpacity>
          )}
        </View>
      </View>
      {topCaption && (
        <Text
          style={[
            topCaptionStyles,
            styles.topCaption,
            { paddingHorizontal: 4 + padding },
          ]}
        >
          {topCaption}
        </Text>
      )}
      {!!contentImage && (
        <Image
          source={contentImage}
          style={[styles.contentImage, contentImageStyles]}
          resizeMode={
            object.attributes.content.cropImage === false ? 'contain' : 'cover'
          }
        />
      )}
      {bottomTextEnabled && (
        <View style={[styles.bottomTextContainer, bottomTextContainerStyles]}>
          <Text numberOfLines={1} style={leftTextStyles}>
            {leftText}
          </Text>
          <Text numberOfLines={1} style={rightTextStyles}>
            {rightText}
          </Text>
        </View>
      )}
      <BottomButtons
        {...props}
        iconButtonAction={iconButtonAction}
        bottomButtonAction={() => runButtonAction('onPressBottomButton')}
      />
    </TouchableOpacity>
  )
}

const styles = StyleSheet.create({
  item: {
    width: '100%',
  },
  profilePicture: {
    width: 50,
    height: 50,
    borderRadius: 25,
  },
  headerLeft: {
    flexDirection: 'row',
    alignItems: 'center',
    flexShrink: 1,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  headerText: {
    marginLeft: 10,
    justifyContent: 'center',
    flexShrink: 1,
  },
  headerIconsContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  headerIcon: {
    alignSelf: 'center',
  },
  topCaption: {
    paddingVertical: 5,
  },
  contentImage: {
    width: '100%',
    aspectRatio: 4 / 3,
  },
  bottomTextContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
})
