const MAX_VISIBLE_TOASTS = 3
const DEFAULT_DURATION = {
  success: 3000,
  error: 5000,
  info: 4000,
  warning: 4500
}

const ICON_MAP = {
  success: '✅',
  error: '❌',
  info: 'ℹ️',
  warning: '⚠️'
}

let stylesInjected = false
let toastContainer = null
let activeToasts = new Map()

function injectStyles() {
  if (stylesInjected || typeof document === 'undefined') return

  const styleEl = document.createElement('style')
  styleEl.textContent = `
#toast-container {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 99999;
  display: flex;
  flex-direction: column-reverse;
  gap: 10px;
  max-width: 400px;
  pointer-events: none;
}

.toast {
  position: relative;
  min-width: 280px;
  max-width: 400px;
  padding: 14px 16px;
  border-radius: 10px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(10px);
  background: rgba(255, 255, 255, 0.95);
  pointer-events: auto;
  animation: toast-enter 0.3s cubic-bezier(0.21, 1.02, 0.73, 1);
}

@keyframes toast-enter {
  from { transform: translateX(100%); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}

@keyframes toast-exit {
  to { transform: translateX(100%); opacity: 0; }
}

.toast-exit { animation: toast-exit 0.3s ease-in forwards; }

.toast-content {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.toast-icon {
  font-size: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

.toast-body {
  flex: 1;
  min-width: 0;
}

.toast-title {
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 4px;
  line-height: 1.3;
}

.toast-message {
  font-size: 13px;
  color: #4b5563;
  line-height: 1.4;
  word-break: break-word;
}

.toast-close {
  background: none;
  border: none;
  font-size: 18px;
  color: #9ca3af;
  cursor: pointer;
  padding: 0 2px;
  transition: color 0.15s;
}
.toast-close:hover { color: #4b5563; }

.toast-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 3px;
  border-radius: 0 0 10px 10px;
  animation: toast-timer linear forwards;
}

@keyframes toast-timer {
  from { width: 100%; }
  to   { width: 0%; }
}

.toast-success { border-left: 4px solid #10b981; }
.toast-success .toast-progress { background: #10b981; }

.toast-error { border-left: 4px solid #ef4444; }
.toast-error .toast-progress { background: #ef4444; }

.toast-info { border-left: 4px solid #3b82f6; }
.toast-info .toast-progress { background: #3b82f6; }

.toast-warning { border-left: 4px solid #f59e0b; }
.toast-warning .toast-progress { background: #f59e0b; }

@media (max-width: 480px) {
  #toast-container {
    left: 10px;
    right: 10px;
    max-width: calc(100vw - 20px);
  }
  .toast {
    min-width: auto;
    max-width: 100%;
  }
}
`

  document.head.appendChild(styleEl)
  stylesInjected = true
}

function ensureContainer() {
  if (toastContainer) return toastContainer

  if (typeof document === 'undefined') return null

  toastContainer = document.createElement('div')
  toastContainer.id = 'toast-container'
  toastContainer.setAttribute('role', 'alert')
  toastContainer.setAttribute('aria-live', 'polite')
  document.body.appendChild(toastContainer)

  return toastContainer
}

function createToastElement({ type, title, message, duration, closable }) {
  const toastId = `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
  const icon = ICON_MAP[type] || 'ℹ️'

  const toastEl = document.createElement('div')
  toastEl.className = `toast toast-${type}`
  toastEl.id = toastId
  toastEl.setAttribute('role', 'status')

  let closeBtnHTML = ''
  if (closable !== false) {
    closeBtnHTML = `<button class="toast-close" aria-label="关闭">&times;</button>`
  }

  let titleHTML = ''
  if (title) {
    titleHTML = `<div class="toast-title">${escapeHtml(title)}</div>`
  }

  const progressStyle = duration > 0 ? `animation-duration: ${duration}ms` : ''

  toastEl.innerHTML = `
    <div class="toast-content">
      <span class="toast-icon">${icon}</span>
      <div class="toast-body">
        ${titleHTML}
        <div class="toast-message">${escapeHtml(message)}</div>
      </div>
      ${closeBtnHTML}
    </div>
    ${duration > 0 ? `<div class="toast-progress" style="${progressStyle}"></div>` : ''}
  `

  if (closable !== false) {
    const closeBtn = toastEl.querySelector('.toast-close')
    closeBtn.addEventListener('click', () => removeToast(toastId))
  }

  return { toastId, toastEl }
}

function removeToast(toastId) {
  const container = ensureContainer()
  if (!container) return

  const toastEl = document.getElementById(toastId)
  if (!toastEl) return

  toastEl.classList.add('toast-exit')

  setTimeout(() => {
    if (toastEl.parentNode) {
      toastEl.parentNode.removeChild(toastEl)
    }
    activeToasts.delete(toastId)

    adjustContainerPosition()
  }, 300)
}

function adjustContainerPosition() {
  const container = ensureContainer()
  if (!container) return

  const containerRect = container.getBoundingClientRect()
  const viewportHeight = window.innerHeight

  if (containerRect.top < 80 && containerRect.height > viewportHeight * 0.5) {
    container.style.bottom = 'auto'
    container.style.top = '20px'
  } else {
    container.style.top = 'auto'
    container.style.bottom = '20px'
  }
}

function escapeHtml(text) {
  const div = document.createElement('div')
  div.textContent = text
  return div.innerHTML
}

function enforceMaxLimit() {
  while (activeToasts.size >= MAX_VISIBLE_TOASTS) {
    const oldestToastId = activeToasts.keys().next().value
    if (oldestToastId) {
      removeToast(oldestToastId)
      break
    }
  }
}

export function showToast(options) {
  injectStyles()

  const {
    type = 'info',
    title,
    message,
    duration,
    closable = true
  } = options

  if (!message) {
    console.warn('[Toast] message is required')
    return null
  }

  const validTypes = ['success', 'error', 'info', 'warning']
  if (!validTypes.includes(type)) {
    console.warn(`[Toast] Invalid type: "${type}", falling back to "info"`)
    options.type = 'info'
  }

  const resolvedDuration = duration !== undefined ? duration : (DEFAULT_DURATION[type] || DEFAULT_DURATION.info)

  enforceMaxLimit()

  const container = ensureContainer()
  if (!container) return null

  const { toastId, toastEl } = createToastElement({
    type: options.type || type,
    title,
    message,
    duration: resolvedDuration,
    closable
  })

  container.appendChild(toastEl)
  activeToasts.set(toastId, { element: toastEl, timer: null })

  if (resolvedDuration > 0) {
    const timer = setTimeout(() => {
      removeToast(toastId)
    }, resolvedDuration)

    activeToasts.set(toastId, { element: toastEl, timer })
  }

  setTimeout(() => {
    adjustContainerPosition()
  }, 50)

  return toastId
}

export function notifySuccess(message, title = '操作成功') {
  return showToast({
    type: 'success',
    title,
    message
  })
}

export function notifyError(message, title = '操作失败') {
  return showToast({
    type: 'error',
    title,
    message
  })
}

export function notifyInfo(message, title = '提示') {
  return showToast({
    type: 'info',
    title,
    message
  })
}

export function notifyWarning(message, title = '注意') {
  return showToast({
    type: 'warning',
    title,
    message
  })
}

export function clearAllToasts() {
  for (const [toastId] of activeToasts) {
    removeToast(toastId)
  }
}
