import { Navigate } from "@solidjs/router";
import { platform } from "@tauri-apps/plugin-os";
import { jwtDecode } from "jwt-decode";
import { type Component, type ParentProps, Show, useContext } from "solid-js";
import { save_token } from "tauri-plugin-ios-shared-token-api";
import { Notifications, NotificationsContext } from "./notifications";
import { useSearchImageContext } from "./contexts/SearchImageContext";

export const isTokenValid = (): boolean => {
    const token = localStorage.getItem("access");

    if (token == null) {
        return false;
    }

    try {
        jwtDecode(token);
        return true;
    } catch (err) {
        return false;
    }
};

const WithNotifications: Component<ParentProps> = (props) => {
    const { onRefetchImages } = useSearchImageContext();
    const notifications = Notifications(onRefetchImages);

    return (
        <NotificationsContext.Provider value={notifications}>
            {props.children}
        </NotificationsContext.Provider>
    );
};

export const useNotifications = () => {
    const notifications = useContext(NotificationsContext);
    if (notifications == null) {
        throw new Error("Notifications must be defined when using this hook");
    }

    return notifications;
};

export const ProtectedRoute: Component<ParentProps> = (props) => {
    const isValid = isTokenValid();

    if (isValid) {
        const token = localStorage.getItem("access");
        if (token == null) {
            throw new Error("unreachable");
        }

        if (platform() === "ios") {
            // iOS share extension is a seperate process to the App.
            // Therefore, we need to share our access token somewhere both the App & Share Extension can access
            // This involves App Groups.
            save_token(token)
                .then(() => console.log("Saved token!!!"))
                .catch((e) => console.error(e));
        }
    }

    return (
        <Show when={isValid} fallback={<Navigate href="/login" />}>
            <WithNotifications>{props.children}</WithNotifications>
        </Show>
    );
};
