import React, { useCallback } from 'react'
import {
  View,
  Text,
  StyleSheet,
  LayoutChangeEvent,
  ViewStyle,
  StyleProp,
} from 'react-native'
import { IObject } from 'interfaces'
import {
  useContextFixedColumnWidthUpdate,
  useContextHeaderHeight,
} from './context'
import { getStyleWidthValue } from './utils'
import type { TableTheme } from './theme'
import { sharedStyles } from './styles'
import TableRow, { Row } from './TableRow'
import type { TableColumn } from './TableTypes'
import SortIndicator from './SortIndicator'

type Props = {
  firstColumn: TableColumn
  data: Row[]
  tableObject: IObject
  datasource: { datasourceId: string; tableId: string }
  theme: TableTheme
}

const FixedColumn: React.FC<Props> = props => {
  const { firstColumn, data, tableObject, datasource, theme } = props
  const { setFixedColumnWidth, fixedColumnWidth } =
    useContextFixedColumnWidthUpdate(tableObject.id)
  const { headerHeight } = useContextHeaderHeight(tableObject.id)

  const onLayout = useCallback(
    (ev: LayoutChangeEvent) => {
      const { width = 0 } = ev.nativeEvent.layout
      const minWidth = getStyleWidthValue(firstColumn.style)
      const fixedWidth = Math.max(minWidth, width)
      setFixedColumnWidth(fixedWidth)
    },
    [firstColumn.style]
  )

  if (!firstColumn) {
    return null
  }

  const firstColumnData = data.map(rowData => {
    const { cells, ...other } = rowData
    return { cells: cells.slice(0, 1), ...other }
  })

  const { tableContainer } = theme
  const { backgroundColor, borderColor } = tableContainer

  const fixedContainerStyle: StyleProp<ViewStyle> = {
    backgroundColor,
    borderRightWidth: 1,
    borderRightColor: borderColor,
    borderStyle: 'solid',
    shadowColor: '#000',
    shadowOffset: { width: 4, height: 0 },
    shadowOpacity: 0.05,
    shadowRadius: 4,
  }

  const headerStyles: StyleProp<ViewStyle> = [
    sharedStyles.header,
    sharedStyles.headerCell,
    theme.header,
    {
      backgroundColor: theme.headerBackground.backgroundColor,
      minHeight: headerHeight,
    },
  ]

  let layoutStyles = {}
  if (fixedColumnWidth) {
    layoutStyles = { width: fixedColumnWidth }
  }

  return (
    <View
      style={[styles.fixedContent, fixedContainerStyle, layoutStyles]}
      onLayout={onLayout}
    >
      <View style={headerStyles} key={`${firstColumn?.label}_fixed`}>
        <Text style={[sharedStyles.headerText, theme.headerText]}>
          {firstColumn?.label}
        </Text>
        <SortIndicator theme={theme} direction={firstColumn?.sort} />
      </View>
      {firstColumnData.map((rowData: Row) => {
        return (
          <TableRow
            fixed
            datasource={datasource}
            data={rowData}
            theme={theme}
            tableObject={tableObject}
          />
        )
      })}
    </View>
  )
}

const styles = StyleSheet.create({
  fixedContent: {
    // Note that in react-native there's no `position: fixed` like in web.
    // We need to work around this by setting the position relative to the parent outside of the
    // Table's ScrollView
    position: 'absolute',
    top: 0,
    left: 0,
    zIndex: 2,
  },
})

export default FixedColumn
