import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'
import {
  CustomInput,
  CustomDatePicker,
  Digit,
  CustomCheckboxGroup,
  Picture,
  RadioButtonGroup,
  UserCitySelection,
  CustomMap,
  CustomTextArea,
  MultilineText,
} from '../index'
import { AtButton } from 'taro-ui'
import { isEmpty } from '../../util'
import { phoneReg, linkReg } from '../../util/constants'
import { getArea, getUserCitySelection, loadData, getDicService } from '../../service/global'
import ListItem from './ListItem'
import './index.scss'
import '../index.scss'


interface Props {
  metaData: any
  defaultValue: any
  getFieldsValues?: (values: any) => void
  onView?: boolean
}

class Index extends Component<Props> {

  componentWillReceiveProps(nextProps) {
    const { defaultValue } = nextProps
    this.setState({ values: defaultValue })
  }

  state = {
    values: {},
    metaData: {},
  }

  formDataOnChange = (value, item, parentTerm) => {
    const { name } = item.props
    const { values } = this.state
    let newValues: any = []
    if (parentTerm) {
      newValues = {
        [parentTerm]: {
          ...values[parentTerm],
          [item.props.name]: value
        }
      }
    } else {
      newValues = {
        [name]: value
      }
    }

    this.setState({
      values: {
        ...values,
        ...newValues
      }
    })
  }

  getInitialValue = (init: any = '', values, parentTerm, name) => {
    let initValue = init
    if (values) {
      if (parentTerm && values[parentTerm] && values[parentTerm][name]) {
        initValue = values[parentTerm][name]
      } else {
        initValue = values[name]
      }
    }
    return initValue
  }

  renderFormItems = (formItems, listItemChildren?: boolean, parentTerm?: string) => {
    const { values } = this.state
    const { onView } = this.props
    return (
      formItems && formItems.map(
        (item) => {
          if (item.comp === 'Text') {
            return (
              <CustomInput
                onView={onView}
                name={item.props.name}
                term={item.props.term}
                onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
                key={item.name}
                value={this.getInitialValue('', values, parentTerm, item.props.name)}
                listItemChildren={listItemChildren}
              />
            )
          }
          if (item.comp === 'DateTime') {
            return <CustomDatePicker
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'Digit') {
            return <Digit
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'MultilineText') {
            if (Taro.getEnv() !== 'WEAPP') {
              return <MultilineText
                onView={onView}
                {...item.props}
                key={item.name}
                onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
                value={this.getInitialValue('', values, parentTerm, item.props.name)}
                listItemChildren={listItemChildren}
              />
            }
            return <CustomTextArea
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'SingleSelection') {
            return <RadioButtonGroup
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              loadDicData={getDicService}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'MultipleSelection') {
            return <CustomCheckboxGroup
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue([], values, parentTerm, item.props.name)}
              loadDicData={getDicService}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'MobilePhone') {
            return <CustomInput
              onView={onView}
              {...item.props}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              type='phone'
              key={item.name}
              value={this.getInitialValue([], values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'Link') {
            return <CustomInput
              onView={onView}
              {...item.props}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              type='link'
              key={item.name}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'Picture') {
            return <Picture
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue([], values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'UserCitySelection') {
            return <UserCitySelection
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              loadData={loadData}
              getArea={getArea}
              getUserCitySelection={getUserCitySelection}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'PositionMap') {
            return <CustomMap
              onView={onView}
              {...item.props}
              key={item.name}
              onChange={(value) => this.formDataOnChange(value, item, parentTerm)}
              value={this.getInitialValue('', values, parentTerm, item.props.name)}
              listItemChildren={listItemChildren}
            />
          }

          if (item.comp === 'ItemListPlus') {
            return <ListItem
              formItems={item.children}
              listItemChildren={true}
              parentTerm={item.props.name}
              onView={onView}
              values={values}
              formDataOnChange={this.formDataOnChange}
              getInitialValue={this.getInitialValue}
              term={item.props.term}
              help={item.props.help}
            />
          }
        }
      )
    )
  }

  onSubmit = () => {
    const { getFieldsValues, metaData } = this.props
    const { values } = this.state
    const { children } = metaData as any
    if (children && children.length) {
      const validatorArray = children.filter(item => item.props.required && item.props.name && !item.props.hidden)
      const formatValidatorArray = children.filter(item => item.props.name && !item.props.hidden)
      const validateChildrenArray = children.filter(item => item.children && item.children.length)
      const formatValidatorChildrenArray =
        children.filter(item => item.children && item.children.length && item.children.find(i => i.props.name && !i.props.hidden))

      const result = validatorArray.find(i => isEmpty(values[i.props.name]))
      if (result) {
        console.error('result', `${result.props.term}为必填项`)
        Taro.showToast({
          title: `${result.props.term} 为必填项`,
          icon: 'none'
        })
        return
      }

      const childrenResult = validateChildrenArray.map(item => item.children.find(i => {
        return i.props.required && !i.props.hidden && values[item.props.name] && isEmpty(values[item.props.name][i.props.name])
      })).filter(v => v)

      if (childrenResult && childrenResult.length) {
        console.error('result', `${childrenResult[0].props.term}为必填项`)
        Taro.showToast({
          title: `${childrenResult[0].props.term} 为必填项`,
          icon: 'none'
        })
        return
      }

      const phoneRegError = formatValidatorArray.filter(item => item.comp === 'MobilePhone')
        .find(i => values[i.props.name] && !phoneReg.test(values[i.props.name]))

      const phoneChildrenRegError = formatValidatorChildrenArray
        .map(item => item.children.filter(i => i.comp === 'MobilePhone').find(it => {
          return values[item.props.name] && values[item.props.name][it.props.name] && !phoneReg.test(values[item.props.name][it.props.name])
        }
        )).filter(v => v)

      if (phoneRegError) {
        console.error('regError', `${phoneRegError.props.term}格式错误`)
        Taro.showToast({
          title: `${phoneRegError.props.term} 格式错误`,
          icon: 'none'
        })
        return
      }

      if (phoneChildrenRegError && phoneChildrenRegError.length) {
        console.error('regError', `${phoneChildrenRegError[0].props.term}格式错误`)
        Taro.showToast({
          title: `${phoneChildrenRegError[0].props.term} 格式错误`,
          icon: 'none'
        })
        return
      }

      const linkRegError = formatValidatorArray.filter(item => item.comp === 'Link')
        .find(i => values[i.props.name] && !linkReg.test(values[i.props.name]))

      if (linkRegError) {
        console.error('regError', `${linkRegError.props.term}格式错误`)
        Taro.showToast({
          title: `${linkRegError.props.term} 格式错误`,
          icon: 'none'
        })
        return
      }

      const linkChildrenRegError = formatValidatorChildrenArray
        .map(item => item.children.filter(i => i.comp === 'Link').find(it => {
          return values[item.props.name] && !linkReg.test(values[item.props.name][it.props.name])
        }
        )).filter(v => v)

      if (linkChildrenRegError && linkChildrenRegError.length) {
        console.error('regError', `${linkChildrenRegError[0].props.term}格式错误`)
        Taro.showToast({
          title: `${linkChildrenRegError[0].props.term} 格式错误`,
          icon: 'none'
        })
        return
      }

      const digitError = formatValidatorArray.filter(item => item.comp === 'Digit')
        .find(i => values[i.props.name] && (String(values[i.props.name]).startsWith('.') || String(values[i.props.name]).endsWith('.') || String(values[i.props.name]) === '-0' || String(values[i.props.name]) === '-'))

      const digitChildrenError = formatValidatorChildrenArray
        .map(item => item.children.filter(i => i.comp === 'Digit')
          .find(it => values[item.props.name] && (String(values[item.props.name][it.props.name]).startsWith('.') || String(values[item.props.name][it.props.name]).endsWith('.') || String(values[item.props.name][it.props.name]) === '-0' || String(values[item.props.name][it.props.name]) === '-')
          )).filter(v => v)

      if (digitError) {
        console.error('digitError', `${digitError.props.term}格式错误`)
        Taro.showToast({
          title: `${digitError.props.term} 格式错误`,
          icon: 'none'
        })
        return
      }

      if (digitChildrenError && digitChildrenError.length) {
        console.error('digitError', `${digitChildrenError[0].props.term}格式错误`)
        Taro.showToast({
          title: `${digitChildrenError[0].props.term} 格式错误`,
          icon: 'none'
        })
        return
      }
    }
    if (getFieldsValues) {
      getFieldsValues(values)
    }
  }

  onEdit = () => {
    Taro.redirectTo({
      url: '/pages/index/index'
    })
  }

  render() {
    const { metaData, onView } = this.props
    // const platformStyle: any = Taro.getEnv() === 'WEAPP' ? {} : { overflowY: 'auto', height: '100%' }
    return (
      <View className='renderer-container' >
        {this.renderFormItems(metaData ? metaData.children : [])}
        <View>
          {onView ?
            <AtButton onClick={this.onEdit} type='secondary' className='submit-btn'>返回编辑</AtButton>
            : <AtButton onClick={this.onSubmit} type='primary' className='submit-btn'>提交</AtButton>}
        </View>
      </View>
    )
  }
}

export default Index