'use client';

import { type ErrorInfo, type ReactNode } from 'react';
import { ErrorBoundary, type ErrorBoundaryFallbackProps } from './error-boundary';

interface ComponentErrorBoundaryProps {
  children: ReactNode;
  /**
   * Short label identifying the widget (e.g. "bản đồ", "thanh toán", "tìm kiếm").
   * Shown in the fallback UI so users understand which section failed.
   */
  label?: string;
  /**
   * Compact mode renders a smaller fallback suited to narrow widgets like cards
   * or sidebars. Defaults to false.
   */
  compact?: boolean;
  onError?: (error: Error, info: ErrorInfo) => void;
}

/**
 * Inline error boundary for critical widgets (map, payment form, search).
 *
 * Renders a contained, non-intrusive fallback that does not take over the page.
 * Captures errors to Sentry via the base `ErrorBoundary`.
 */
export function ComponentErrorBoundary({
  children,
  label,
  compact = false,
  onError,
}: ComponentErrorBoundaryProps) {
  return (
    <ErrorBoundary
      onError={onError}
      fallback={({ error, reset }) => (
        <ComponentFallback error={error} reset={reset} label={label} compact={compact} />
      )}
    >
      {children}
    </ErrorBoundary>
  );
}

function ComponentFallback({
  error,
  reset,
  label,
  compact,
}: ErrorBoundaryFallbackProps & { label?: string; compact: boolean }) {
  if (compact) {
    return (
      <div
        className="flex items-center gap-3 rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-sm"
        role="alert"
      >
        <svg
          className="h-4 w-4 shrink-0 text-destructive"
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
          aria-hidden="true"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"
          />
        </svg>
        <span className="flex-1 text-xs text-muted-foreground">
          {label ? `Lỗi ${label}` : 'Đã xảy ra lỗi'}
          {process.env.NODE_ENV !== 'production' && error.message
            ? `: ${error.message}`
            : ''}
        </span>
        <button
          onClick={reset}
          className="shrink-0 text-xs font-medium text-primary underline-offset-2 hover:underline focus-visible:outline-none"
        >
          Thử lại
        </button>
      </div>
    );
  }

  return (
    <div
      className="flex min-h-[160px] flex-col items-center justify-center rounded-lg border border-destructive/20 bg-destructive/5 px-6 py-6 text-center"
      role="alert"
    >
      <svg
        className="mb-2 h-7 w-7 text-destructive"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"
        />
      </svg>
      <p className="text-sm font-medium text-foreground">
        {label ? `Không thể tải ${label}` : 'Đã xảy ra lỗi'}
      </p>
      {process.env.NODE_ENV !== 'production' && error.message && (
        <p className="mt-1 max-w-xs truncate text-xs text-muted-foreground">{error.message}</p>
      )}
      <button
        onClick={reset}
        className="mt-4 inline-flex h-8 items-center justify-center rounded-md bg-primary px-4 text-xs font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
      >
        Thử lại
      </button>
    </div>
  );
}
