import React, { useEffect, useState } from 'react'
import { Box } from '@native-base/formik-ui'
import { Factory, HStack } from 'native-base'
import { observer } from 'mobx-react-lite'
import type { EntityModelType, FieldConfig } from './EntityModel'
import { fieldValue, ViewType } from './EntityModel'
import { DataTable } from 'react-native-paper'
import { useLoadedItem } from './EntityTable'
import { LoadingSpinner } from './LoadingSpinner'

export const TTDataTable = Factory(DataTable)
export const TTDataTableHeader = Factory(DataTable.Header)
export const TTDataTableTitle = Factory(DataTable.Title)
export const TTDataTableRow = Factory(DataTable.Row)
export const TTDataTableCell = Factory(DataTable.Cell)

export type EntityDataProps<ModelType> = {
  model: EntityModelType

  // ID of the view data
  viewId?: string | number

  dataRowGenerator?: (field: FieldConfig<ModelType>, obj: ModelType, model: EntityModelType) => JSX.Element
}

function defaultDataRowGenerator(field: FieldConfig<any>, obj: any, model: EntityModelType) {
  return (
    // @ts-ignore
    <TTDataTableRow key={field.name}>
      <TTDataTableCell flex={2} justifyContent={'right'} pr={3}>
        {field.displayNameVal()}:
      </TTDataTableCell>
      <TTDataTableCell flex={4}>
        {field.inData?.cellComponent
          ? field.inData?.cellComponent(field, obj, model)
          : fieldValue(field, ViewType.DETAILS, obj)}
      </TTDataTableCell>
    </TTDataTableRow>
  )
}

export const EntityData: React.FC<EntityDataProps<any>> = observer(({ model, viewId, dataRowGenerator }) => {
  const [dataRowGeneratorFunc] = useState(() => (dataRowGenerator ? dataRowGenerator : defaultDataRowGenerator))
  const { loadingOpacity } = useLoadedItem(model)

  useEffect(() => {
    model.load(viewId!.toString())
  }, [model, viewId])

  useEffect(() => {}, [model.loadedItem])

  function includeField(f: FieldConfig<EntityModelType>) {
    return f.listableInDetailsVal()
  }

  return (
    <>
      <Box>
        {loadingOpacity != 1 && !model.loadedItem ? (
          <LoadingSpinner />
        ) : (
          <HStack>
            {loadingOpacity != 1 ? <LoadingSpinner /> : null}
            <TTDataTable opacity={loadingOpacity}>
              <>
                {model.config
                  .fieldsVal()
                  .filter(includeField)
                  .map((f) => dataRowGeneratorFunc(f, model.loadedItem, model))}
              </>
            </TTDataTable>
          </HStack>
        )}
      </Box>
    </>
  )
})
