import React from 'react'
import { requireNativeComponent, ViewProps, findNodeHandle, NativeSyntheticEvent, UIManager } from 'react-native'
import { UIManagerHelper } from './utils';
import { RemoteParticipant } from './types';
const NATIVE_COMPONENT_NAME = "CallView"
const NTiveCallView = requireNativeComponent(NATIVE_COMPONENT_NAME)

interface CallViewProps extends ViewProps {
    shareVideo: boolean
    shareAudio: boolean
    // 
    onDidConnect?: (participants: Array<RemoteParticipant>) => void
    onFailedToConnect?: () => void
    onDisConnected?: () => void
    onReConnecting?: () => void
    onFailedReConnect?: () => void
    onDidReConnect?: () => void
    onParticipantConnected?: (participant: Array<RemoteParticipant>) => void
    onParticipantDisConnected?: (participant: Array<RemoteParticipant>) => void
}

class CallView extends React.PureComponent<CallViewProps> {

    onDidConnect = (evt: NativeSyntheticEvent<any>) => {
        const { participants } = evt.nativeEvent
        const { onDidConnect } = this.props
        onDidConnect && onDidConnect(participants)
    }

    onFailedToConnect = () => {
        const { onFailedToConnect } = this.props
        onFailedToConnect && onFailedToConnect()
    }

    onDisConnected = () => {
        const { onDisConnected } = this.props
        onDisConnected && onDisConnected()
    }

    onReConnecting = () => {
        const { onReConnecting } = this.props
        onReConnecting && onReConnecting()
    }

    onFailedReConnect = () => {
        const { onFailedReConnect } = this.props
        onFailedReConnect && onFailedReConnect()
    }

    onDidReConnect = () => {
        const { onDidReConnect } = this.props
        onDidReConnect && onDidReConnect()
    }

    onParticipantConnected = (evt: NativeSyntheticEvent<any>) => {
        const { participants } = evt.nativeEvent
        const { onParticipantConnected } = this.props
        onParticipantConnected && onParticipantConnected(participants)
    }

    onParticipantDisConnected = (evt: NativeSyntheticEvent<any>) => {
        const { participants } = evt.nativeEvent
        const { onParticipantDisConnected } = this.props
        onParticipantDisConnected && onParticipantDisConnected(participants)
    }

    //
    dispatchNativeMethod = (name: string, params: Array<any>) => {
        UIManagerHelper.dispatchViewMethod(this, NATIVE_COMPONENT_NAME, name, params)
    }
    nativeConnectWithOptions = (token: string, room: string) => {
        this.dispatchNativeMethod("connectWithOptions", [token, room])
    }

    nativeFlipCamera = () => {
        this.dispatchNativeMethod("flipCamera", [])
    }
    
    nativeDisconnect = () => {
        this.dispatchNativeMethod("disconnect", [])
    }

    assignPropsToChildren = (child: unknown) => {
        const c = child as React.ReactElement
        const e = React.cloneElement(c, { parentNode: this })
        return e
    }
    
    render() {
        const childrenWithProps = React.Children.map(this.props.children, this.assignPropsToChildren)
        return (
            <NTiveCallView
                {...this.props}
                onDidConnect={this.onDidConnect}
                onFailedToConnect={this.onFailedToConnect}
                onDisConnected={this.onDisConnected}
                onReConnecting={this.onReConnecting}
                onFailedReConnect={this.onFailedReConnect}
                onDidReConnect={this.onDidReConnect}
                onParticipantConnected={this.onParticipantConnected}
                onParticipantDisConnected={this.onParticipantDisConnected}
                children={childrenWithProps}
            />
        )
    }
}

export default CallView