import { useNavigate } from '@/router'
import { Alert } from '@blueprintjs/core'
import { createGraphiQLFetcher } from '@graphiql/toolkit'
import { useAuthIdentity } from '@inject/graphql/auth'
import { useHost } from '@inject/graphql/connection/host'
import { useWs } from '@inject/graphql/connection/ws'
import { httpGraphql } from '@inject/shared/config'
import Keys from '@inject/shared/localstorage/keys'
import authenticatedFetch from '@inject/shared/utils/authenticatedFetch'
import { useLocalStorageState } from 'ahooks'
import { Suspense, lazy } from 'react'

const GraphiQL = lazy(() => import('graphiql'))
import('graphiql/graphiql.css')

const GraphiQLPage = /* @__PURE__ */ () => {
  const ws = useWs()
  const host = useHost()
  const { isStaff } = useAuthIdentity()
  const [confirmed, setConfirmed] = useLocalStorageState(
    Keys.GRAPHIQL_CONFIRMED,
    {
      defaultValue: false,
    }
  )
  const nav = useNavigate()

  if (!isStaff) {
    return <p>You are not authorized to access this page</p>
  }

  if (!ws || !host) {
    return <p>No `WS` or `HOST` set to ApolloProviderWrapper</p>
  }

  const http = httpGraphql(host)

  return (
    <>
      <Suspense fallback={<p>Loading...</p>}>
        <GraphiQL
          /*
           * TODO: Fix Error: Your GraphiQL createFetcher is not properly configured for websocket subscriptions yet
           * Note: adding sessionid to wsConnectionParams did not fix the issue
           */
          fetcher={createGraphiQLFetcher({
            url: http,
            subscriptionUrl: ws,
            fetch: authenticatedFetch,
          })}
        />
      </Suspense>
      <Alert
        isOpen={!confirmed}
        cancelButtonText='Cancel'
        onCancel={() => nav('/')}
        confirmButtonText='Confirm'
        icon='warning-sign'
        intent='warning'
        onConfirm={() => setConfirmed(true)}
      >
        <p>
          You are about to access the GraphiQL interface. This interface allows
          you to interact with the backend directly.
        </p>
        <p>
          <strong>
            Do not use this interface unless you know what you are doing.
          </strong>
        </p>
      </Alert>
    </>
  )
}

export default GraphiQLPage
