import React, { ReactNode } from "react"
import useSWR from "swr"
import { createContext, useContext } from 'react';

import { decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings"
import { useUnstableProvider } from "./UnstableProvider"

const MetadataProvider = createContext(null)
export const useMetadata = () => useContext(MetadataProvider)

const CACHE_VERSION = "v2"

export const MetadataProviderProvider = ({ children }) => {
    const { client, chainId } = useUnstableProvider()
    const { data: metadata } = useSWR(
        client && chainId ? ["metadata", client, chainId] : null,
        async ([_, client]) => {
            const storageKey = `metadata-${chainId}-${CACHE_VERSION}`
            const storedMetadata = sessionStorage.getItem(storageKey)

            if (storedMetadata) return unifyMetadata(decAnyMetadata(storedMetadata))

            Object.keys(sessionStorage).forEach(key => {
                if (key.startsWith("metadata-")) {
                    sessionStorage.removeItem(key);
                }
            });

            const metadata = await new Promise((resolve, reject) =>
                    client._request("state_getMetadata", [], {
                        onSuccess: resolve,
                        onError: reject,
                    }),
                )
                .then(r => r)
                .catch(_ => undefined)

            if (metadata) {
                sessionStorage.setItem(storageKey, metadata)
                return unifyMetadata(decAnyMetadata(metadata))
            } else {
                sessionStorage.removeItem(storageKey)
                return undefined
            }
        }
    )

    return (
        <MetadataProvider.Provider value={metadata}>
            {children}
        </MetadataProvider.Provider>
    )
}
