import React from 'react';
import AppLoading from 'expo-app-loading';
import { Ionicons } from '@expo/vector-icons';
import * as Font from 'expo-font';

// Redux + Storage
import swimtrackerReducer from './state/Reducer';
import { createStore } from 'redux';
import { ConnState, WifiState, DeviceReduxCoupling } from './state/DeviceReduxCoupling';
import { Provider } from 'react-redux';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistStore, persistReducer } from 'redux-persist'
import hardSet from 'redux-persist/lib/stateReconciler/hardSet'
import { PersistGate } from 'redux-persist/integration/react'

// Navigation
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

// Own views
import MainMenuView from "./views/MainMenuView";
import SettingsView from "./views/SettingsView";
import TrainingView from "./views/TrainingView";
import LastSessionsView from "./views/LastSessionsView";
import ConnectingView from './views/ConnectingView';
import WifiSelectionView from './views/WifiSelectionView';
import WifiPasswordView from './views/WifiPasswordView';


const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
    stateReconciler: hardSet,
};

const persistedReducer = persistReducer(persistConfig, swimtrackerReducer)
const store = createStore(persistedReducer);
const persistor = persistStore(store);
const Stack = createStackNavigator();

export default class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isReady: false,
            disconnected: true,
            isProvisioning: false,
        };
        this.unsubscribe = undefined;
    }

    componentDidMount() {
        this.setState({ isReady: true });
        this.device = new DeviceReduxCoupling(store);

        console.log("subscribing");
        let theApp = this;
        this.unsubscribe = store.subscribe(() => {
            const state = store.getState();
            theApp.setState({
                disconnected: state.deviceState.connState == ConnState.DISCONNECTED,
                isProvisioning: state.deviceState.wifiState == WifiState.AP_PROVISIONING || state.deviceState.wifiState == WifiState.UNKNOWN,
            });
        });
    }

    componentWillUnmount() {
        if (this.unsubscribe) {
            this.unsubscribe();
            console.log("unsubscribe");
        }
    }

    render() {
        if (!this.state.isReady) {
            return <AppLoading />;
        }
        const screenOptions = {
            headerShown: false,
        };

        let disconnectedView = (
            <>
                <Stack.Screen
                    name="ConnectingView"
                    options={screenOptions}
                    component={ConnectingView} />
            </>
        );

        let provisioningView = (
            <>
                <Stack.Screen
                    name="WifiSelectionView"
                    options={screenOptions} >
                    {props => <WifiSelectionView {...props} device={this.device} />}
                </Stack.Screen>
                <Stack.Screen
                    name="WifiPasswordView"
                    options={screenOptions}
                    component={WifiPasswordView}
                >
                </Stack.Screen>
            </>
        );

        let normalView = (
            <>
                <Stack.Screen
                    name="Home"
                    component={MainMenuView}
                    options={screenOptions}
                />
                <Stack.Screen
                    name="Settings"
                    component={SettingsView}
                    options={screenOptions}
                />
                <Stack.Screen
                    name="Training"
                    component={TrainingView}
                    options={screenOptions}
                />
                <Stack.Screen
                    name="LastSessions"
                    component={LastSessionsView}
                    options={screenOptions}
                />
            </>
        );

        let activeView;
        if (this.state.disconnected)
            activeView = disconnectedView;
        else if (this.state.isProvisioning)
            activeView = provisioningView;
        else
            activeView = normalView;

        return (
            <Provider store={store}>
                <PersistGate loading={<AppLoading />} persistor={persistor}>
                    <NavigationContainer>
                        <Stack.Navigator >
                            {activeView}
                        </Stack.Navigator>
                    </NavigationContainer>
                </PersistGate>
            </Provider>
        );


    }
}

