import React, { useMemo } from 'react'
import { observer } from 'mobx-react-lite'
import { FormScreen } from './FormScreen'
import type { NativeStackScreenProps } from '@react-navigation/native-stack'
import { createEntityForm } from './EntityForm'
import { useAppStore } from './store'
import { useFocusEffect } from '@react-navigation/native'
import type { EntityModelType } from './EntityModel'

type Props = NativeStackScreenProps<any, any>

const EntityCreateEditScreen: React.FC<Props> = observer((props) => {
  const appStore = useAppStore()
  const params = appStore.getRouteConfig(props.route)
  const relation = params.relation
  const entityModel = params.entityModel as EntityModelType
  const rootEntityModel = params.rootEntityModel
  const Form = useMemo(
    () => createEntityForm(),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [entityModel]
  )

  // Redefine onDeletePress on focus, which is also used by detail screen
  useFocusEffect(
    React.useCallback(() => {
      entityModel.config.entityListScreenConfig.onDeletePress = (_event, item, _config) => {
        entityModel.delete([item]).then((/*result*/) => {
          entityModel.reloadList()
          props.navigation.goBack()
          // For root entity models editing happens in the details view, so we need to go back 2 levels to the root model listing
          if (params.isRootModelCreateEdit === true) {
            props.navigation.goBack()
          }
        })
      }
    }, [entityModel, params.isRootModelCreateEdit, props.navigation])
  )

  return (
    <FormScreen>
      <Form
        model={entityModel}
        rootEntityModel={rootEntityModel}
        editId={entityModel.editId}
        currentRoute={props.route}
        navigation={props.navigation}
        create={
          !entityModel.editId && relation?.createNew
            ? (rootEntityModel, _model, values) => {
                return relation.createNew(appStore.gqlStore, rootEntityModel, entityModel, values, relation.fieldName)
              }
            : undefined
        }
        beforeSave={
          !entityModel.editId && relation?.prepareNew
            ? (rootEntityModel, _model, values) => {
                relation.prepareNew(appStore.gqlStore, rootEntityModel, entityModel, values, relation.fieldName)
              }
            : undefined
        }
        afterSave={(values: any) => {
          // fake a go back so that the details screen always leads back to the listing screen
          props.navigation.goBack()
          // Make sure the list's display is always up-to-date and includes the newly added item
          entityModel.reloadList()
          entityModel.setSelectedId(values.id)
          // We may edit a root entity or a related entity for a detail screen. Where we navigate from here
          // depends on isRootModelCreateEdit. In case it is true we navigate to the root mode's detail screen
          // if not, we navigate to the detial screen  of the edited related entity.
          // E.g. a TodoItem is edited in a TodoList:
          //  1. isRootModelCreateEdit==true --> got to TodoList's detail screen
          //  2. isRootModelCreateEdit==false --> got to TodoItem's detail screen
          appStore.navigate(
            props.navigation as any,
            params.isRootModelCreateEdit
              ? rootEntityModel.config.detailsScreenRouteNameVal()
              : entityModel.config.detailsScreenRouteNameVal(),
            {
              parentRoute: props.route.name,
              rootEntityModel: rootEntityModel,
              entityModel: entityModel,
            }
          )
        }}
        afterCancel={() => {
          props.navigation.goBack()
        }}
      />
    </FormScreen>
  )
})

export default EntityCreateEditScreen
