import React, { createContext, ReactNode, useContext, useEffect, useState } from 'react'
import { observer } from 'mobx-react'
import { IState } from 'formstate-x'
import { FormItem as BaseFormItem, FormItemProps as BaseFormItemProps } from 'react-icecream'

export interface Props extends Omit<BaseFormItemProps, 'validateStatus' | 'validateMessage'> {
  state?: IState<unknown>
}

// Input 向上（`FormItem`）注册 state 的函数
type StateRegisterFn = (state?: IState<unknown>) => void

// Input 向上（`FormItem`）注册 state 的 context
const stateRegisterCtx = createContext<StateRegisterFn>(() => undefined)

export interface InputWrapperProps {
  state: IState | undefined
  children: ReactNode
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
function noop() {}

/**
 * 用来包裹 `FormItem` 中的 Input 组件内容：使得 `FormItem` 可以正确地感知到 Input 组件（及其对应的 state）
 * 注意适合 `FormItem` 对应单个 Input 组件的场景；若单个 `FormItem` 中包含了多个 Input 组件，
 * 需要通过给 `FormItem` 显式传递 prop state 来指定 `FormItem` 消费的 state
 */
export function InputWrapper({ state, children }: InputWrapperProps) {
  const registerState = useContext(stateRegisterCtx)
  useEffect(() => {
    registerState(state)
    return () => registerState(undefined)
  }, [registerState, state])
  return (
    <stateRegisterCtx.Provider value={noop}>
      {children}
    </stateRegisterCtx.Provider>
  )
}

export default observer(function FormItem({ state: stateFromProps, children, ...restProps }: Props) {
  const [innerState, setInnerState] = useState<IState<unknown>>()
  const state = stateFromProps ?? innerState
  const validateProps = state != null ? bindFormItem(state) : null
  return (
    <stateRegisterCtx.Provider value={setInnerState}>
      <BaseFormItem {...validateProps} {...restProps}>
        {children}
      </BaseFormItem>
    </stateRegisterCtx.Provider>
  )
})

/** 将 formstate-x state 绑定到 icecream FormItem 的辅助函数 */
export function bindFormItem(state: IState): Pick<BaseFormItemProps, 'validateStatus' | 'validateMessage'> {
  if (state.hasOwnError) {
    return {
      validateStatus: 'error',
      validateMessage: state.ownError
    }
  }
  // TODO: 有些 form item 需要在校验成功时显示成功样式（绿边）
  // 即 `validateStatus: 'success'`，需要支持下
  return { validateStatus: 'default' }
}
