import React, { Component } from 'react'
import { View, StyleSheet, Alert, Platform, } from 'react-native'
import { StackNavigationProp, } from '@react-navigation/stack'
import { RNCamera, TakePictureOptions, TakePictureResponse, } from 'react-native-camera'
import FileViewer from 'react-native-file-viewer'
import PushNotification from 'react-native-push-notification'
import NotificationPopup from 'react-native-push-notification-popup'
import NotificationSounds, { playSampleSound } from  'react-native-notification-sounds'
import RecordScreen from 'react-native-record-screen'
import { format, parse, addSeconds, } from 'date-fns'
import { NotificationMobM, PrankTypeMobE, } from '../../models/mobileModels'
import c from '../../color/colors'
import t from '../../translator/translator'

import BasePage from '../BasePage'
import HeaderView from './HeaderView'
import BodyView from './BodyView'
import BottomView from './BottomView'


type Props = {
    navigation: StackNavigationProp<''>,
    route: {
        params: {
            notifications: NotificationMobM[],
        },
    },
}


export default class NoticifationPrankCameraPage extends BasePage<Props>
{
    cameraView: RNCamera = null
    popupView: NotificationPopup = null

    isCameraInProgress: Boolean = false
    isTakePhotoPressed: Boolean = false
    videoTimerInterval: Number = -1
    isStartedVideoTimer: Boolean = false
    
    sendedNotificationId = 1000
    notifications: NotificationMobM[] = []

    state: {
        cameraType: String,
        flashMode: any,
        isPrankStarted: Boolean,
        videoTimer: Date,
    }


    constructor(props: Props)
    {
        super(props)
        this.onPressTakePhoto = this.onPressTakePhoto.bind(this)
        this.onPressPauseResume = this.onPressPauseResume.bind(this)
        this.onPressChangeCamera = this.onPressChangeCamera.bind(this)
        this.onPressFlash = this.onPressFlash.bind(this)
        this.startPrank = this.startPrank.bind(this)
        this.endPrank = this.endPrank.bind(this)
        this.playNotificationSound = this.playNotificationSound.bind(this)

        this.notifications = this.props.route.params?.notifications || []

        this.state = {
            cameraType: RNCamera.Constants.Type.front,
            flashMode: RNCamera.Constants.FlashMode.off,
            isPrankStarted: false,
            videoTimer: parse('00:00:00', 'HH:mm:ss', new Date()),
        }
    }

    componentDidMount()
    {
        // this.startPrank()
    }

    componentWillUnmount()
    {
        this.timerStop()
        RecordScreen.stopRecording()
    }


    render()
    {
        return (
            <>
            <View style={ styles.container }>
                <RNCamera
                    ref = { ref => this.cameraView = ref }
                    style = { styles.camera }
                    type = { this.state.cameraType }
                    flashMode = { this.state.flashMode }
                    androidCameraPermissionOptions = { {
                        title: 'Permission to use camera',
                        message: 'We need your permission to use your camera',
                        buttonPositive: 'Ok',
                        buttonNegative: 'Cancel',
                    } }
                    androidRecordAudioPermissionOptions = { {
                        title: 'Permission to use audio recording',
                        message: 'We need your permission to use your audio',
                        buttonPositive: 'Ok',
                        buttonNegative: 'Cancel',
                    } }
                >

                    <HeaderView
                        secondsText = { format(this.state.videoTimer, 'mm:ss') }
                        onPressBack = { this.props.navigation.goBack }
                        isFlashTorched = { this.state.flashMode == RNCamera.Constants.FlashMode.torch }
                    />

                    <BodyView/>

                    <BottomView
                        isRecording = { this.state.isPrankStarted }
                        onPressTakePhoto = { this.onPressTakePhoto }
                        onPressPauseResume = { this.onPressPauseResume }
                    />

                </RNCamera>
            </View>
            <NotificationPopup
                ref = { ref => this.popupView = ref }
            />
            </>
        )
    }


    onPressChangeCamera()
    {
        if(this.state.cameraType == RNCamera.Constants.Type.front)
            this.setState({ cameraType: RNCamera.Constants.Type.back })
        else
            this.setState({ cameraType: RNCamera.Constants.Type.front })
    }

    onPressFlash()
    {
        if(this.state.flashMode == RNCamera.Constants.FlashMode.off)
            this.setState({ flashMode: RNCamera.Constants.FlashMode.torch })
        else
            this.setState({ flashMode: RNCamera.Constants.FlashMode.off })
    }

    onPressTakePhoto()
    {
        if(this.isTakePhotoPressed)
            return
        this.isTakePhotoPressed = true

        if(!this.state.isPrankStarted)
            this.startPrank()
        else
            this.endPrank()

        this.isTakePhotoPressed = false
    }

    onPressPauseResume()
    {
        if(this.state.isPrankStarted == false)
            return

        if(this.isStartedVideoTimer == false)
        {
            this.timerStart()
            this.isStartedVideoTimer = true
        }
        else
        {
            this.timerStop()
            this.isStartedVideoTimer = false
        }
    }


    async startPrank()
    {
        try
        {
            let result = await RecordScreen.startRecording({ mic: true })
            if(result == true || result == 'started')
            {
                this.setState({ isPrankStarted: true })
                this.onPressPauseResume()
            }
            else
            {
                throw 'Ne nachalos!!! ' + JSON.stringify(result)
            }

            for (let i = 0; i < this.notifications.length; i++)
            {
                const notif = this.notifications[i]

                if(notif.senderName && notif.notificationText)
                    this.sentNotification(notif.senderName, notif.notificationText, notif.timeValue)   
            }
        }
        catch(error)
        {
            Alert.alert('Ne nachalos zapis', JSON.stringify(error))
            this.setState({ isPrankStarted: false })
        }
    }


    async endPrank()
    {
        try
        {
            let res = await RecordScreen.stopRecording()

            if(res)
            {
                this.setState({ isPrankStarted: false })

                const url = res?.result?.outputURL

                this.props.navigation.navigate('ShareVideoPage', {
                    videoPath: url,
                    prankType: PrankTypeMobE.NotificationPrank,
                })
            }
        }
        catch(error)
        {
            Alert.alert('Error when endPrank()', JSON.stringify(error))
        }
    }



    timerStart()
    {
        this.videoTimerInterval = setInterval(() =>
        {
            this.state.videoTimer = addSeconds(this.state.videoTimer, 1)
            this.setState({ videoTimer: this.state.videoTimer })
        },
        995)
    }

    timerStop()
    {
        clearInterval(this.videoTimerInterval)
    }

    sentNotification(title: String = '', message: String = '', delaySeconds: Number = 0)
    {
        // PushNotification.localNotificationSchedule({
        //     id: this.sendedNotificationId++,
        //     title,
        //     message,
        //     playSound: true,
        //     channelId: 'testChanne5',
        //     smallIcon: 'ic_simple_message',
        //     largeIcon: '',
        //     date: new Date(Date.now() + delaySeconds * 1000),
        //     allowWhileIdle: true,
        // })

        let timeOut = setTimeout(() =>
        {
            this.playNotificationSound()
            this.popupView.show({
                onPress: function() {console.log('Pressed')},
                appIconSource: require('../../../assets/icons/notificationIcons/message.png'),
                appTitle: 'Message',
                timeText: 'Now',
                title,
                body: message,
                slideOutTime: 5000,
            })
            clearTimeout(timeOut)
        }, delaySeconds * 1000)
        
    }

    playNotificationSound()
    {
        NotificationSounds.getNotifications('notification').then(soundsList =>
        {
            let notificationName = Platform.select({ ios: 'Notification Haptic', android: 'Spaceline' })
            let sound = soundsList.find(x => x.title.includes(notificationName))

            if(sound)
                playSampleSound(sound)
        })
    }

}



const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    camera: {
        flex: 1,
        backgroundColor: 'green',
    },
})
