import * as React from 'react';
import Search from '@beisen-phoenix/search';
import utils from '@beisen-phoenix/common-utils';
import {AvatarProps} from '@beisen-phoenix/avatar';
import {ChrysanthemumLoading} from '@beisen-phoenix/loading';
import Button from '@beisen-phoenix/button';
import PlaceHolder from './placeHolder'
import trim from 'lodash/trim'
import Item from './item'
const classes = utils.BEMClass('lookup-list');
import './index.scss'
import {callFetch, getUpdateData} from '../../util.js'

export interface OptionsType {
    label?: string;
    sublabel?: string;
    value?: string;
    avator?: AvatarProps;
}

export interface ListProps {
    isSearchBox?: boolean;              //是否显示搜索框
    isAvator?: boolean;                 //是否显示头象
    multiple?: boolean;                 //是否多选，默认否
    moreText?: string;                  //全部查找标题
    noDataText?: string;                //没有数据提示
    isAdvanceVbl?: boolean;             //是否显示全部查找按钮
    options?: OptionsType[];            //列表值
    selectValue?: OptionsType[];        //选中值列表
    onSearchChange?: Function;          //搜过回调事件
    onSearchAllClick?: Function;       //全部查询
    onOk?: Function;                   //多选点击确认方法
    btnOkText?: string;                //自定义按钮名称
    formatData?: Function;             //格式化数据方法
    searchUrl?: string;                //动态请求url
    simpleListCount?: number;          //简单列表显示的记录数
    autoFocus?: boolean;               //简单模式，输入自动获得焦点
    translation?: {moreText: string,  noDataText: string, btnOkText: string}
}

const defaultTranslation = {moreText: '全部查找', noDataText: '这里什么都没有', btnOkText: '确定'};

export default class SimpleList extends React.Component<ListProps, any> {

    private inputRef: any = React.createRef()

    // 默认配置
    static defaultProps = {
        isSearchBox: true,
        isAvator: false,
        multiple: false,
        isAdvanceVbl: true,
        loading: false,
        selectValue: [],
        translation: defaultTranslation
    };

    constructor(props) {
        super(props);
        this.state={
            options: props.options || [],
            selectValue: props.selectValue,
            searchTip: '',
            loading: false,
            searchValue: ''
        }
    }

    componentDidMount() {
        const {options} = this.props

         if (options && options.length > 0) {
             return;
         }
         this.fetchSplData('')

        this.setSearchInputFocus()
    }

    componentDidUpdate (prevProps, prevState, snapshot) {
        let isUpdate = getUpdateData(['selectValue','options'], this.props, prevProps)
        if (isUpdate) {
            this.setState(isUpdate)
        }
    }

    //设置自动获取焦点
    setSearchInputFocus = () => {
        const { autoFocus } = this.props
        autoFocus && this.inputRef.current && this.inputRef.current.focus()
    }

    //搜索框输入超出200，截断提示
    validateSearch = (val) => {
        console .log(val)
        let res = { value: val, info: '' }
        if (val.length > 200) {
            return { value: val.slice(0, 200), info: '搜索字符不能大于200个',clearTipAfter:5000 }
        }
        return res
    }

    simpleSetData = (data)  => {
        this.setState(data)
    }

    filterOptionsData = (qryStr) => {
        let { options = [] } = this.props
        return trim(qryStr) == '' ? options : options.filter(n => {
            return n.label && n.label.indexOf(qryStr) > -1
        })
    }

    fetchSplData = (qryStr) => {
        const { searchUrl, formatData } = this.props
        this.setState({loading: true})
        let param = {
            key: qryStr || ''
        }
        if (searchUrl) {//拿到请求，直接内部发送请求
            callFetch(searchUrl, param , (res) => {
                this.simpleSetData({loading: false, options: formatData && formatData(res.data) || res.data})
            }, (res) => {
                this.simpleSetData({loading: false, options: []})
            })
        }
    }

    simpleFetchData = (qryStr) => {
        let { options } = this.props
        options ? this.simpleSetData({
            options:this.filterOptionsData(qryStr)
        }) : this.fetchSplData(qryStr)
    }

    handleSearch = (value) => {
        let tmpString = String(value)
        let finalString: string = tmpString;
        let tipInfo: string = '';
        //处理字数超200提示截断
        if (this.validateSearch) {
            const res = this.validateSearch(tmpString);
            if (res) {
                tipInfo = res.info;
                finalString = res.value;
                setTimeout(() => {this.setState({searchTip: ''})},3000);
            } else {
                tipInfo = '';
                finalString = tmpString;
            }
        }
        const val = finalString || tmpString;

        this.setState({
            searchValue: val,
            searchTip: tipInfo || ''
        })

        //搜索回调事件传入，则全部走外部搜索
        const {onSearchChange} = this.props
        if (onSearchChange) {
            onSearchChange(val)
        }

        this.simpleFetchData(val)
    }

    renderSearchInput = () => {
        const { isSearchBox, autoFocus } = this.props
        const { searchValue, searchTip } = this.state

        return isSearchBox ? <div className={classes({element: 'searchBox'})}>
                                <Search inputRef={node => {
                                    this.inputRef.current = node
                                }} value={searchValue} onChange={this.handleSearch} extend={searchTip} autoFocus={autoFocus} />
                            </div> : null
    }

    onSearchAllClick = () => {
        const { onSearchAllClick } = this.props
        const { selectValue } = this.state
        onSearchAllClick && onSearchAllClick(selectValue)
    }

    renderSearAllBtn = () => {
        const { isAdvanceVbl, moreText, translation = defaultTranslation} = this.props
        return isAdvanceVbl ? <div className={classes({element: 'searchAll-tool'})}>
                                <span className={classes({element: 'searchAll-tool-btn'})} onClick={this.onSearchAllClick}>{moreText || translation.moreText}</span>
                            </div> : null
    }

    onOk = (data) => {
        const { onOk } = this.props
        const {selectValue} = this.state
        //处理多选和单选时，取值问题
        let selectData = data && data.type == 'click' && selectValue || data
        if (onOk) {
            onOk(selectData)
        }
    }

    renderOkBtn = () => {
        const { multiple, btnOkText, translation = defaultTranslation } = this.props
        return multiple ? <div className={classes({element: 'footer-tool'})}>
            <Button onClick={this.onOk} size="small">{btnOkText || translation.btnOkText}</Button>
        </div> : null
    }

    //查询选中的节点
    getIsSelected = (selectValue, n) => {
        return !!(selectValue || []).find((v) => {
            return v.value == n.value
        })
    }

    renderContent = () => {
        const { isAvator, multiple, noDataText, simpleListCount, translation = defaultTranslation } = this.props
        const { options, selectValue, searchValue, loading} = this.state

        //数据加载中
        if (loading){
            return <ChrysanthemumLoading />
        }
        else {

            //数据为空，加载空数据
            if (options.length == 0){
                return <PlaceHolder translation={{noData: noDataText || translation.noDataText}} />
            }

            //渲染数据
            return ((options || []).slice(0,simpleListCount || 50)).map((n, index) => {
                return <Item
                    key={index}
                    {...n}
                    isAvator={isAvator}
                    onClick={this.onItemClick}
                    isSelected={this.getIsSelected(selectValue, n)}
                    searchWord={searchValue}
                    srcValue={n}
                    multiple={multiple}/>
            })
        }
    }

    onItemClick = (param) => {
        const { multiple} = this.props
        const { selectValue } = this.state
        const {isSelected, ...other} = param

        //处理多选和单选的情况，返回值都是数据
        let _value = isSelected ? (multiple ? selectValue || [] : []).concat([other]) :
                        (selectValue || []).filter((n) => { return n.value != param.value })

        this.setState({selectValue: _value})

        //如果单选则触发选中事件
        if (!multiple) {
            this.onOk(param)
        }
    }

    render() {
        const { isSearchBox, multiple, isAdvanceVbl } = this.props
        let searchInput = this.renderSearchInput()
        let searchAllBtn = this.renderSearAllBtn()
        let content = this.renderContent()
        let okBtn = this.renderOkBtn()
        let modifiers = {}
        let simpleClass = isSearchBox ? isAdvanceVbl ? 'simpleOnSearch' : 'simpleOnSearchNoMore'
                            : isAdvanceVbl ? 'simpleNoSearch' : 'simpleNoSearchNoMore'
        modifiers[simpleClass] = !multiple
        let multClass = 'ex' + (!isAdvanceVbl ? '-nomore' : '') + (!isSearchBox ? '-nosearch' : '')
        modifiers[multClass] = multiple

        return (
            <div className={classes({element: ''})}>
                {searchInput}
                <div className={classes({element: 'items', modifiers: modifiers
                    })}>
                    {content}
                </div>
                {searchAllBtn}
                {okBtn}
            </div>
        )
    }
}