import * as React from 'react'
import { createPortal } from 'react-dom'
import { Toaster as SonnerToaster } from 'sonner'
import type { ToasterProps as SonnerToasterProps } from 'sonner'
import { getThemeFromDocument } from './theme-from-document'

export { toast } from 'sonner'

export type ToasterProps = Omit<SonnerToasterProps, 'theme'> & {
  theme?: 'light' | 'dark'
  /** 可选：Portal 根节点 data-style，主库可传入 useThemeStyle 的值 */
  dataStyle?: string
  /** 可选：Portal 根节点 data-theme，主库可传入 useThemeStyle 的值 */
  dataTheme?: string
}

/** 图标/文字用最小 token 间距；按钮与容器边缘、按钮之间用 spacing-2 */
const TOAST_INNER_GAP = 'calc(var(--spacing-px) * 2)'
const TOAST_EDGE_PADDING = 'var(--spacing-2)'
const TOAST_BUTTON_GAP = 'var(--spacing-2)'

/** 强制 toast 四边内边距 + 根节点 text-sm 变量 + 非首个按钮左间距；选择器带 data-styled 以覆盖 sonner */
const TOAST_PADDING_TOP_BOTTOM = 'var(--spacing-3)'
/** 根节点用设计系统 text-sm 变量；[data-content] 撑满中间；非首个按钮左间距 */
const TOAST_LAYOUT_FIX_CSS = `[data-sonner-toaster] [data-sonner-toast][data-styled="true"] { padding-left: ${TOAST_EDGE_PADDING} !important; padding-right: ${TOAST_EDGE_PADDING} !important; padding-top: ${TOAST_PADDING_TOP_BOTTOM} !important; padding-bottom: ${TOAST_PADDING_TOP_BOTTOM} !important; font-size: var(--font-size-sm) !important; line-height: var(--font-size-sm--line-height) !important; }
[data-sonner-toaster] [data-sonner-toast] [data-content] { flex: 1 !important; min-width: 0 !important; }
[data-sonner-toaster] [data-sonner-toast] [data-button]:not(:first-of-type) { margin-left: ${TOAST_BUTTON_GAP} !important; }`

const defaultToastOptions: NonNullable<SonnerToasterProps['toastOptions']> = {
  className: 'text-sm',
  style: {
    padding: `${TOAST_PADDING_TOP_BOTTOM} ${TOAST_EDGE_PADDING}`,
    gap: TOAST_INNER_GAP,
    background: 'var(--color-bg-container)',
    borderColor: 'var(--color-border-tertiary)',
    color: 'var(--color-text)',
  },
  descriptionClassName: 'text-xs text-text-secondary',
  actionButtonStyle: {
    borderRadius: 'var(--radius)',
    paddingLeft: 'var(--spacing-2)',
    paddingRight: 'var(--spacing-2)',
    height: 'var(--spacing-7)',
    fontSize: 'var(--font-size-xs)',
  },
  cancelButtonStyle: {
    borderRadius: 'var(--radius)',
    paddingLeft: 'var(--spacing-2)',
    paddingRight: 'var(--spacing-2)',
    height: 'var(--spacing-7)',
    fontSize: 'var(--font-size-xs)',
  },
}

const SONNER_GAP = 14
const SONNER_VISIBLE_TOASTS = 3
/** toaster 距视口右侧默认 24px，改为 8px 使按钮到屏幕边缘不会过大 */
const DEFAULT_OFFSET = { right: 8, left: 8, top: 24, bottom: 24 }

export function Toaster({ theme, toastOptions, dataStyle, dataTheme, icons, gap = SONNER_GAP, visibleToasts = SONNER_VISIBLE_TOASTS, offset = DEFAULT_OFFSET, ...props }: ToasterProps) {
  const fromDocument = getThemeFromDocument()
  const dataProps =
    dataStyle !== undefined || dataTheme !== undefined
      ? { 'data-style': dataStyle, 'data-theme': dataTheme }
      : fromDocument
  const resolvedTheme = theme ?? (typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light')

  const content = (
    <>
      <style dangerouslySetInnerHTML={{ __html: TOAST_LAYOUT_FIX_CSS }} />
      <div style={{ display: 'contents' }} {...dataProps}>
        <SonnerToaster
          theme={resolvedTheme}
          closeButton
          icons={icons}
          gap={gap}
          visibleToasts={visibleToasts}
          offset={offset}
          toastOptions={{
            ...defaultToastOptions,
            ...toastOptions,
            style: { ...defaultToastOptions.style, ...toastOptions?.style },
          }}
          style={
            {
              '--border-radius': 'var(--radius-lg)',
              fontFamily: 'inherit',
              '--gap': `${gap}px`,
              '--toast-icon-margin-start': '0',
              '--toast-icon-margin-end': TOAST_INNER_GAP,
              /* 控制 action/cancel 按钮间距：按钮间仅靠 toast 根 gap，不再额外 margin */
              '--toast-button-margin-start': 'auto',
              '--toast-button-margin-end': '0',
            } as React.CSSProperties
          }
          {...props}
        />
      </div>
    </>
  )

  return typeof document !== 'undefined' ? createPortal(content, document.body) : null
}
Toaster.displayName = 'Toaster'
