import React from 'react';
import {
    View,
    StyleSheet,
    Text,
    ScrollView,
    Platform,
    AppState,
    AppStateStatus,
    NativeEventSubscription
} from 'react-native';
import { inject, observer } from 'mobx-react';
import { StackNavigationProp } from '@react-navigation/stack';
import { Route } from '@react-navigation/native';

import Screen from '../../../components/Screen';
import Header from '../../../components/Header';
import Button from '../../../components/Button';
import LoadingIndicator from '../../../components/LoadingIndicator';
import CollapsedQR from '../../../components/CollapsedQR';
import ModalBox from '../../../components/ModalBox';

import NostrWalletConnectStore from '../../../stores/NostrWalletConnectStore';
import { themeColor } from '../../../utils/ThemeUtils';
import { localeString } from '../../../utils/LocaleUtils';
import AlertIcon from '../../../assets/images/SVG/Alert.svg';
import { font } from '../../../utils/FontUtils';

interface NWCConnectionQRProps {
    navigation: StackNavigationProp<any, any>;
    route: Route<'NWCConnectionQR', { connectionId: string; nostrUrl: string }>;
    NostrWalletConnectStore: NostrWalletConnectStore;
}

interface NWCConnectionQRState {
    isConnected: boolean;
    appState: AppStateStatus;
    showTimeoutMessage: boolean;
}
const CONNECTION_TIMEOUT_MS = 20000;
@inject('NostrWalletConnectStore')
@observer
export default class NWCConnectionQR extends React.Component<
    NWCConnectionQRProps,
    NWCConnectionQRState
> {
    appStateSubscription: NativeEventSubscription | null = null;
    connectionTimeout: ReturnType<typeof setTimeout> | null = null;

    constructor(props: NWCConnectionQRProps) {
        super(props);
        this.state = {
            isConnected: false,
            appState: AppState.currentState,
            showTimeoutMessage: false
        };
    }

    componentDidMount() {
        const { NostrWalletConnectStore, route } = this.props;
        const { connectionId } = route.params;
        NostrWalletConnectStore.startWaitingForConnection(connectionId);
        this.appStateSubscription = AppState.addEventListener(
            'change',
            this.handleAppStateChange
        );
        this.connectionTimeout = setTimeout(() => {
            if (
                NostrWalletConnectStore.waitingForConnection &&
                !NostrWalletConnectStore.connectionJustSucceeded
            ) {
                this.setState({ showTimeoutMessage: true });
            }
        }, CONNECTION_TIMEOUT_MS);
    }

    componentDidUpdate() {
        const { NostrWalletConnectStore, navigation } = this.props;
        if (
            NostrWalletConnectStore.connectionJustSucceeded &&
            !this.state.isConnected
        ) {
            if (this.connectionTimeout) {
                clearTimeout(this.connectionTimeout);
                this.connectionTimeout = null;
            }
            this.setState({ isConnected: true, showTimeoutMessage: false });
            setTimeout(() => {
                navigation.popTo('NostrWalletConnect');
            }, 2000);
        }
    }

    componentWillUnmount() {
        const { NostrWalletConnectStore } = this.props;
        NostrWalletConnectStore.stopWaitingForConnection();
        if (this.appStateSubscription) {
            this.appStateSubscription.remove();
        }
        if (this.connectionTimeout) {
            clearTimeout(this.connectionTimeout);
            this.connectionTimeout = null;
        }
    }

    handleAppStateChange = (nextAppState: AppStateStatus) => {
        this.setState({ appState: nextAppState });
    };

    handleContinueWaiting = () => {
        const { NostrWalletConnectStore } = this.props;

        this.setState({ showTimeoutMessage: false });

        if (this.connectionTimeout) {
            clearTimeout(this.connectionTimeout);
        }
        this.connectionTimeout = setTimeout(() => {
            if (
                NostrWalletConnectStore.waitingForConnection &&
                !NostrWalletConnectStore.connectionJustSucceeded
            ) {
                this.setState({ showTimeoutMessage: true });
            }
        }, CONNECTION_TIMEOUT_MS);
    };

    handleGoBack = () => {
        const { navigation } = this.props;
        this.setState({ showTimeoutMessage: false });
        navigation.popTo('NostrWalletConnect');
    };

    render() {
        const { navigation, NostrWalletConnectStore, route } = this.props;
        const { nostrUrl } = route.params;
        const { appState } = this.state;

        const shouldShowIosTimer =
            Platform.OS === 'ios' &&
            appState === 'inactive' &&
            NostrWalletConnectStore.iosHandoffInProgress &&
            NostrWalletConnectStore.iosBackgroundTimeRemaining > 0;

        return (
            <Screen>
                <Header
                    leftComponent="Back"
                    centerComponent={{
                        text: localeString(
                            'views.Settings.NostrWalletConnect.connectionSecret'
                        ),
                        style: {
                            color: themeColor('text'),
                            fontFamily: 'PPNeueMontreal-Book'
                        }
                    }}
                    navigation={navigation}
                />
                <ScrollView
                    style={{
                        paddingHorizontal: 15
                    }}
                >
                    <CollapsedQR
                        value={nostrUrl}
                        showShare={true}
                        hideText={true}
                        expanded
                        iconOnly={true}
                    />

                    {NostrWalletConnectStore.waitingForConnection && (
                        <View style={[styles.loadingContainer]}>
                            <LoadingIndicator />
                            <Text
                                style={[
                                    styles.loadingText,
                                    { color: themeColor('secondaryText') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.waitingForAppToConnect'
                                )}
                            </Text>
                        </View>
                    )}

                    {shouldShowIosTimer && (
                        <View style={styles.iosTimerContainer}>
                            <Text
                                style={[
                                    styles.iosTimerTitle,
                                    { color: themeColor('text') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.switchToNostrClient'
                                )}
                            </Text>
                            <View style={styles.timerCircle}>
                                <Text
                                    style={[
                                        styles.timerText,
                                        { color: themeColor('highlight') }
                                    ]}
                                >
                                    {
                                        NostrWalletConnectStore.iosBackgroundTimeRemaining
                                    }
                                </Text>
                                <Text
                                    style={[
                                        styles.timerLabel,
                                        {
                                            color: themeColor('secondaryText')
                                        }
                                    ]}
                                >
                                    {localeString('models.Invoice.seconds')}
                                </Text>
                            </View>
                            <Text
                                style={[
                                    styles.iosTimerSubtitle,
                                    { color: themeColor('secondaryText') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.backgroundConnectionWindow'
                                )}
                            </Text>
                        </View>
                    )}

                    {this.state.isConnected && (
                        <View style={[styles.connectedContainer]}>
                            <Text
                                style={[
                                    styles.connectedText,
                                    { color: themeColor('success') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.connectedSuccessfully'
                                )}
                            </Text>
                        </View>
                    )}
                    <View style={styles.buttonContainer}>
                        <Button
                            title={localeString('general.close')}
                            onPress={() => {
                                navigation.popTo('NostrWalletConnect');
                            }}
                            secondary
                            noUppercase
                        />
                    </View>
                </ScrollView>
                <ModalBox
                    isOpen={
                        this.state.showTimeoutMessage &&
                        NostrWalletConnectStore.waitingForConnection
                    }
                    style={{
                        backgroundColor: 'transparent',
                        minHeight: 200,
                        zIndex: 9999
                    }}
                    onClosed={() =>
                        this.setState({ showTimeoutMessage: false })
                    }
                    backdropPressToClose={false}
                    swipeToClose={false}
                >
                    <View
                        style={{
                            flex: 1,
                            justifyContent: 'center',
                            alignItems: 'center'
                        }}
                    >
                        <View
                            style={[
                                styles.modalContainer,
                                {
                                    backgroundColor:
                                        themeColor('modalBackground')
                                }
                            ]}
                        >
                            <View style={styles.modalIconContainer}>
                                <AlertIcon
                                    fill={themeColor('highlight')}
                                    width={42}
                                    height={42}
                                />
                            </View>
                            <Text
                                style={[
                                    styles.modalTitle,
                                    { color: themeColor('text') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.connectionTimeout'
                                )}
                            </Text>
                            <Text
                                style={[
                                    styles.modalMessage,
                                    { color: themeColor('secondaryText') }
                                ]}
                            >
                                {localeString(
                                    'views.Settings.NostrWalletConnect.noEventReceivedTimeoutDescription'
                                )}
                            </Text>
                            <View style={styles.modalButtonsContainer}>
                                <View style={styles.modalButton}>
                                    <Button
                                        title={localeString(
                                            'views.Settings.NostrWalletConnect.continueWaiting'
                                        )}
                                        onPress={this.handleContinueWaiting}
                                    />
                                </View>
                                <View style={styles.modalButton}>
                                    <Button
                                        title={localeString('general.goBack')}
                                        onPress={this.handleGoBack}
                                        secondary
                                    />
                                </View>
                            </View>
                        </View>
                    </View>
                </ModalBox>
            </Screen>
        );
    }
}

const styles = StyleSheet.create({
    loadingContainer: {
        justifyContent: 'center',
        alignItems: 'center',
        marginBottom: 20,
        paddingVertical: 5,
        borderRadius: 12,
        paddingHorizontal: 10
    },
    loadingText: {
        fontSize: 16,
        fontFamily: 'PPNeueMontreal-Book',
        textAlign: 'center',
        marginTop: 12,
        fontWeight: '500'
    },
    buttonContainer: {
        width: '100%',
        alignItems: 'center'
    },
    connectedContainer: {
        justifyContent: 'center',
        alignItems: 'center',
        marginBottom: 40,
        paddingVertical: 20,
        paddingHorizontal: 24
    },
    connectedText: {
        fontSize: 16,
        fontFamily: 'PPNeueMontreal-Book',
        textAlign: 'center',
        fontWeight: '600'
    },
    iosTimerContainer: {
        alignItems: 'center',
        marginVertical: 16,
        paddingVertical: 16
    },
    iosTimerTitle: {
        fontSize: 18,
        fontFamily: 'PPNeueMontreal-Book',
        fontWeight: '600',
        textAlign: 'center',
        marginBottom: 16
    },
    timerCircle: {
        width: 70,
        height: 70,
        borderRadius: 50,
        justifyContent: 'center',
        alignItems: 'center',
        marginVertical: 12
    },
    timerText: {
        fontSize: 36,
        fontFamily: 'PPNeueMontreal-Book',
        fontWeight: '700'
    },
    timerLabel: {
        fontSize: 12,
        fontFamily: 'PPNeueMontreal-Book',
        marginTop: 4
    },
    iosTimerSubtitle: {
        fontSize: 14,
        fontFamily: 'PPNeueMontreal-Book',
        textAlign: 'center',
        marginTop: 12,
        lineHeight: 20
    },
    modalContainer: {
        borderRadius: 30,
        padding: 30,
        width: '90%',
        maxWidth: 400,
        alignItems: 'center',
        shadowColor: '#000',
        shadowOffset: {
            width: 0,
            height: 4
        },
        shadowOpacity: 0.3,
        shadowRadius: 8,
        elevation: 8
    },
    modalIconContainer: {
        marginBottom: 20,
        alignItems: 'center',
        justifyContent: 'center'
    },
    modalTitle: {
        fontSize: 28,
        fontFamily: font('marlideBold'),
        fontWeight: '600',
        textAlign: 'center',
        marginBottom: 12
    },
    modalMessage: {
        fontSize: 16,
        fontFamily: 'PPNeueMontreal-Book',
        textAlign: 'center',
        lineHeight: 22,
        marginBottom: 30
    },
    modalButtonsContainer: {
        width: '100%',
        alignItems: 'center'
    },
    modalButton: {
        width: '100%',
        marginBottom: 12
    }
});
