import { toast } from 'sonner';
import { logger } from './logger';

export type ErrorContext = {
  action: string;
  userId?: string;
  metadata?: Record<string, unknown>;
};

export class AppError extends Error {
  constructor(
    message: string,
    public code: string,
    public userMessage?: string
  ) {
    super(message);
    this.name = 'AppError';
  }
}

export const handleError = (
  error: unknown,
  context: ErrorContext
): void => {
  const errorMessage = error instanceof AppError 
    ? error.userMessage || error.message
    : error instanceof Error 
    ? error.message 
    : 'An unexpected error occurred';

  // Log to console/monitoring
  logger.error('Error occurred', {
    ...context,
    error: error instanceof Error ? error.message : String(error),
    stack: error instanceof Error ? error.stack : undefined
  });

  // Show user-friendly toast
  toast.error(context.action, {
    description: errorMessage,
    duration: 5000
  });
};

export const handleSuccess = (
  title: string,
  description?: string
): void => {
  toast.success(title, {
    description,
    duration: 3000
  });
};

export const handleInfo = (
  title: string,
  description?: string
): void => {
  toast.info(title, {
    description,
    duration: 4000
  });
};

/**
 * Type-safe error message extraction utility
 * Use this instead of `error: any` in catch blocks
 */
export function getErrorMessage(error: unknown): string {
  if (error instanceof Error) {
    return error.message;
  }
  if (typeof error === 'string') {
    return error;
  }
  if (error && typeof error === 'object' && 'message' in error) {
    return String(error.message);
  }
  return 'An unexpected error occurred';
}

/**
 * Type guard to check if error has a code property
 */
export function hasErrorCode(error: unknown): error is { code: string } {
  return (
    error !== null &&
    typeof error === 'object' &&
    'code' in error &&
    typeof (error as { code: unknown }).code === 'string'
  );
}
