import { ReactNode, createContext, useContext, useEffect } from "react"
import { useLocation, useNavigate } from "react-router-dom"
import useSWR from "swr"
import { rpc } from "../api"
import { z } from "zod"

type Context = {
    keyring: {
        isLocked: boolean
        hasPassword: boolean
    }
    unlock(password: string): Promise<void>
    reset(password: string): Promise<void>
    lock(): Promise<void>
    refresh(): Promise<void>
}

const LocationStateSchema = z.object({
    pathname: z.string(),
    search: z.string().optional(),
})

const LockContext = createContext({} as Context)

export const KeyringProvider = ({ children }: { children?: ReactNode }) => {
    const {
        data: keyring,
        isLoading,
        error,
        mutate,
    } = useSWR("rpc.getKeyringState", () => rpc.client.getKeyringState())

    const navigate = useNavigate()
    const location = useLocation()

    if (isLoading || error) return null

    const refresh = async () => {
        await mutate()
    }
    const unlock = async (password: string) => {
        await rpc.client.unlockKeyring(password)
        await refresh()

        const locationResult = LocationStateSchema.safeParse(location.state)
        if (locationResult.success) {
            navigate({
                pathname: locationResult.data.pathname,
                search: locationResult.data.search,
            })
        } else {
            navigate("/accounts")
        }
    }
    const lock = async () => {
        await rpc.client.lockKeyring()
        await refresh()
        navigate("/unlock-keyring")
    }
    const reset = async (password: string) => {
        await rpc.client.resetKeyring(password)
        await refresh()
        navigate("/welcome")
    }
    const value = {
        keyring: keyring!,
        unlock,
        lock,
        reset,
        refresh,
    }
    return <LockContext.Provider value={value}>{children}</LockContext.Provider>
}

export const useKeyring = () => useContext(LockContext)
