// frontend/src/components/NotificationCenter.tsx

import { useEffect, useMemo, useRef, useState } from 'react'
import {
  BellIcon,
  EnvelopeOpenIcon,
  FaceSmileIcon,
} from '@heroicons/react/20/solid'
import Button from './Button'
import Tabs, { type TabItem } from './Tabs'
import type { Notification } from './types'

type NotificationCenterProps = {
  notifications: Notification[]
  unreadCount: number
  onMarkRead: (notificationId: string) => void
  onMarkAllRead: () => void
}

type NotificationTab = 'unread' | 'all'

function formatNotificationDate(value: string) {
  try {
    return new Intl.DateTimeFormat('de-DE', {
      dateStyle: 'short',
      timeStyle: 'short',
    }).format(new Date(value))
  } catch {
    return value
  }
}

export default function NotificationCenter({
  notifications,
  unreadCount,
  onMarkRead,
  onMarkAllRead,
}: NotificationCenterProps) {
  const [open, setOpen] = useState(false)
  const [activeTab, setActiveTab] = useState<NotificationTab>('unread')
  const containerRef = useRef<HTMLDivElement | null>(null)

  const filteredNotifications = useMemo(() => {
    if (activeTab === 'unread') {
      return notifications.filter((notification) => !notification.readAt)
    }

    return notifications
  }, [activeTab, notifications])

  const notificationTabs: TabItem[] = [
    {
      name: 'Ungelesen',
      href: '#',
      current: activeTab === 'unread',
      count: unreadCount > 0 ? unreadCount : undefined,
      onClick: () => setActiveTab('unread'),
    },
    {
      name: 'Alle',
      href: '#',
      current: activeTab === 'all',
      count: notifications.length > 0 ? notifications.length : undefined,
      onClick: () => setActiveTab('all'),
    },
  ]

  useEffect(() => {
    if (!open) {
      return
    }

    function handlePointerDown(event: PointerEvent) {
      const target = event.target

      if (!(target instanceof Node)) {
        return
      }

      if (containerRef.current?.contains(target)) {
        return
      }

      setOpen(false)
    }

    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === 'Escape') {
        setOpen(false)
      }
    }

    document.addEventListener('pointerdown', handlePointerDown)
    document.addEventListener('keydown', handleKeyDown)

    return () => {
      document.removeEventListener('pointerdown', handlePointerDown)
      document.removeEventListener('keydown', handleKeyDown)
    }
  }, [open])

  function getEmptyText() {
    if (activeTab === 'unread') {
      return 'Keine ungelesenen Benachrichtigungen vorhanden.'
    }

    return 'Keine Benachrichtigungen vorhanden.'
  }

  return (
    <div ref={containerRef} className="relative">
      <button
        type="button"
        onClick={() => setOpen((value) => !value)}
        className="relative rounded-full p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/10 dark:hover:text-white"
      >
        <span className="sr-only">Benachrichtigungen öffnen</span>
        <BellIcon aria-hidden="true" className="size-6" />

        {unreadCount > 0 && (
          <span className="absolute top-1 right-1 flex size-4 items-center justify-center rounded-full bg-red-600 text-[10px] font-semibold text-white">
            {unreadCount > 9 ? '9+' : unreadCount}
          </span>
        )}
      </button>

      {open && (
        <div className="absolute right-0 z-50 mt-2 w-96 overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black/5 dark:bg-gray-900 dark:ring-white/10">
          <div className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-x-3 border-b border-gray-200 dark:border-white/10">
            <h2 className="min-w-0 truncate px-4 py-3 text-sm font-semibold text-gray-900 dark:text-white">
              Benachrichtigungen
            </h2>

            <div className="flex justify-end px-4">
              {unreadCount > 0 && (
                <Button
                  type="button"
                  variant="secondary"
                  color="indigo"
                  size="sm"
                  onClick={onMarkAllRead}
                  aria-label="Alle Benachrichtigungen als gelesen markieren"
                  title="Alle gelesen"
                  leadingIcon={
                    <EnvelopeOpenIcon aria-hidden="true" className="size-4" />
                  }
                >
                  Alle gelesen
                </Button>
              )}
            </div>
          </div>

          <Tabs
            tabs={notificationTabs}
            variant="full-width-underline"
            align="center"
            ariaLabel="Benachrichtigungsfilter"
            className="px-4 [&_a]:py-3"
          />

          <div className="h-96 overflow-y-auto">
            {filteredNotifications.length === 0 ? (
              <div className="flex h-full flex-col items-center justify-center px-6 py-10 text-center">
                <FaceSmileIcon
                  aria-hidden="true"
                  className="size-12 text-gray-300 dark:text-gray-600"
                />

                <p className="mt-3 text-sm font-medium text-gray-900 dark:text-white">
                  Alles erledigt
                </p>

                <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                  {getEmptyText()}
                </p>
              </div>
            ) : (
              filteredNotifications.map((notification) => {
                const unread = !notification.readAt

                return (
                  <button
                    key={notification.id}
                    type="button"
                    onClick={() => onMarkRead(notification.id)}
                    className="block w-full border-b border-gray-100 px-4 py-3 text-left hover:bg-gray-50 dark:border-white/10 dark:hover:bg-white/5"
                  >
                    <div className="flex gap-x-3">
                      <span
                        className={
                          unread
                            ? 'mt-1 size-2 rounded-full bg-indigo-600'
                            : 'mt-1 size-2 rounded-full bg-transparent'
                        }
                      />

                      <div className="min-w-0 flex-1">
                        <p className="text-sm font-medium text-gray-900 dark:text-white">
                          {notification.title}
                        </p>

                        <p className="mt-0.5 line-clamp-2 text-sm text-gray-600 dark:text-gray-300">
                          {notification.message}
                        </p>

                        <p className="mt-1 text-xs text-gray-400 dark:text-gray-500">
                          {formatNotificationDate(notification.createdAt)}
                        </p>
                      </div>
                    </div>
                  </button>
                )
              })
            )}
          </div>
        </div>
      )}
    </div>
  )
}