import React, {Component, ReactNode} from 'react'
import {Animated, View, Modal, StyleSheet, TouchableOpacity, NativeEventSubscription} from 'react-native'
import SystemTool from '../tool/SystemTool'
import TimerTool from '../tool/TimerTool'
import {isFunction} from '../tool/TypeTool'

type StateType = {
    isShow: boolean
}

type PropsType = {
    onDismiss?: () => void
    customView: ReactNode
    viewHeight: number
}

export default class PYSheet extends Component<PropsType, StateType> {
    translateValue: Animated.Value
    opacityValue: Animated.Value
    backEvent: NativeEventSubscription | null = null
    constructor(props: PropsType) {
        super(props)
        this.translateValue = new Animated.Value(props.viewHeight)
        this.opacityValue = new Animated.Value(0)
        this.state = {
            isShow: false,
        }
    }

    componentDidMount() {
        this.backEvent = SystemTool.addBackListener(this._handleHwBackEvent.bind(this))
    }

    componentWillUnmount() {
        this.backEvent && this.backEvent.remove()
        this.backEvent = null
        this.setState = () => {}
    }

    show = () => {
        this.setState({
            isShow: true,
        })
        Animated.parallel([
            Animated.timing(this.translateValue, {
                toValue: 0,
                duration: 250,
                useNativeDriver: true,
            }),
            Animated.timing(this.opacityValue, {
                toValue: 1,
                duration: 250,
                useNativeDriver: true,
            }),
        ]).start()
    }

    hide = async (completion?: () => void) => {
        if (this.state.isShow) {
            Animated.parallel([
                Animated.timing(this.translateValue, {
                    toValue: this.props.viewHeight,
                    duration: 250,
                    useNativeDriver: true,
                }),
                Animated.timing(this.opacityValue, {
                    toValue: 0,
                    duration: 150,
                    useNativeDriver: true,
                }),
            ]).start()
            isFunction(this.props.onDismiss) && this.props.onDismiss!()
            await TimerTool.delay(150)
            this.setState(
                {
                    isShow: false,
                },
                completion,
            )
        }
    }

    _handleHwBackEvent = () => {
        this.hide()
        return true
    }

    render() {
        if (!this.state.isShow) {
            return null
        }
        return (
            <Modal
                animationType="fade"
                transparent={true}
                visible={true}
                statusBarTranslucent={false}
                hardwareAccelerated={true}
                onRequestClose={() => {
                    this.hide()
                }}>
                <View style={styles.container}>
                    <Animated.View style={[styles.shadow, {opacity: this.opacityValue}]} />
                    <TouchableOpacity
                        style={styles.container}
                        activeOpacity={1}
                        onPress={this._onPressOutside.bind(this)}>
                        <Animated.View
                            style={[styles.contentContainer, {transform: [{translateY: this.translateValue}]}]}>
                            {this.props.customView}
                        </Animated.View>
                    </TouchableOpacity>
                </View>
            </Modal>
        )
    }

    _onPressOutside = () => {
        this.hide()
    }
}

const styles = StyleSheet.create({
    container: {
        width: '100%',
        height: '100%',
        alignItems: 'center',
        position: 'absolute',
    },
    shadow: {
        width: '100%',
        height: '100%',
        position: 'absolute',
        backgroundColor: 'rgba(52,52,52,0.5)',
    },
    contentContainer: {
        position: 'absolute',
        bottom: 0,
        width: '100%',
        alignItems: 'center',
    },
})
