import * as React from 'react'
import './index.scss'
import utils from '@beisen-phoenix/common-utils'
import SelectedPanel from './SelectedPanel'
import {OptionsType} from "../simpleList"
import isEmpty from 'lodash/isEmpty'
import clonedeep from 'lodash.clonedeep'
//import BasicTable from '@beisen-phoenix/data-table'
import BasicTable from '@beisen-phoenix/table'
import SearchForm from '@beisen-phoenix/search-form'
const classes = utils.BEMClass('lookup-advanced')
import {callFetch, getUpdateData, resetCalculateHeight, calculateModalHeight,getValueUseKey} from '../../util.js'


export interface AdvancedProps {
    searchFormMeta?: any;                  //searchForm的数据描述
    tableMeta?: any;                       //table的数据描述
    advMetaParam?: Object;                 //请求advMetaUrl时，发送的数据
    advMetaUrl?: string | Function;        //form和table的元数据请求接口
    advFormatListData?: Function;            //格式化table数据
    advFormatMetaData?: Function;             //格式化Meta数据,searchform和table描述数据
    advanceSearchUrl?: string;              //searchform改变后，发送获取table数据的请求url
    advanceSearchFunction?: Function;       //searchform改变后，回调函数
    modalSize?: string;                     //高级弹窗大小
    maxSize?: number;                       //多选模式下，最大选择数量
    getContainer?: Function;                //modal的dom节点
    tablePrimaryKey?: string;               //table的主键
    modalHeight?: string;                   //高级弹窗高度

    dlgTitle?:  string;                //高级弹窗标题
    multiple?: boolean;                //列表多选
    selectValue?: OptionsType[];       //选中值列表
    translation?: {clearSelected: string, selected: string, emptyMsg: string}
}


///多选中后列表
export default class AdvancedCmpt extends React.Component<AdvancedProps, any> {
    // 默认配置
    static defaultProps = {
        tablePrimaryKey: 'value'
    };

    private tableRef = React.createRef()

    constructor(props) {
        super(props);
        this.state = {
            selectValue: props.selectValue || [],
            searchFormMeta: props.searchFormMeta || [],
            tableMeta: props.tableMeta || [],
            scrollY: 0,
            clientHeight: calculateModalHeight(props.modalHeight, 116),
            isReSizeHeight: false,
            current: 0,
            pagination: props.pagination || {
                pageIndex: 0,
                pageSize: 15
            },
            loading: false,
            searchParam: {}
        }

        this.clearItem = this.clearItem.bind(this);
    }

    componentDidMount() {
        const {advMetaParam, advMetaUrl, advFormatMetaData} = this.props
        //发送获取searchForm\table数据描述接口
        if (advMetaParam && advMetaUrl) {
            this.resetLoading(true)
            callFetch(advMetaUrl, advMetaParam, advFormatMetaData , (res) => {
                let data = advFormatMetaData && advFormatMetaData(res.data)
                this.setState({
                    searchFormMeta: data.searchFormMeta || [],
                    tableMeta: data.tableMeta || [],
                    loading: false
                })
            }, (res) => {
                this.resetLoading(false)
            })
        }
    }

    resetCalcHeight = () => {
        const { multiple } = this.props
        //此判断仅限于lookup嵌入到Modal内的计算
        let data = resetCalculateHeight('.phoenix-lookup-advanced__mainContainer', 72)
        if (data) {
            this.setState(Object.assign(data, {isReSizeHeight: true}))
        }
    }

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


        const { isReSizeHeight } = this.state
        if (!isReSizeHeight){
            setTimeout(this.resetCalcHeight, 200)
        }
    }

    clearItem = (item) => {
        let data = this.state.selectValue.filter(n => {
            return (n.value != item.value || n.key != item.key)
        })
        this.setState({
            selectValue: data
        })
    }

    clearAll = () => {
        this.setState({selectValue: []});
    }

    renderSelectedPanel () {

        const { multiple, translation, maxSize } = this.props
        const { selectValue, clientHeight } = this.state

        return multiple ? <div className={classes({element: 'selected'})} style={{height: clientHeight + 'px'}}>
                            <SelectedPanel translation={translation} maxSize={maxSize} data={selectValue} onClearItem={this.clearItem}  onClearAll={this.clearAll} />
                        </div> : null
    }

    resetLoading = (loading) => {
        this.setState({
            loading: loading
        })
    }

    initTableData = (param, pagination, data) => {
        const { advFormatListData } = this.props
        const { tableMeta } = this.state
        let rdata = advFormatListData && advFormatListData(data) || data
        tableMeta.data = rdata || []
        this.setState({
            tableMeta : tableMeta,                                     //table的数据
            searchParam: Object.assign(param, pagination),             //保存搜索条件
            loading: false,
            isReSizeHeight: false
        })
    }

    getListInfo = (param, pagination) => {
        const { advanceSearchUrl, advanceSearchFunction, advMetaParam } = this.props
        const { tableMeta } = this.state
        this.setState(Object.assign({isReSizeHeight: true}, {pagination: pagination}))
        //调用外部函数
        if (advanceSearchFunction) {
            advanceSearchFunction(param, (data)=> {
                this.initTableData(param, pagination, data)
            })
        }//调用外部接口，内部发请求
        else if(advanceSearchUrl) {
            this.resetLoading(true)
            callFetch(advanceSearchUrl, Object.assign(param, advMetaParam) , (res) => {
                this.initTableData(param, pagination, res.data)
            }, (res) => {
                this.resetLoading(false)
                console.log(res)
            })
        }//其他情况不成立，将外部初始化的数据传回
        else {
            this.initTableData(param, pagination, tableMeta.data)
        }
    }

    onSearchFormChange = (value) => {
        let {pagination} = this.state
        this.getListInfo(value, clonedeep(pagination))
    }

    tableOnChange = (data) => {
        let {searchParam} = this.state
        let pagination = {
            pageIndex: data.current,
            pageSize: data.pageSize
        }

        this.getListInfo(clonedeep(searchParam), clonedeep(pagination))
    }

    getSelected = () => {
        //return (this.tableRef.current as any).getSelectRows()
        return this.state.selectValue
    }

    //合并table选择的数据
    getSelectedRowsData = (rows) => {
        const { selectValue } = this.state
        let _rows = (rows || []).filter(n => {
            return !(selectValue || []).find((s) => {
                return n.key == s.key
            })
        })

        return (selectValue || []).concat(_rows || [])
    }

    renderTable = () => {

        const { tableMeta, scrollY, pagination, loading, selectValue } = this.state
        const { multiple, tablePrimaryKey } = this.props
        //统一属性，统一返回值信息，此处存在一个问题，就是默认的返回值与列表的返回值会存在差异，看是否有人提出再进行处理
        const transformObjData = (data) => {
            return Object.assign({
                label: data.label || data.name || data.text,
                value: getValueUseKey(data,tablePrimaryKey) || data.id || data.value
            }, data)
        }

        const transformArrayData = (data) => {
            return (data || []).map(n => {
                return transformObjData(n)
            })
        }

        //超出maxSize值，不允许填加
        const limitMaxSize = (data) => {
            const { maxSize } = this.props
            return maxSize && (data || []).splice(0, maxSize) || data
        }

        const rowSelection= {
            type: multiple ? 'multiple' : 'single',
            // onChange: this.tableOnChange,
            getInitProps(data) {
                return {
                    checked:  !!(selectValue || []).find(n => {
                        let value = getValueUseKey(data,tablePrimaryKey) || data.value
                        return n.value == value
                    })
                }
            },
            onSelectAll: (selectRows, selected, event) => {
                let { selectValue } = this.state
                this.setState({
                    selectValue: selected ? limitMaxSize((selectValue || []).concat(transformArrayData(selectRows.filter(n => {
                        let _nv = getValueUseKey(n,tablePrimaryKey) || n.value
                        return !selectValue.find(v => {
                            let _vv = getValueUseKey(v,tablePrimaryKey) || v.value
                            return  _vv == _nv
                        })
                    })))) : selectValue.filter(n => {
                        let _nv = getValueUseKey(n,tablePrimaryKey) || n.value
                        return !selectRows.find(v => {
                            let _vv = getValueUseKey(v,tablePrimaryKey) || v.value
                            return _vv == _nv
                        })
                    })
                })
            },
            //table选中触发
            onSelect: (record, selected, selectedRows, evt) => {
                //超出maxSize值，不允许填加
                const { maxSize, multiple } = this.props
                let { selectValue } = this.state
                if (selected) {
                    let _r = transformObjData(record)
                    let _v = (maxSize && selectValue.length > maxSize -1) ? [] : [_r]
                    this.setState({
                        selectValue: multiple ? (selectValue || []).concat(_v) : _v
                    })
                }
            },
            //table取消选中触发
            onSelectInvert: (record, selected, selectedRows, evt) => {
                if (!selected) {
                    let { selectValue } = this.state
                    let key = getValueUseKey(record,tablePrimaryKey) || record.value
                    this.setState({
                        selectValue: selectValue.filter(n => {
                            return !((getValueUseKey(n,tablePrimaryKey) || n.value) == key)
                        })
                    })
                }
            }
        }

        const paginationCfg = {
            total: tableMeta.data && tableMeta.data.length,
            onChange: (pageSize) => {
              let { searchParam } = this.state
              this.getListInfo(clonedeep(searchParam), clonedeep(pageSize))
            }
        }

        return  <BasicTable
                    keygen="id"
                    fit={false}
                    fixed='both'
                    autoHeight={false}
                    ref={this.tableRef}
                    rowsInView={15}
                    rowSelection={rowSelection}
                    {...tableMeta}
                    height={scrollY}
                    showSelectCount={false}
                    pagination={ Object.assign(paginationCfg, pagination) }
                    loading={ loading }
                />
    }

    render() {
        const { searchFormMeta } = this.state
        const { getContainer } = this.props
        const selectedPnl = this.renderSelectedPanel()
        const table = this.renderTable()
        return (
            <div className={classes({element: 'mainContainer'})}>
                <div className={classes({element: 'container'})}>
                    <SearchForm zIndex={1100} {...searchFormMeta}  onChange={this.onSearchFormChange} getContainer={getContainer}/>
                    {table}
                </div>
                {selectedPnl}
            </div>
        )
    }
}