import { useEffect, useMemo, useState } from 'react'
import SwaggerUI from 'swagger-ui-react'
import 'swagger-ui-react/swagger-ui.css'
import type { DocsBootstrap } from '../types/docsBootstrap'
import { apiUrl } from '../lib/apiOrigin'

type Props = {
  bootstrapPath: string
  authorization?: string | null
}

export function SwaggerDocs({ bootstrapPath, authorization }: Props) {
  const [bootstrap, setBootstrap] = useState<DocsBootstrap | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    ;(async () => {
      try {
        const headers: HeadersInit = { Accept: 'application/json' }
        if (authorization) {
          headers.Authorization = authorization
        }
        const res = await fetch(apiUrl(bootstrapPath), { headers })
        const body = await res.json().catch(() => null)
        if (!res.ok) {
          const msg =
            typeof body?.message === 'string'
              ? body.message
              : `HTTP ${res.status}`
          throw new Error(msg)
        }
        if (!cancelled) {
          setBootstrap(body as DocsBootstrap)
          setError(null)
        }
      } catch (e) {
        if (!cancelled) {
          setBootstrap(null)
          setError(e instanceof Error ? e.message : 'Failed to load docs config')
        }
      }
    })()
    return () => {
      cancelled = true
    }
  }, [bootstrapPath, authorization])

  useEffect(() => {
    if (bootstrap?.title) {
      document.title = bootstrap.title
    }
  }, [bootstrap?.title])

  const specUrl = useMemo(() => {
    if (!bootstrap?.openapi_url) {
      return ''
    }
    return apiUrl(bootstrap.openapi_url)
  }, [bootstrap])

  if (error) {
    return (
      <div className="docs-error">
        <p>{error}</p>
      </div>
    )
  }

  if (!bootstrap || !specUrl) {
    return <div className="docs-loading">Loading documentation…</div>
  }

  const hideAuthorize = !bootstrap.show_authorize_button

  return (
    <div className={`docs-root variant-${bootstrap.variant}`}>
      {bootstrap.welcome_name ? (
        <div className="admin-banner">
          Welcome, <span>{bootstrap.welcome_name}</span>
        </div>
      ) : null}
      {hideAuthorize ? <style>{`.swagger-ui .btn.authorize { display: none !important; }`}</style> : null}
      <SwaggerUI
        url={specUrl}
        docExpansion="none"
        defaultModelsExpandDepth={-1}
        deepLinking
        tryItOutEnabled={bootstrap.try_it_out_enabled}
        persistAuthorization={bootstrap.persist_authorization}
        requestInterceptor={(req: {
          headers: Record<string, string>
        }) => {
          if (authorization && !req.headers.Authorization) {
            req.headers.Authorization = authorization
          }
          return req
        }}
      />
    </div>
  )
}
