"use client"

import { Component, type ReactNode } from "react"
import { AlertCircle, RefreshCw } from "lucide-react"
import { useTranslations } from "next-intl"

import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"

type AiErrorBoundaryProps = {
  children: ReactNode
  /** 自定义 fallback 渲染 */
  fallback?: (error: Error, reset: () => void) => ReactNode
  /** 错误回调（用于埋点） */
  onError?: (error: Error, info: unknown) => void
}

type AiErrorBoundaryState = {
  error: Error | null
}

/**
 * AI 专用 Error Boundary
 *
 * 包裹所有 AI 数据区块，防止单个 AI 调用失败导致整页崩溃。
 * 提供重试按钮与友好的错误提示。
 */
export class AiErrorBoundary extends Component<
  AiErrorBoundaryProps,
  AiErrorBoundaryState
> {
  constructor(props: AiErrorBoundaryProps) {
    super(props)
    this.state = { error: null }
  }

  static getDerivedStateFromError(error: Error): AiErrorBoundaryState {
    return { error }
  }

  componentDidCatch(error: Error, info: unknown): void {
    if (this.props.onError) {
      this.props.onError(error, info)
    }
  }

  private handleReset = (): void => {
    this.setState({ error: null })
  }

  render(): ReactNode {
    if (this.state.error) {
      if (this.props.fallback) {
        return this.props.fallback(this.state.error, this.handleReset)
      }
      return <DefaultAiErrorFallback error={this.state.error} onReset={this.handleReset} />
    }
    return this.props.children
  }
}

function DefaultAiErrorFallback({
  error,
  onReset,
}: {
  error: Error
  onReset: () => void
}): ReactNode {
  const t = useTranslations("ai")
  return (
    <Card className="border-destructive/30">
      <CardHeader>
        <CardTitle className="flex items-center gap-2 text-destructive">
          <AlertCircle className="h-4 w-4" />
          {t("error.boundaryTitle")}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-3">
        <p className="text-sm text-muted-foreground">{t("error.boundaryDescription")}</p>
        <p className="text-xs text-muted-foreground/70 font-mono">{error.message}</p>
        <Button type="button" variant="outline" size="sm" onClick={onReset}>
          <RefreshCw className="mr-1 h-3.5 w-3.5" />
          {t("error.retry")}
        </Button>
      </CardContent>
    </Card>
  )
}
