'use client';

import { QueryClientProvider, QueryErrorResetBoundary } from '@tanstack/react-query';
import { useTranslations } from 'next-intl';
import { Component, type ErrorInfo, type ReactNode } from 'react';
import { getQueryClient } from '@/lib/query-client';

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

function QueryErrorFallback({ error, reset }: FallbackProps) {
  const t = useTranslations();

  return (
    <div className="flex min-h-[200px] flex-col items-center justify-center px-4" role="alert">
      <p className="text-sm text-destructive">{t('error.description')}</p>
      {error.message && (
        <p className="mt-1 text-xs text-muted-foreground">{error.message}</p>
      )}
      <button
        onClick={reset}
        className="mt-3 inline-flex h-8 items-center rounded-md bg-primary px-4 text-xs font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
      >
        {t('common.retry')}
      </button>
    </div>
  );
}

interface ErrorBoundaryState {
  error: Error | null;
}

class QueryErrorBoundaryInner extends Component<
  { children: ReactNode; onReset: () => void },
  ErrorBoundaryState
> {
  override state: ErrorBoundaryState = { error: null };

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

  override componentDidCatch(error: Error, info: ErrorInfo) {
    if (process.env.NODE_ENV !== 'production') {
      console.error('Query error boundary caught:', error, info);
    }
  }

  reset = () => {
    this.props.onReset();
    this.setState({ error: null });
  };

  override render() {
    if (this.state.error) {
      return <QueryErrorFallback error={this.state.error} reset={this.reset} />;
    }
    return this.props.children;
  }
}

export function QueryProvider({ children }: { children: React.ReactNode }) {
  const queryClient = getQueryClient();
  return (
    <QueryClientProvider client={queryClient}>
      <QueryErrorResetBoundary>
        {({ reset }) => (
          <QueryErrorBoundaryInner onReset={reset}>
            {children}
          </QueryErrorBoundaryInner>
        )}
      </QueryErrorResetBoundary>
    </QueryClientProvider>
  );
}
