/**
 * Canonical toast configuration — single source of truth for toast durations,
 * position, and severity-to-handler mapping.
 *
 * Both `useFlashToasts` (server-side Inertia flash) and `useToastMessages`
 * (client-side imperative) read from this file so the toast experience is
 * identical regardless of where the toast originates.
 *
 * **Position:** top-right (set on the `<Toaster />` mount in `app.tsx`).
 *
 * **Durations** (per Severity → ms):
 *   success / info — 4 s   (confirmations users glance at)
 *   warning        — 6 s   (caution that needs to be read)
 *   error          — 7 s   (failure that may require an action)
 *
 * Rationale: success/info are "we did the thing" confirmations; users absorb
 * them in a glance. Warning/error require reading and sometimes a follow-up
 * action, so they linger longer. Going much past 7 s causes pile-up when
 * multiple toasts fire in sequence.
 */

import { toast } from 'sonner';

import { router } from '@inertiajs/react';

export type ToastSeverity = 'success' | 'error' | 'warning' | 'info';

/**
 * AI-KEY-RECOVERY-CTA: optional action shown as a clickable button inside the toast.
 * Mirrors the shape of `flash.recovery_action` emitted by the server.
 * `onClick` navigates via Inertia router (fire-and-forget — gotcha #11).
 */
export interface ToastAction {
  label: string;
  href: string;
}

/** Canonical duration in milliseconds, keyed by severity. */
export const TOAST_DURATIONS: Record<ToastSeverity, number> = {
  success: 4000,
  info: 4000,
  warning: 6000,
  error: 7000,
};

/** Canonical position for the Sonner Toaster. */
export const TOAST_POSITION = 'top-right' as const;

/**
 * Fire a toast of the given severity with the canonical duration.
 * Prefer this helper over calling `toast.success(...)` directly so that
 * duration drift can never re-emerge.
 *
 * The optional `action` parameter adds a clickable button to error toasts
 * (currently only used by AI-KEY-RECOVERY-CTA). Other severities ignore it
 * so existing callers with no third arg remain byte-for-byte identical.
 */
export function fireToast(severity: ToastSeverity, message: string, action?: ToastAction): void {
  const duration = TOAST_DURATIONS[severity];
  switch (severity) {
    case 'success':
      toast.success(message, { duration });
      return;
    case 'error':
      toast.error(message, {
        duration,
        ...(action
          ? {
              action: {
                label: action.label,
                // router.visit is fire-and-forget (gotcha #11) — do not await.
                // Relative-path guard: defense-in-depth against any future open-redirect
                // if an absolute URL somehow reaches this handler.
                onClick: () => {
                  if (!action.href.startsWith('/')) return;
                  router.visit(action.href);
                },
              },
            }
          : {}),
      });
      return;
    case 'warning':
      toast.warning(message, { duration });
      return;
    case 'info':
      toast.info(message, { duration });
      return;
  }
}
