// @design-system: overlays/Toast
// Registered at /design-system#toast-overlay - Phase 3 (Agent 3E) will render the gallery.

import * as RadixToast from '@radix-ui/react-toast';
import { X } from 'lucide-react';
import { useEffect, useState } from 'react';
import { cn } from '@/lib/cn';
import { useT } from '@/lib/i18n/react';

// ─── Provider ─────────────────────────────────────────────────────────────

/** Toast provider - wraps the app root. */
export const ToastProvider = RadixToast.Provider;

// ─── Viewport ─────────────────────────────────────────────────────────────

/** Props for ToastViewport */
export type ToastViewportProps = React.ComponentPropsWithoutRef<typeof RadixToast.Viewport>;

/**
 * Toast viewport - the fixed container for all toasts.
 * Place once at the bottom of the app tree, inside the provider.
 */
export function ToastViewport({
  className,
  'aria-label': ariaLabel = 'Notifications',
  ...props
}: ToastViewportProps) {
  const [keyboardInset, setKeyboardInset] = useState(0);

  useEffect(() => {
    if (typeof window === 'undefined' || !window.visualViewport) return;
    const viewport = window.visualViewport;
    const updateKeyboardInset = () => {
      const nextInset = Math.max(0, window.innerHeight - viewport.height - viewport.offsetTop);
      setKeyboardInset(nextInset);
    };
    updateKeyboardInset();
    viewport.addEventListener('resize', updateKeyboardInset);
    viewport.addEventListener('scroll', updateKeyboardInset);
    return () => {
      viewport.removeEventListener('resize', updateKeyboardInset);
      viewport.removeEventListener('scroll', updateKeyboardInset);
    };
  }, []);

  return (
    <RadixToast.Viewport
      aria-label={ariaLabel}
      className={cn(
        'z-toast fixed end-0',
        'pointer-events-none flex flex-col items-end gap-2',
        'w-full max-w-sm p-4',
        'focus:outline-none',
        className,
      )}
      style={
        {
          bottom:
            'calc(var(--bottom-nav-height) + var(--safe-area-bottom) + var(--toast-keyboard-inset, 0px))',
          insetInlineStart: 'auto',
          '--toast-keyboard-inset': `${keyboardInset}px`,
        } as React.CSSProperties
      }
      {...props}
    />
  );
}

// ─── Tone styles ──────────────────────────────────────────────────────────

export type ToastTone = 'success' | 'warning' | 'danger' | 'info' | 'neutral';

const toneStyles: Record<ToastTone, string> = {
  success: 'border-success-500 bg-success-50 text-success-700',
  warning: 'border-warning-500 bg-warning-50 text-warning-700',
  danger: 'border-danger-500 bg-danger-50 text-danger-700',
  info: 'border-info-500 bg-info-50 text-info-700',
  neutral: 'border-border-default bg-surface-base text-neutral-900',
};

// ─── Toast root ────────────────────────────────────────────────────────────

/** Props for Toast */
export interface ToastProps extends React.ComponentPropsWithoutRef<typeof RadixToast.Root> {
  /** Visual tone of the toast. @default 'neutral' */
  tone?: ToastTone;
}

/**
 * Individual toast notification.
 */
export function Toast({ className, tone = 'neutral', children, ...props }: ToastProps) {
  return (
    <RadixToast.Root
      className={cn(
        'pointer-events-auto relative flex w-full items-start gap-3',
        'rounded-lg border',
        'p-4 shadow-lg',
        'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-bottom-4',
        'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-end-full',
        'data-[swipe=end]:animate-out data-[swipe=end]:fade-out',
        'data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]',
        'motion-safe:[transform:translateY(var(--toast-stack-offset,0))_scale(calc(1-var(--toast-stack-offset,0)/120))]',
        'motion-reduce:animate-none motion-reduce:transition-none',
        toneStyles[tone],
        className,
      )}
      {...props}
    >
      {children}
    </RadixToast.Root>
  );
}

// ─── Sub-components ────────────────────────────────────────────────────────

/** Props for ToastTitle */
export type ToastTitleProps = React.ComponentPropsWithoutRef<typeof RadixToast.Title>;

/** Toast title. */
export function ToastTitle({ className, ...props }: ToastTitleProps) {
  return <RadixToast.Title className={cn('text-sm font-medium', className)} {...props} />;
}

/** Props for ToastDescription */
export type ToastDescriptionProps = React.ComponentPropsWithoutRef<typeof RadixToast.Description>;

/** Toast description. */
export function ToastDescription({ className, ...props }: ToastDescriptionProps) {
  return <RadixToast.Description className={cn('text-sm opacity-80', className)} {...props} />;
}

/** Props for ToastClose */
export type ToastCloseProps = React.ComponentPropsWithoutRef<typeof RadixToast.Close>;

/** Close button for toast. */
export function ToastClose({ className, ...props }: ToastCloseProps) {
  const t = useT('toast');
  return (
    <RadixToast.Close
      className={cn(
        'absolute end-2 top-2',
        'flex h-6 w-6 items-center justify-center rounded-sm',
        'text-current opacity-50',
        'transition-opacity hover:opacity-100',
        'focus-visible:ring-brand-primary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',
        className,
      )}
      {...props}
      aria-label={t('dismiss')}
    >
      <X width={12} height={12} strokeWidth={2.5} aria-hidden="true" />
    </RadixToast.Close>
  );
}

/** Props for ToastAction */
export type ToastActionProps = React.ComponentPropsWithoutRef<typeof RadixToast.Action>;

/** Undo or follow-up action inside toast. */
export function ToastAction({ className, altText, ...props }: ToastActionProps) {
  return (
    <RadixToast.Action
      altText={altText}
      className={cn(
        'shrink-0 rounded-sm px-3 py-1',
        'text-xs font-medium',
        'border border-current opacity-70',
        'transition-opacity hover:opacity-100',
        'focus-visible:ring-brand-primary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',
        className,
      )}
      {...props}
    />
  );
}
