type ToastTheme = 'info' | 'success' | 'warn' | 'error';

type ToastStyle = {
  background: string;
  color: string;
  icon: string;
};

type ToastInstance = {
  close: () => void;
};

type ToastMethod = (message: string, duration?: number) => ToastInstance;

type ToastAPI = {
  info: ToastMethod;
  success: ToastMethod;
  warn: ToastMethod;
  error: ToastMethod;
  closeAll: () => void;
};

const TOAST_CONTAINER_ID = 'custom-toast-container';

const THEME_MAP: Record<ToastTheme, ToastStyle> = {
  info: {
    background: 'rgba(0, 0, 0, 0.82)',
    color: '#ffffff',
    icon: 'i',
  },
  success: {
    background: '#e8f8ee',
    color: '#0f9d58',
    icon: '✓',
  },
  warn: {
    background: '#fff7e8',
    color: '#d97706',
    icon: '!',
  },
  error: {
    background: '#fdecec',
    color: '#dc2626',
    icon: '×',
  },
};

const isBrowser = (): boolean =>
  typeof window !== 'undefined' && typeof document !== 'undefined';

const getContainer = (): HTMLDivElement | null => {
  if (!isBrowser()) {
    return null;
  }

  const existingContainer = document.getElementById(TOAST_CONTAINER_ID);

  if (existingContainer instanceof HTMLDivElement) {
    return existingContainer;
  }

  const container = document.createElement('div');
  container.id = TOAST_CONTAINER_ID;
  container.style.position = 'fixed';
  container.style.top = '20px';
  container.style.left = '50%';
  container.style.transform = 'translateX(-50%)';
  container.style.zIndex = '99999';
  container.style.display = 'flex';
  container.style.flexDirection = 'column';
  container.style.alignItems = 'center';
  container.style.gap = '12px';
  container.style.pointerEvents = 'none';
  document.body.appendChild(container);

  return container;
};

const removeToast = (
  toastElement: HTMLDivElement,
  container: HTMLDivElement,
): void => {
  toastElement.style.opacity = '0';
  toastElement.style.transform = 'translateY(-8px)';

  window.setTimeout(() => {
    if (toastElement.parentNode) {
      toastElement.parentNode.removeChild(toastElement);
    }

    if (container.childNodes.length === 0 && container.parentNode) {
      container.parentNode.removeChild(container);
    }
  }, 250);
};

const createToast = (
  type: ToastTheme,
  message: string,
  duration = 2500,
): ToastInstance => {
  const container = getContainer();

  if (!container) {
    return {
      close: () => {},
    };
  }

  const config = THEME_MAP[type];
  const toastElement = document.createElement('div');
  const iconElement = document.createElement('span');
  const textElement = document.createElement('span');
  const content = message == null ? '' : String(message);

  toastElement.style.display = 'flex';
  toastElement.style.alignItems = 'center';
  toastElement.style.maxWidth = '80vw';
  toastElement.style.minWidth = '180px';
  toastElement.style.padding = '12px 16px';
  toastElement.style.borderRadius = '12px';
  toastElement.style.background = config.background;
  toastElement.style.color = config.color;
  toastElement.style.boxShadow = '0 8px 24px rgba(0, 0, 0, 0.12)';
  toastElement.style.fontSize = '14px';
  toastElement.style.lineHeight = '1.4';
  toastElement.style.pointerEvents = 'auto';
  toastElement.style.wordBreak = 'break-word';
  toastElement.style.opacity = '0';
  toastElement.style.transform = 'translateY(-8px)';
  toastElement.style.transition = 'all 0.25s ease';

  iconElement.textContent = config.icon;
  iconElement.style.display = 'inline-flex';
  iconElement.style.alignItems = 'center';
  iconElement.style.justifyContent = 'center';
  iconElement.style.width = '18px';
  iconElement.style.height = '18px';
  iconElement.style.marginRight = '8px';
  iconElement.style.fontWeight = '700';
  iconElement.style.flex = '0 0 auto';

  textElement.textContent = content;
  textElement.style.whiteSpace = 'pre-wrap';
  textElement.style.flex = '1';

  toastElement.appendChild(iconElement);
  toastElement.appendChild(textElement);
  container.appendChild(toastElement);

  window.requestAnimationFrame(() => {
    toastElement.style.opacity = '1';
    toastElement.style.transform = 'translateY(0)';
  });

  const close = (): void => removeToast(toastElement, container);

  if (duration > 0) {
    window.setTimeout(close, duration);
  }

  return { close };
};

const toast: ToastAPI = {
  info(message, duration) {
    return createToast('info', message, duration);
  },

  success(message, duration) {
    return createToast('success', message, duration);
  },

  warn(message, duration) {
    return createToast('warn', message, duration);
  },

  error(message, duration) {
    return createToast('error', message, duration);
  },

  closeAll() {
    if (!isBrowser()) {
      return;
    }

    const container = document.getElementById(TOAST_CONTAINER_ID);

    if (container) {
      container.remove();
    }
  },
};

export default toast;
