import type { FallbackProps } from 'react-error-boundary';
import { useNavigate } from 'react-router-dom';
import { AlertTriangle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { toUserMessage } from '@/lib/errors';
import { appEnv } from '@/config/env';

function ErrorCard({
  error,
  onGoHome,
  onRetry,
}: {
  error: unknown;
  onGoHome: () => void;
  onRetry: () => void;
}) {
  return (
    <div className="flex h-screen w-full items-center justify-center p-6">
      <Card className="w-full max-w-md">
        <CardHeader>
          <div className="flex items-center gap-2">
            <AlertTriangle className="text-destructive size-4" />
            <CardTitle>Something went wrong</CardTitle>
          </div>
          <CardDescription>{toUserMessage(error)}</CardDescription>
        </CardHeader>
        {appEnv === 'dev' && error instanceof Error ? (
          <CardContent>
            <details className="text-muted-foreground text-xs">
              <summary className="cursor-pointer select-none">
                Technical details
              </summary>
              <pre className="mt-2 max-h-48 overflow-auto whitespace-pre-wrap break-all">
                {error.stack ?? error.message}
              </pre>
            </details>
          </CardContent>
        ) : null}
        <CardFooter className="flex gap-2">
          <Button size="sm" onClick={onGoHome}>
            Go home
          </Button>
          <Button size="sm" variant="outline" onClick={onRetry}>
            Try again
          </Button>
        </CardFooter>
      </Card>
    </div>
  );
}

// Outside the router `useNavigate` is unavailable, so "Go home" drops the hash directly.
export function TopLevelErrorFallback({
  error,
  resetErrorBoundary,
}: FallbackProps) {
  const goHome = () => {
    window.location.hash = '#/';
    resetErrorBoundary();
  };
  return (
    <ErrorCard error={error} onGoHome={goHome} onRetry={resetErrorBoundary} />
  );
}

export function RouteErrorFallback({
  error,
  resetErrorBoundary,
}: FallbackProps) {
  const navigate = useNavigate();
  const goHome = () => {
    navigate('/');
    resetErrorBoundary();
  };
  return (
    <ErrorCard error={error} onGoHome={goHome} onRetry={resetErrorBoundary} />
  );
}
