import type { ShowToastRequest } from '@yaakapp-internal/plugins';
import classNames from 'classnames';
import * as m from 'motion/react-m';
import type { ReactNode } from 'react';

import { useKey } from 'react-use';
import { Icon, type IconProps } from '@yaakapp-internal/ui';
import { IconButton } from './IconButton';
import { VStack } from './Stacks';

export interface ToastProps {
  children: ReactNode;
  open: boolean;
  onClose: () => void;
  className?: string;
  timeout: number | null;
  action?: (args: { hide: () => void }) => ReactNode;
  icon?: ShowToastRequest['icon'] | null;
  color?: ShowToastRequest['color'];
}

const ICONS: Record<NonNullable<ToastProps['color'] | 'custom'>, IconProps['icon'] | null> = {
  custom: null,
  danger: 'alert_triangle',
  info: 'info',
  notice: 'alert_triangle',
  primary: 'info',
  secondary: 'info',
  success: 'check_circle',
  warning: 'alert_triangle',
};

export function Toast({ children, open, onClose, timeout, action, icon, color }: ToastProps) {
  useKey(
    'Escape',
    () => {
      if (!open) return;
      onClose();
    },
    {},
    [open],
  );

  const toastIcon = icon === null ? null : (icon ?? (color && color in ICONS && ICONS[color]));

  return (
    <m.div
      initial={{ opacity: 0, right: '-10%' }}
      animate={{ opacity: 100, right: 0 }}
      exit={{ opacity: 0, right: '-100%' }}
      transition={{ duration: 0.2 }}
      className={classNames('bg-surface m-2 rounded-lg')}
    >
      <div
        className={classNames(
          `x-theme-toast x-theme-toast--${color}`,
          'pointer-events-auto overflow-hidden',
          'relative pointer-events-auto bg-surface text-text rounded-lg',
          'border border-border shadow-lg w-[25rem]',
        )}
      >
        <div className="pl-3 py-3 pr-10 flex items-start gap-2 w-full max-h-[11rem] overflow-auto">
          {toastIcon && <Icon icon={toastIcon} color={color} className="mt-1 flex-shrink-0" />}
          <VStack space={2} className="w-full min-w-0">
            <div className="select-auto">{children}</div>
            {action?.({ hide: onClose })}
          </VStack>
        </div>

        <IconButton
          color={color}
          variant="border"
          className="opacity-60 border-0 !absolute top-2 right-2"
          title="Dismiss"
          icon="x"
          onClick={onClose}
        />

        {timeout != null && (
          <div className="w-full absolute bottom-0 left-0 right-0">
            <m.div
              className="bg-surface-highlight h-[3px]"
              initial={{ width: '100%' }}
              animate={{ width: '0%', opacity: 0.2 }}
              transition={{ duration: timeout / 1000, ease: 'linear' }}
            />
          </div>
        )}
      </div>
    </m.div>
  );
}
