import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { notify } from './notify';

// Recursive: first non-empty string in a string | array | { message | error | detail }. Never throws.
function extractMessage(value: unknown): string | null {
  if (value == null) return null;
  if (typeof value === 'string') return value.trim() || null;
  if (Array.isArray(value)) {
    const parts = value.map(extractMessage).filter(Boolean) as string[];
    return parts.length ? parts.join(', ') : null;
  }
  if (typeof value === 'object') {
    const o = value as Record<string, unknown>;
    return extractMessage(o.message) ?? extractMessage(o.error) ?? extractMessage(o.detail) ?? null;
  }
  return null;
}

// HTTP status OR RTK string status (FETCH_ERROR/TIMEOUT_ERROR/PARSING_ERROR/CUSTOM_ERROR) → i18n key.
function statusKeyFor(status: number | string | undefined): string {
  if (status === 400 || status === 422) return 'msg.validationError';
  if (status === 401) return 'msg.authError';
  if (status === 403) return 'msg.permissionError';
  if (status === 404) return 'msg.notFoundError';
  if (status === 413) return 'msg.fileTooLarge';
  if (typeof status === 'number' && status >= 500) return 'msg.serverError';
  if (typeof status === 'string') return 'msg.networkError';
  return 'msg.genericError';
}

function logError(err: unknown): void {
  if (err && typeof err === 'object' && 'status' in err) {
    console.error('[API ERROR]', (err as { status?: unknown }).status, (err as { data?: unknown }).data);
    return;
  }
  console.error('Error caught:', err);
}

export function useErrorHandler() {
  const { t } = useTranslation();

  // Priority: backend message (FetchBaseQueryError.data) → Error.message → status/network fallback key.
  const getErrorMessage = useCallback(
    (err: unknown): string => {
      let status: number | string | undefined;
      if (err && typeof err === 'object' && ('status' in err || 'data' in err)) {
        status = (err as { status?: number | string }).status;
        const fromData = extractMessage((err as { data?: unknown }).data);
        if (fromData) return fromData;
      }
      if (err instanceof Error) {
        const fromError = extractMessage(err.message);
        if (fromError) return fromError;
      }
      return t(statusKeyFor(status));
    },
    [t],
  );

  const handleError = useCallback(
    (err: unknown): string => {
      logError(err);
      const message = getErrorMessage(err);
      notify.error(message);
      return message;
    },
    [getErrorMessage],
  );

  return { getErrorMessage, handleError };
}
