import React from 'react';
import { View, Text, ScrollView, PixelRatio } from 'react-native';
import variables from '../../common/styles/variables';
import { range } from '../../common/utils';
import scrollpickerStyles from './styles';
export { scrollpickerStyles };
const px = 1 / PixelRatio.get();
const DEFAULT_CONTAINER_HEIGHT = 1;
export class Scrollpicker extends React.Component {
    constructor(props) {
        super(props);
        this.containerRef = null;
        this.scrollers = [];
        this.targetItemHeight = null;
        this.containerHeight = null;
        this.containerRef = null;
        const data = this.initialize(props);
        this.state = {
            ...data,
            targetItemHeight: null,
            containerHeight: null
        };
        this.scrollers = [];
    }
    initialize(props) {
        const data = this.initData(props);
        return data;
    }
    initData(props) {
        let { list, proportion, value } = props;
        if (!list || !list.length) {
            throw TypeError('提供有效的 list 参数');
        }
        const { offsetCount } = this.props;
        const placeholderList = range(offsetCount).map(() => {
            return '';
        });
        list = list.map(scrollItem => {
            const tmp = scrollItem.concat();
            [].push.apply(tmp, placeholderList);
            [].unshift.apply(tmp, placeholderList);
            return tmp;
        });
        const length = list.length;
        if (!proportion ||
            !proportion.length ||
            (proportion && proportion.length && proportion.length !== length)) {
            proportion = range(length).map(() => {
                return 1;
            });
        }
        if (!value ||
            !value.length ||
            (value && value.length && value.length !== length)) {
            value = range(length).map(() => {
                return 0;
            });
        }
        return {
            list,
            value,
            proportion
        };
    }
    componentDidMount() {
        this.getUIData(this.containerRef, DEFAULT_CONTAINER_HEIGHT).then((data) => {
            const { targetItemHeight } = data;
            const containerHeight = this.resizeContainerHeight(targetItemHeight);
            this.setState({
                containerHeight,
                targetItemHeight
            }, () => {
                this.getUIData(this.containerRef, this.state.containerHeight).then((uiData) => {
                    const { value } = this.state;
                    value.forEach((item, index) => {
                        this.scrollTo(index, item, false);
                    });
                }).catch((e) => {
                    console.log(e);
                });
            });
        }).catch((e) => {
            console.log(e);
        });
    }
    componentWillReceiveProps(nextProps) {
        if (nextProps !== this.props) {
            const data = this.initialize(nextProps);
            this.setState({
                ...data
            }, () => {
                setTimeout(() => {
                    const { value } = this.state;
                    value.forEach((item, index) => {
                        this.scrollTo(index, item);
                    });
                });
            });
        }
    }
    getUIData(element, accurateHeight, maxCount) {
        let count = 0;
        maxCount = maxCount == null ? 20 : maxCount;
        return new Promise((resolve, reject) => {
            let toCheck = null;
            let measure = () => {
                let ret = null;
                element.measure((x, y, width, height, left, top) => {
                    // console.log(
                    //   `Get container height: ${height}, accurate height: ${accurateHeight} and target item height: ${
                    //     this.targetItemHeight
                    //   } for ${++count}th.`
                    // )
                    if (height) {
                        // 安卓机器获取高度不精确
                        const needToReset = height % 1 === 0 ? false : true;
                        let minHeight;
                        let maxHeight;
                        if (needToReset) {
                            minHeight = Math.floor(height);
                            maxHeight = minHeight + 1;
                        }
                        else {
                            minHeight = maxHeight = height;
                        }
                        if ((minHeight === accurateHeight || maxHeight === accurateHeight) &&
                            this.targetItemHeight) {
                            ret = {
                                rect: {
                                    x,
                                    y,
                                    width,
                                    height
                                },
                                targetItemHeight: this.targetItemHeight
                            };
                        }
                    }
                    toCheck(ret);
                });
            };
            toCheck = (ret) => {
                if (ret) {
                    return resolve(ret);
                }
                else {
                    if (count < maxCount) {
                        setTimeout(() => {
                            measure();
                        }, 20);
                    }
                    else {
                        return reject('获取元素高度失败！');
                    }
                }
            };
            measure();
        });
    }
    resizeContainerHeight(targetItemHeight) {
        const { offsetCount } = this.props;
        const ret = targetItemHeight + 2 * (targetItemHeight * offsetCount);
        return ret;
    }
    locateIndicator(targetItemHeight) {
        const styles = scrollpickerStyles;
        const { offsetCount } = this.props;
        return (React.createElement(View, { style: [styles.indicator], pointerEvents: 'none' },
            React.createElement(View, { style: [
                    styles.indicator,
                    styles.indicatorMask,
                    { bottom: targetItemHeight + offsetCount * targetItemHeight },
                    { borderBottomWidth: 1 * px, borderBottomColor: variables.mtdBorderColorDark }
                ] }),
            React.createElement(View, { style: [
                    styles.indicator,
                    styles.indicatorMask,
                    { top: targetItemHeight + offsetCount * targetItemHeight },
                    { borderTopWidth: 1 * px, borderTopColor: variables.mtdBorderColorDark }
                ] })));
    }
    scrollTo(scrollIndex, targetItemIndex, animated) {
        const { targetItemHeight } = this.state;
        // const { offsetCount } = this.props
        this.scrollProper(scrollIndex, targetItemHeight * targetItemIndex, animated);
    }
    onScroll(scrollIndex, scrollHeight) {
        const targetItemIndex = this.scrollProper(scrollIndex, scrollHeight);
        this.props.onChange && this.props.onChange(scrollIndex, targetItemIndex);
    }
    scrollProper(scrollIndex, scrollHeight, animated) {
        const { targetItemHeight, list } = this.state;
        const { offsetCount } = this.props;
        const scrollListLength = list[scrollIndex].length;
        let newScrollHeight;
        const min = 0;
        const max = (scrollListLength - 2 * offsetCount - 1) * targetItemHeight;
        if (scrollHeight <= min) {
            newScrollHeight = min;
        }
        else if (scrollHeight >= max) {
            newScrollHeight = max;
        }
        else {
            const quotient = parseInt(String(scrollHeight / targetItemHeight), 10);
            newScrollHeight = quotient * targetItemHeight;
            const halfHeight = targetItemHeight / 2;
            if (scrollHeight - newScrollHeight > halfHeight) {
                newScrollHeight += targetItemHeight;
            }
        }
        this.scrollers[scrollIndex] && this.scrollers[scrollIndex].scrollTo && this.scrollers[scrollIndex].scrollTo({
            x: 0,
            y: newScrollHeight,
            animated: animated === false ? false : true
        });
        const targetItemIndex = newScrollHeight / targetItemHeight;
        return targetItemIndex;
    }
    render() {
        const styles = scrollpickerStyles;
        const { list, proportion, containerHeight, targetItemHeight } = this.state;
        return (React.createElement(View, { ref: el => {
                this.containerRef = el;
            }, style: [
                styles.container,
                this.props.style,
                { height: containerHeight || DEFAULT_CONTAINER_HEIGHT }
            ] },
            containerHeight && this.locateIndicator(targetItemHeight),
            list.map((scrollItem, scrollIndex) => {
                return (React.createElement(View, { key: scrollIndex, style: [
                        styles.proportionWrapper,
                        { flex: Number(proportion[scrollIndex]) }
                    ] },
                    React.createElement(ScrollView, { ref: c => {
                            this.scrollers[scrollIndex] = c;
                        }, style: styles.scroller, showsVerticalScrollIndicator: false, contentContainerStyle: [styles.scrollerContentContainer], onScrollEndDrag: (e) => {
                            this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y);
                        } }, scrollItem.map((item, index) => {
                        return (React.createElement(View, { key: index, style: [styles.targetItem, { height: targetItemHeight }], onLayout: e => {
                                if (item &&
                                    this.targetItemHeight == null &&
                                    e.nativeEvent.layout.height) {
                                    this.targetItemHeight = Math.ceil(e.nativeEvent.layout.height);
                                    // console.log(
                                    //   'OnLayout get target item height:',
                                    //   this.targetItemHeight
                                    // )
                                }
                            } }, this.props.renderItem ? this.props.renderItem(item, index) :
                            React.createElement(Text, { style: [
                                    styles.targetItemContent
                                ], numberOfLines: 1 }, typeof item === 'object' ? item.label : item)));
                    }))));
            })));
    }
}
Scrollpicker.defaultProps = {
    style: {},
    list: [
        ['第一列第一项', '第一列第二项', '第一列第三项'],
        ['第二列第一项', '第二列第二项', '第二列第三项'],
        ['第三列第一项', '第三列第二项', '第三列第三项']
    ],
    value: [],
    proportion: [2, 1, 1],
    offsetCount: 2,
    onChange: null,
    renderItem: null
};
//# sourceMappingURL=index.js.map