import * as Sentry from '@sentry/react'
import { type ReactNode, useEffect, useRef } from 'react'
import { Button } from '@/components/ui/Button'

interface FallbackProps {
  error: Error
  resetError: () => void
}

function isChunkLoadError(error: Error): boolean {
  const msg = error.message || ''
  return (
    msg.includes('dynamically imported module') ||
    msg.includes('Loading chunk') ||
    msg.includes('Failed to fetch') ||
    error.name === 'ChunkLoadError'
  )
}

function DefaultFallback({ error, resetError }: FallbackProps) {
  const reloadingRef = useRef(false)

  // Auto-reload on stale chunk errors (happens after deployments)
  useEffect(() => {
    if (!isChunkLoadError(error)) return
    const key = 'rf_boundary_chunk_reload'
    const lastReload = sessionStorage.getItem(key)
    const now = Date.now()
    if (!lastReload || now - Number(lastReload) > 10_000) {
      sessionStorage.setItem(key, String(now))
      reloadingRef.current = true
      window.location.reload()
    }
  }, [error])

  return (
    <div className="flex min-h-[400px] flex-col items-center justify-center p-8">
      <div className="max-w-md text-center">
        <h2 className="mb-2 text-xl font-semibold text-red-400">
          Something went wrong
        </h2>
        <p className="mb-4 text-muted-foreground">
          An unexpected error occurred. Please try refreshing the page.
        </p>
        <pre className="mb-4 overflow-auto rounded-xl bg-white/5 border border-border p-3 text-left text-xs text-red-400">
          {error.message}
        </pre>
        <div className="flex justify-center gap-3">
          <Button variant="secondary" onClick={resetError}>
            Try Again
          </Button>
          <Button onClick={() => window.location.reload()}>
            Refresh Page
          </Button>
        </div>
      </div>
    </div>
  )
}

interface Props {
  children: ReactNode
  fallback?: ReactNode
}

export function ErrorBoundary({ children, fallback }: Props) {
  return (
    <Sentry.ErrorBoundary
      fallback={({ error, resetError }) => {
        if (fallback) return fallback as React.ReactElement
        return <DefaultFallback error={error as Error} resetError={resetError} />
      }}
      beforeCapture={(scope, error) => {
        // Don't report chunk load errors to Sentry — they're deploy artifacts, not bugs
        if (error && isChunkLoadError(error as Error)) {
          scope.setLevel('info')
          scope.setTag('chunk_load_error', 'true')
        }
      }}
      showDialog={false}
    >
      {children}
    </Sentry.ErrorBoundary>
  )
}

export default ErrorBoundary
