import * as React from 'react'

import { cn } from './utils'

/* ------------------------------------------------------------------ */
/*  Types                                                              */
/* ------------------------------------------------------------------ */

export type NotificationLevel = 'info' | 'success' | 'warning' | 'error'

export interface NotificationItem {
  id: string
  title: string
  description?: string
  level?: NotificationLevel
  timestamp: Date
  read?: boolean
  icon?: React.ReactNode
  action?: {
    label: string
    onClick: (id: string) => void
  }
}

/* ------------------------------------------------------------------ */
/*  Helpers                                                            */
/* ------------------------------------------------------------------ */

function formatRelativeTime(date: Date): string {
  const diff = Date.now() - date.getTime()
  const seconds = Math.floor(diff / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  const days = Math.floor(hours / 24)

  if (seconds < 60) return 'Just now'
  if (minutes < 60) return `${String(minutes)}m ago`
  if (hours < 24) return `${String(hours)}h ago`
  if (days < 7) return `${String(days)}d ago`
  return date.toLocaleDateString()
}

/* ------------------------------------------------------------------ */
/*  NotificationCenter                                                 */
/* ------------------------------------------------------------------ */

export interface NotificationCenterProps extends React.ComponentProps<'div'> {
  notifications: NotificationItem[]
  maxVisible?: number
  emptyMessage?: string
  onMarkRead?: (id: string) => void
  onMarkAllRead?: () => void
  onDismiss?: (id: string) => void
  onClearAll?: () => void
}

function NotificationCenter({
  className,
  notifications,
  maxVisible = 50,
  emptyMessage = 'No notifications',
  onMarkRead,
  onMarkAllRead,
  onDismiss,
  onClearAll,
  ...props
}: NotificationCenterProps) {
  const visible = notifications.slice(0, maxVisible)
  const unreadCount = notifications.filter(n => n.read !== true).length

  return (
    <div
      data-slot="notification-center"
      role="region"
      aria-label="Notification center"
      className={cn(
        'flex flex-col rounded-xl border border-border-glass bg-glass backdrop-blur-[20px]',
        'w-full max-w-sm overflow-hidden',
        className
      )}
      {...props}
    >
      {/* Header */}
      <div className="flex items-center justify-between border-b border-border-glass px-4 py-3">
        <div className="flex items-center gap-2">
          <span className="text-sm font-semibold text-foreground">Notifications</span>
          {unreadCount > 0 && (
            <span
              aria-label={`${String(unreadCount)} unread`}
              className="inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-accent-rose px-1.5 text-[10px] font-bold text-white"
            >
              {unreadCount}
            </span>
          )}
        </div>
        <div className="flex items-center gap-1">
          <button
            type="button"
            onClick={onMarkAllRead}
            className="rounded-lg px-2 py-1 text-[11px] text-foreground-secondary transition-colors hover:bg-glass-hover hover:text-foreground"
          >
            Mark all read
          </button>
          <button
            type="button"
            onClick={onClearAll}
            className="rounded-lg px-2 py-1 text-[11px] text-foreground-secondary transition-colors hover:bg-glass-hover hover:text-foreground"
          >
            Clear all
          </button>
        </div>
      </div>

      {/* List */}
      <div role="list" className="flex max-h-80 flex-col overflow-y-auto">
        {visible.length === 0 ? (
          <div className="flex items-center justify-center px-4 py-8 text-sm text-foreground-muted">
            {emptyMessage}
          </div>
        ) : (
          visible.map(item => (
            <NotificationCenterItem
              key={item.id}
              item={item}
              onMarkRead={onMarkRead}
              onDismiss={onDismiss}
            />
          ))
        )}
      </div>
    </div>
  )
}

/* ------------------------------------------------------------------ */
/*  NotificationCenterItem                                             */
/* ------------------------------------------------------------------ */

interface NotificationCenterItemProps {
  item: NotificationItem
  onMarkRead?: ((id: string) => void) | undefined
  onDismiss?: ((id: string) => void) | undefined
}

function NotificationCenterItem({ item, onMarkRead, onDismiss }: NotificationCenterItemProps) {
  const level = item.level ?? 'info'

  return (
    <div
      role="listitem"
      data-notification-id={item.id}
      onClick={() => {
        if (item.read !== true) onMarkRead?.(item.id)
      }}
      className={cn(
        'group flex gap-3 border-b border-border-glass px-4 py-3 transition-colors last:border-b-0',
        item.read !== true && 'bg-primary/5 cursor-pointer',
        item.read === true && 'opacity-70'
      )}
    >
      {/* Level dot */}
      <div className="flex shrink-0 pt-0.5">
        <span
          aria-hidden="true"
          className={cn('inline-block size-2 rounded-full', {
            'bg-accent-cyan': level === 'info',
            'bg-accent-emerald': level === 'success',
            'bg-accent-amber': level === 'warning',
            'bg-accent-rose': level === 'error',
          })}
        />
      </div>

      {/* Content */}
      <div className="flex min-w-0 flex-1 flex-col gap-0.5">
        <span className="text-sm font-medium text-foreground">{item.title}</span>
        {item.description !== undefined && (
          <span className="truncate text-xs text-foreground-secondary" title={item.description}>
            {item.description}
          </span>
        )}
        <span className="text-[11px] text-foreground-muted">
          {formatRelativeTime(item.timestamp)}
        </span>
      </div>

      {/* Actions */}
      <div className="flex shrink-0 items-start gap-1">
        {item.action !== undefined && (
          <button
            type="button"
            onClick={e => {
              e.stopPropagation()
              item.action?.onClick(item.id)
            }}
            className="rounded-lg px-2 py-0.5 text-[11px] font-medium text-primary transition-colors hover:bg-primary/10"
          >
            {item.action.label}
          </button>
        )}
        <button
          type="button"
          aria-label="Dismiss notification"
          onClick={e => {
            e.stopPropagation()
            onDismiss?.(item.id)
          }}
          className="rounded-lg p-0.5 text-foreground-muted opacity-0 transition-all hover:bg-glass-hover hover:text-foreground group-hover:opacity-100"
        >
          <svg
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth={2}
            strokeLinecap="round"
            strokeLinejoin="round"
            className="size-3.5"
          >
            <path d="m18 6-12 12" />
            <path d="m6 6 12 12" />
          </svg>
        </button>
      </div>
    </div>
  )
}

export { NotificationCenter, NotificationCenterItem }
