/** @format */

import * as React from 'react';
import {Checkbox, Empty, Collapse, Row} from 'antd';
import Button from '../button';
import Parameter, {ValueProps} from './parameter';
const {Panel} = Collapse;
const NOT_OUT_MAX_EMPTYDATA = 5;
const ERROR_MESSAGE = `空列表上限为${NOT_OUT_MAX_EMPTYDATA}条,请对现有列表设置参数名!`;

interface GroupProps {
    values: Partial<ValueProps>;
    isEditable?: boolean;
    chooseAll?: boolean;
    requestType: 'request' | 'response';
    mode: 'query' | 'config';

    onChange: (value: ValueProps) => void;
}
//计算是否全选
const reduceChooseAll: (params: ValueProps[]) => boolean = (params: ValueProps[]) => {
    let isChooseAll = true;
    for (let k = 0; k < params.length; k++) {
        params[k].selected ? (isChooseAll = reduceChooseAll(params[k].child || [])) : (isChooseAll = false);
        if (!isChooseAll) {
            break;
        }
    }
    return isChooseAll;
};
//选中或者全不选
const switchChooseAll = (params: ValueProps[], type: boolean) => {
    for (let k = 0; k < params.length; k++) {
        params[k].selected = type;
        switchChooseAll(params[k].child, type);
    }
    return params;
};
/**
 * 生成可展开的列表
 */
class Group extends React.Component<GroupProps, {values: ValueProps}> {
    constructor(props) {
        super(props);
        this.state = {
            values: props.values,
        };
    }
    componentWillReceiveProps(nextProps) {
        this.setState(preState => ({...preState, values: nextProps.values}));
    }
    handleAdd = (id: string) => {
        const newValues = this.state.values.child.map(element => {
            if (element.id === id) {
                return {
                    ...element,
                    child: [
                        {
                            id: String(Date.now()),
                            required: false,
                            selected: true,
                            name: '',
                            mean: '',
                            type: 'string',
                            child: [],
                            in: '',
                        },
                    ].concat(...element.child),
                };
            }
            return element;
        });
        this.props.onChange({...this.state.values, child: newValues});
        this.setState(preState => ({...preState, values: {...preState.values, child: newValues}}));
    };
    handleChange = (values: ValueProps) => {
        const newValue = this.state.values.child.map(element => {
            if (element.id === values.id) {
                return {
                    ...element,
                    ...values,
                };
            }
            return element;
        });
        this.props.onChange({...this.state.values, child: newValue});
    };
    handleDelete = (id: string) => {
        const newValue = this.state.values.child.filter(element => element.id !== id);
        this.setState(preState => ({...preState, values: {...preState.values, child: newValue}}));
        this.props.onChange({...this.state.values, child: newValue});
    };
    render() {
        const {isEditable, requestType, mode, chooseAll} = this.props;
        return (
            <>
                {chooseAll && mode === 'config' ? (
                    <Checkbox
                        checked={reduceChooseAll(this.state.values.child)}
                        onChange={event => {
                            const newChilds = switchChooseAll(this.state.values.child, event.target.checked);
                            this.setState(preState => {
                                this.props.onChange({...preState.values, child: newChilds});
                                return {...preState, values: {...preState.values, child: newChilds}};
                            });
                        }}
                    >
                        全选
                    </Checkbox>
                ) : null}

                <Collapse bordered={false} accordion>
                    {this.state.values.child.map(element => {
                        return (
                            <Panel
                                showArrow={element.child && element.child.length !== 0}
                                key={element.id}
                                header={
                                    <Parameter
                                        values={element}
                                        requestType={requestType}
                                        isEditable={isEditable}
                                        onAdd={this.handleAdd}
                                        onChange={this.handleChange}
                                        onDelete={this.handleDelete}
                                        mode={mode}
                                        parentType={this.state.values.type}
                                    />
                                }
                            >
                                {element.child && !!element.child.length && (
                                    <Group {...this.props} values={element} onChange={this.handleChange} />
                                )}
                            </Panel>
                        );
                    })}
                </Collapse>
            </>
        );
    }
}

interface ParamsProps {
    isEditable: boolean; //是否可编辑
    chooseAll?: boolean; // 是否可全选
    requestType?: 'request' | 'response';
    value?: ValueProps[];
    onChange?: (value: ValueProps[]) => void;
    mode?: 'query' | 'config';
}
interface Istate {
    valuelength: number;
    chooseAll: boolean;
    params: ValueProps[];
}
export default React.memo(
    React.forwardRef((props: ParamsProps, ref) => {
        const {value = [], isEditable = false, chooseAll = false, requestType = 'request', mode = 'config'} = props;
        const timeRef: any = React.useRef(null);
        const [state, setState] = React.useState<Istate>({
            valuelength: 20,
            chooseAll: false,
            params: [],
        });
        //监听上级传递得values
        React.useEffect(() => {
            setState(preState => ({...preState, params: value, valuelength: 20}));
        }, [value]);
        React.useImperativeHandle(ref, () => {
            return {
                getParams: () => {
                    return state.params;
                },
            };
        });
        const handleChange = (values: ValueProps) => {
            if (timeRef.current) {
                clearTimeout(timeRef.current);
            }
            timeRef.current = setTimeout(() => {
                setState(preState => ({
                    ...preState,
                    params: values.child.concat(...state.params.slice(state.valuelength)),
                }));
            }, 400);
        };
        const handleLoadMore = () => {
            setState(preState => {
                if (preState.valuelength === 20) {
                    return {...preState, valuelength: preState.valuelength + 100};
                }
                return {...preState, valuelength: preState.params.length};
            });
        };
        const handleAdd = () => {
            const newValue: ValueProps[] = [
                {
                    id: String(Date.now()),
                    required: false,
                    selected: true,
                    name: '',
                    mean: '',
                    type: 'string',
                    child: [],
                    in: '',
                },
            ];
            setState(preState => {
                return {...preState, params: newValue.concat(...preState.params)};
            });
        };

        return (
            <>
                {isEditable && (
                    <Button type='primary' icon='file-add' onClick={handleAdd}>
                        添加参数
                    </Button>
                )}
                {state.params.length === 0 ? (
                    <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
                ) : (
                    <>
                        <Group
                            requestType={requestType}
                            values={{child: state.params.slice(0, state.valuelength), id: '1'}}
                            isEditable={isEditable}
                            chooseAll={chooseAll}
                            onChange={handleChange}
                            mode={mode}
                        />
                        {state.valuelength < state.params.length ? (
                            <Row style={{textAlign: 'center'}}>
                                <Button onClick={handleLoadMore}>加载更多参数</Button>
                            </Row>
                        ) : null}
                    </>
                )}
            </>
        );
    }),
);
