import Taro, { useState, useEffect } from '@tarojs/taro'
import { View, Text, Image, Picker } from '@tarojs/components'
import classnames from 'classnames'
import { formatArea } from '../../util'
import { getGlobalData, setGlobalData } from '../../util/global_data'
import { CustomLabel, ItemExtra, UnEditeableView } from '../index'
import './index.scss'
import arrowImg from '../../assets/ic_arrow_right.png'
// import { getUserCitySelection } from '../../service/global'

interface AreaProps {
  label: string
  value: string
  isLeaf?: boolean | undefined
  children: Array<AreaProps> | null | []
}

interface InputProps {
  help?: string
  itemExtra?: string
  maxLevel?: number
  name: string
  optionKey?: string
  parentSelectable?: boolean
  placeholder?: string
  term: string
  value?: any
  defaultValue?: any
  onChange?: (value) => void
  editable?: boolean
  required?: boolean
  underUserAuth?: boolean
  hidden?: boolean
  onView?: boolean
  getArea: () => Promise<any>
  loadData: (id: string) => Promise<any>
  getUserCitySelection: (id: string) => Promise<any>
  getAreaKey?: string
  loadDataKey?: string
  getUserCitySelectionKey?: string
  listItemChildren?: boolean
}

const UserCitySelection: React.FC<InputProps> = ({
  itemExtra,
  editable,
  name,
  hidden,
  term,
  value,
  onChange,
  help,
  required,
  maxLevel,
  defaultValue,
  onView,
  getArea,
  loadData,
  getUserCitySelection,
  getAreaKey,
  listItemChildren
}) => {

  const [stateValue, setStateValue] = useState<any>(value || defaultValue || [0, 0, 0])
  const [showText, setShowText] = useState<string | undefined>('')
  const [rangeData, setRangeData] = useState<Array<Array<AreaProps | any | any[]>>>([[], [], []])

  const saveArea = (proviceArr: Array<any> = [], cityArr: Array<any> = [], areaArr: Array<any> = [], communityArr: Array<any> = []) => {
    if (maxLevel === 1) {
      setRangeData([proviceArr])
    } else if (maxLevel === 2) {
      setRangeData([proviceArr, cityArr])
    } else if (maxLevel === 3) {
      setRangeData([proviceArr, cityArr, areaArr])
    } else {
      setRangeData([proviceArr, cityArr, areaArr, communityArr])
    }
  }

  const getAreaValue = () => {
    const globalId = getAreaKey || `area-${name}`
    return new Promise((resolve, reject) => {
      if (getGlobalData(globalId)) {
        handlerAreaData({ code: '0', content: getGlobalData(globalId) })
        resolve({ code: '0', content: getGlobalData(globalId) })
      } else if (getArea) {
        return getArea().then((res: any) => {
          if (res.code === '0') {
            setGlobalData(globalId, res.content)
            handlerAreaData(res)
            resolve(res)
          } else {
            reject()
          }
        })
      }
      reject()
    })
  }

  const handlerAreaData = (res) => {
    if (res.code === '0') {
      const proviceArr: any = formatArea(res.content)
      const cityArr = proviceArr[0].children
      const areaArr = proviceArr[0].children.length ? proviceArr[0].children[0].children : []
      if (areaArr[0]) {
        loadCommunityArrData(areaArr[0].value).then((communityArr: any) => {
          saveArea(proviceArr, cityArr, areaArr, communityArr)
        })
      } else {
        saveArea(proviceArr, cityArr, areaArr)
      }
    }
  }

  const loadCommunityArrData = (id: string) => {
    const globalId = `community-${id}`
    return new Promise((resolve, reject) => {
      if (getGlobalData(globalId)) {
        resolve(getGlobalData(globalId))
      } else if (loadData) {
        loadData(id).then((res) => {
          if (res) {
            resolve(res)
            setGlobalData(globalId, res)
          } else {
            reject()
          }
        })
      } else {
        reject()
      }
    })
  }

  const handlerGetUserCitySelectionValue = (showValue: string) => {
    const globalId = `userCityValue-${showValue}`
    return new Promise((resolve, reject) => {
      if (getGlobalData(globalId)) {
        resolve({ code: '0', content: getGlobalData(globalId) })
      } else if (getUserCitySelection) {
        getUserCitySelection(showValue).then((res) => {
          if (res.code === '0') {
            resolve(res)
            setGlobalData(globalId, res.content)
          } else {
            reject()
          }
        })
      } else {
        reject()
      }
    })
  }

  const getUserCitySelectionValue = () => {
    const showValue = value !== undefined ? value : defaultValue
    if (showValue) {
      handlerGetUserCitySelectionValue(showValue).then((res: any) => {
        if (res.code === '0') {
          setShowText(res.content.fullName)
          const initValue = res.content.fullName.split(',')
          getAreaValue().then((result: any) => {
            if (result.code === '0') {
              const proviceArr: any = formatArea(result.content)
              const cityArr = (initValue[0] && proviceArr.find(item => item.label === initValue[0])) ? proviceArr.find(item => item.label === initValue[0]).children : []
              const areaArr = (initValue[1] && cityArr.find(item => item.label === initValue[1])) ? cityArr.find(item => item.label === initValue[1]).children : []
              if (areaArr.length) {
                loadCommunityArrData(areaArr.find(area => area.label === initValue[2]).value).then((communityArr: any) => {
                  const proviceIndex = initValue[0] ? proviceArr.findIndex((item) => item.label === initValue[0]) : 0
                  const cityIndex = initValue[1] ? cityArr.findIndex((item) => item.label === initValue[1]) : 0
                  const areaIndex = initValue[2] ? areaArr.findIndex((item) => item.label === initValue[2]) : 0
                  const communityIndex = initValue[3] ? communityArr.findIndex((item) => item.label === initValue[3]) : 0
                  saveArea(proviceArr, cityArr, areaArr, communityArr)
                  setStateValue([proviceIndex, cityIndex, areaIndex, communityIndex])
                })
              } else {
                const proviceIndex = initValue[0] ? proviceArr.findIndex((item) => item.label === initValue[0]) : 0
                const cityIndex = initValue[1] ? cityArr.findIndex((item) => item.label === initValue[1]) : 0
                const areaIndex = initValue[2] ? areaArr.findIndex((item) => item.label === initValue[2]) : 0
                saveArea(proviceArr, cityArr, areaArr)
                setStateValue([proviceIndex, cityIndex, areaIndex])
              }
            }
          })
        }
      })
    } else {
      getAreaValue()
    }
  }

  useEffect(() => {
    getUserCitySelectionValue()
  }, [value])

  const pickerOnChange = (e) => {
    const { value } = e.detail
    const proviceId = value[0]
    const cityId = value[1]
    const areaId = value[2]
    const communityId = value[3]
    const empty = { label: '', value: '' }
    const provice = rangeData[0].find((item, index) => index === proviceId) || empty
    const city = rangeData[1] && rangeData[1].find((item, index) => index === cityId) || empty
    const area = rangeData[2] && rangeData[2].find((item, index) => index === areaId) || empty
    const community = rangeData[3] && rangeData[3].find((item, index) => index === communityId) || empty
    const newShowText = `${provice.label} ${city.label} ${area.label} ${community.label}`
    setShowText(newShowText)
    const newValue = community.value || area.value || city.value || provice.value
    if (onChange) {
      onChange(newValue)
    }
  }

  const onColumnChange = (e) => {
    const { column, value } = e.detail
    let proviceArr = []
    let cityArr = []
    let areaArr = []
    let communityArr = []
    if (column === 0) {
      proviceArr = rangeData[0] as never
      if (value === 0) {
        cityArr = []
        areaArr = []
        communityArr = []
      } else {
        cityArr = rangeData[0].find((item, index) => index === value).children as never
        areaArr = rangeData[0].find((item, index) => index === value).children[0].children as never
        communityArr = []
      }
    } else if (column === 1) {
      proviceArr = rangeData[0] as never
      cityArr = rangeData[1] as never
      areaArr = rangeData[1].find((item, index) => index === value).children as never
      communityArr = []
    } else if (column === 2) {
      loadCommunityArrData(rangeData[2][value].value).then((communityArr: any) => {
        saveArea(rangeData[0], rangeData[1], rangeData[2], communityArr)
      })
      return
    } else if (column === 3) {
      return
    }
    saveArea(proviceArr, cityArr, areaArr, communityArr)
  }

  if (hidden) {
    return null
  }


  if (editable === false || (editable === undefined && onView)) {
    return <UnEditeableView
      term={term}
      value={showText ? showText.split(',').join(' ') : ''}
      listItemChildren={listItemChildren}
      layout={showText && showText.length >= 20 ? 'column' : 'row'}
    />
  }

  const containerCLs = classnames(['wrap', listItemChildren ? 'item-container' : 'item-container-margin'])

  return (
    <View className={containerCLs}>
      <View className='city-picker-container'>
        <CustomLabel term={term} help={help} required={required} position />
        <Picker mode='multiSelector'
          onChange={pickerOnChange}
          value={stateValue}
          range={rangeData}
          rangeKey='label'
          onColumnChange={onColumnChange}
          disabled={editable}
        >
          <View className='city-picker-content'>
            <Text className='city-picker-text'>{showText ? showText.split(',').join(' ') : ''}</Text>
            <Image
              className="city-picker-arrow"
              mode="aspectFit"
              src={arrowImg}
            />
          </View>
        </Picker>
      </View>
      <ItemExtra text={itemExtra} />
    </View>
  )
}

export default UserCitySelection
