import { useTranslation } from 'react-i18next'
import { useRouter } from '@tanstack/react-router'
import { useState } from 'react'
import { Button } from '@/ui'
import { GlobeLoader } from '@/ui/components/globe-loader'

/**
 * AppErrorBoundary — friendly UI который рендерится через TanStack Router
 * `errorComponent` когда route выкидывает unhandled exception (включая
 * "Maximum update depth exceeded" infinite loops).
 *
 * Юзер видит:
 *  - illustrated GlobeLoader (статичный paused)
 *  - "Что-то пошло не так. Попробуйте обновить страницу"
 *  - кнопки [Обновить] / [На главную]
 *  - dev-only collapsible с raw error (только в dev mode, не в prod)
 *
 * НЕ показывает raw stack trace в prod — это утечка деталей реализации
 * и тревожит юзера.
 */

export type AppErrorBoundaryProps = {
  error: Error
  reset?: () => void
}

export function AppErrorBoundary({ error, reset }: AppErrorBoundaryProps) {
  const { t } = useTranslation()
  const router = useRouter()
  const [showDetails, setShowDetails] = useState(false)
  // Vite dev mode → import.meta.env.DEV — показываем raw error для разработки.
  const isDev = import.meta.env.DEV

  const handleRetry = () => {
    if (reset) reset()
    else router.invalidate()
  }

  const handleHome = () => {
    router.navigate({ to: '/dictionaries' })
  }

  return (
    <div
      role="alert"
      className="min-h-[60vh] flex flex-col items-center justify-center px-6 py-12 text-center"
    >
      <div className="opacity-40 mb-6">
        <GlobeLoader size={120} />
      </div>
      <h1 className="text-title-xl text-ink font-semibold mb-2">
        {t('error.boundary.title', { defaultValue: 'Что-то пошло не так' })}
      </h1>
      <p className="text-body text-mute max-w-md mb-6">
        {t('error.boundary.description', {
          defaultValue:
            'Произошла непредвиденная ошибка при отображении страницы. Попробуйте обновить — обычно это помогает. Если повторится, сообщите нам.',
        })}
      </p>
      <div className="flex items-center gap-2">
        <Button variant="primary" size="sm" onClick={handleRetry}>
          {t('error.boundary.retry', { defaultValue: 'Обновить' })}
        </Button>
        <Button variant="ghost" size="sm" onClick={handleHome}>
          {t('error.boundary.home', { defaultValue: 'На главную' })}
        </Button>
      </div>
      {isDev && (
        <div className="mt-8 w-full max-w-2xl text-left">
          <button
            type="button"
            onClick={() => setShowDetails((v) => !v)}
            className="text-cell text-mute hover:text-ink-2 underline underline-offset-2"
          >
            {showDetails ? 'Скрыть детали (dev)' : 'Показать детали (dev)'}
          </button>
          {showDetails && (
            <pre className="mt-2 rounded-md border border-line bg-surface-2 p-3 text-mono text-cell text-ink-2 overflow-auto max-h-64 whitespace-pre-wrap">
              {error.message}
              {error.stack ? `\n\n${error.stack}` : ''}
            </pre>
          )}
        </div>
      )}
    </div>
  )
}
