import { ReactNode, useRef } from 'react';
import { useToastRegion } from '@react-aria/toast';
import { useToastState } from '@react-stately/toast';
import type { AriaToastProps } from '@react-aria/toast';
import type { AriaToastRegionProps } from '@react-aria/toast';
import type { ToastState } from '@react-stately/toast';
import { CheckCircleIcon, ErrorIcon, InfoIcon, SettingsIcon, WarningIcon } from '@trail-ui/icons';

interface ToastNotificationProps {
  children: (state: ToastState<ReactNode>) => ReactNode;
  variant: 'default' | 'success' | 'warning' | 'error' | 'info';
  title?: string;
  duration?: number;
}

function ToastNotification({ children, ...props }: ToastNotificationProps) {
  let state = useToastState<ReactNode>({
    maxVisibleToasts: 3,
  });

  return (
    <>
      {children(state)}
      {state.visibleToasts.length > 0 && <ToastRegion {...props} state={state} />}
    </>
  );
}

interface ToastRegionProps<T> extends AriaToastRegionProps {
  state: ToastState<T>;
  variant: 'default' | 'success' | 'warning' | 'error' | 'info';
}

function ToastRegion<T extends ReactNode>({ state, ...props }: ToastRegionProps<T>) {
  let ref = useRef(null);
  let { regionProps } = useToastRegion(props, state, ref);

  return (
    <div
      {...regionProps}
      ref={ref}
      className="toast-region fixed bottom-4 flex w-full flex-col items-center gap-2"
    >
      {state.visibleToasts.map((toast) => (
        <Toast key={toast.key} toast={toast} variant={props.variant} />
      ))}
    </div>
  );
}

interface ToastProps<T> extends AriaToastProps<T> {
  variant: 'default' | 'success' | 'warning' | 'error' | 'info';
}

function Toast<T extends ReactNode>({ variant, ...props }: ToastProps<T>) {
  let color;
  let borderColor;
  let flagIcon;
  let bgColor;

  switch (variant) {
    case 'default':
      color = 'text-neutral-900';
      borderColor = 'border-neutral-300';
      flagIcon = <SettingsIcon height={24} width={24} />;
      bgColor = 'bg-neutral-50';
      break;
    case 'success':
      color = 'text-green-950';
      borderColor = 'border-green-950';
      flagIcon = <CheckCircleIcon height={24} width={24} />;
      bgColor = 'bg-green-50';
      break;
    case 'error':
      color = 'text-red-950';
      borderColor = 'border-red-950';
      flagIcon = <ErrorIcon height={24} width={24} />;
      bgColor = 'bg-red-50';
      break;
    case 'warning':
      color = 'text-yellow-950';
      borderColor = 'border-yellow-950';
      flagIcon = <WarningIcon height={24} width={24} />;
      bgColor = 'bg-yellow-50';
      break;
    case 'info':
      color = 'text-blue-950';
      borderColor = 'border-blue-950';
      flagIcon = <InfoIcon height={24} width={24} />;
      bgColor = 'bg-blue-50';
      break;
    default:
      break;
  }

  return (
    <div
      className={`toast ${bgColor} ${color} ${borderColor} shadow-medium flex h-14 w-[370px] items-center rounded border-l-4 px-4 text-base`}
    >
      <div>
        <div className="flex gap-4 font-semibold">
          {flagIcon}
          {props.toast.content}
        </div>
      </div>
    </div>
  );
}

export { ToastNotification };
export type { ToastNotificationProps };
