import React, { ReactNode } from 'react'
import { Field, FieldConfig, IField, FieldInterface } from '../common'
import TextField from '../text'
import * as _ from 'lodash'
import NumberField from '../number'
import BooleanField from '../switch'

export interface AnyFieldConfig extends FieldConfig, FieldInterface {
  type: 'any'
}

export interface IAnyField {
  type: 'null' | 'string' | 'number' | 'boolean'
  value: null | string | number | boolean
  typeContent: ReactNode
  valueContent: ReactNode
}

export interface IAnyTypeField {
  type: 'null' | 'string' | 'number' | 'boolean'
  onChange: (type: 'null' | 'string' | 'number' | 'boolean') => void
}

export default class AnyField extends Field<AnyFieldConfig, IAnyField, null | string | number | boolean> implements IField<null | string | number | boolean> {
  TextField = TextField
  NumberField = NumberField
  BooleanField = BooleanField

  handleChangeType = (type: 'null' | 'string' | 'number' | 'boolean') => {
    const {
      value,
      onChange
    } = this.props
    if (type === 'null') {
      this.props.onValueSet('', null, true)
    } else if (type === 'string') {
      this.props.onValueSet('', value?.toString() || '', true)
    } else if (type === 'number') {
      const number = Number(value)
      if (Number.isNaN(number)) {
        this.props.onValueSet('', 0, true)
      } else {
        this.props.onValueSet('', number, true)
      }
    } else if (type === 'boolean') {
      this.props.onValueSet('', !!value, true)
    }
  }

  renderTypeComponent = (props: IAnyTypeField) => {
    return <React.Fragment>
      您当前使用的UI版本没有实现AnyField组件的TypeComponent。
    </React.Fragment>
  }

  renderComponent = (props: IAnyField) => {
    return <React.Fragment>
      您当前使用的UI版本没有实现AnyField组件。
    </React.Fragment>
  }

  render = () => {
    const {
      value,
      record,
      data,
      step,
      onChange
    } = this.props

    const type = typeof value

    return (
      <React.Fragment>
        {this.renderComponent({
          type: type === 'string' || type === 'number' || type === 'boolean' ? type : 'null',
          value,
          typeContent: this.renderTypeComponent({
            type: type === 'string' || type === 'number' || type === 'boolean' ? type : 'null',
            onChange: (type) => this.handleChangeType(type)
          }),
          valueContent: type === 'string' ? <this.TextField
            ref={() => {}}
            formLayout={'horizontal'}
            value={typeof value === 'string' ? value : ''}
            record={record}
            data={_.cloneDeep(data)}
            step={step}
            config={{ type: 'text', field: '', label: '' }}
            onChange={async (value: string) => { await onChange(value) }}
            onValueSet={this.props.onValueSet}
            onValueUnset={this.props.onValueUnset}
            onValueListAppend={this.props.onValueListAppend}
            onValueListSplice={this.props.onValueListSplice}
            onValueListSort={this.props.onValueListSort}
            baseRoute={this.props.baseRoute}
            loadDomain={this.props.loadDomain}
          /> : (
            type === 'number' ? <this.NumberField
              ref={() => {}}
              formLayout={'horizontal'}
              record={record}
              value={typeof value === 'number' ? value : ''}
              data={_.cloneDeep(data)}
              step={step}
              config={{ type: 'number', field: '', label: '' }}
              onChange={async (value) => { await onChange(Number(value)) }}
              onValueSet={async (path, value, validation) => await this.props.onValueSet(path, Number(value), validation)}
              onValueUnset={this.props.onValueUnset}
              onValueListAppend={this.props.onValueListAppend}
              onValueListSplice={this.props.onValueListSplice}
              onValueListSort={this.props.onValueListSort}
              baseRoute={this.props.baseRoute}
              loadDomain={this.props.loadDomain}
            /> : <this.BooleanField
              ref={() => {}}
              formLayout={'horizontal'}
              record={record}
              value={typeof value === 'boolean' ? value : false}
              data={_.cloneDeep(data)}
              step={step}
              config={{ type: 'switch', field: '', label: '' }}
              onChange={async (value) => { await onChange(Boolean(value)) }}
              onValueSet={this.props.onValueSet}
              onValueUnset={this.props.onValueUnset}
              onValueListAppend={this.props.onValueListAppend}
              onValueListSplice={this.props.onValueListSplice}
              onValueListSort={this.props.onValueListSort}
              baseRoute={this.props.baseRoute}
              loadDomain={this.props.loadDomain}
            />
          )
        })}
      </React.Fragment>
    )
  }
}