import React, { useEffect, useRef, useState } from 'react'

export default function NotificationDropdown({ initialUnreadCount = 0, notificationsUrl = '/api/notifications' }) {
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)
  const [items, setItems] = useState([])
  const [unreadCount, setUnreadCount] = useState(Number(initialUnreadCount || 0))
  const rootRef = useRef(null)
  const csrfToken = typeof document !== 'undefined'
    ? document.querySelector('meta[name="csrf-token"]')?.getAttribute('content')
    : null

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

    const onDocumentClick = (event) => {
      if (rootRef.current && !rootRef.current.contains(event.target)) {
        setOpen(false)
      }
    }

    document.addEventListener('mousedown', onDocumentClick)
    return () => document.removeEventListener('mousedown', onDocumentClick)
  }, [open])

  useEffect(() => {
    if (!open || items.length > 0) return

    setLoading(true)
    fetch(notificationsUrl, {
      headers: { Accept: 'application/json' },
      credentials: 'same-origin',
    })
      .then(async (response) => {
        if (!response.ok) throw new Error('Failed to load notifications')
        return response.json()
      })
      .then((payload) => {
        setItems(Array.isArray(payload?.data) ? payload.data : [])
        setUnreadCount(Number(payload?.unread_count || 0))
      })
      .catch(() => {})
      .finally(() => setLoading(false))
  }, [items.length, notificationsUrl, open])

  const markAllRead = async () => {
    try {
      await fetch('/api/notifications/read-all', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken || '',
        },
        credentials: 'same-origin',
      })
      setItems((current) => current.map((item) => ({ ...item, read: true })))
      setUnreadCount(0)
    } catch {
      // Keep current state on failure.
    }
  }

  const markSingleRead = async (id) => {
    await fetch(`/api/notifications/${id}/read`, {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'X-CSRF-TOKEN': csrfToken || '',
      },
      credentials: 'same-origin',
    })

    setItems((current) => current.map((item) => item.id === id ? { ...item, read: true } : item))
    setUnreadCount((current) => Math.max(0, current - 1))
  }

  const handleNotificationClick = async (event, item) => {
    if (!item?.id || item.read) return

    const href = event.currentTarget.getAttribute('href')
    if (!href) return

    event.preventDefault()

    try {
      await markSingleRead(item.id)
    } catch {
      // Continue to the destination even if marking as read fails.
    }

    window.location.assign(href)
  }

  return (
    <div ref={rootRef} className="relative">
      <button
        type="button"
        onClick={() => setOpen((value) => !value)}
        className="relative inline-flex h-9 w-9 lg:h-10 lg:w-10 items-center justify-center rounded-lg text-white/75 transition hover:bg-white/5 hover:text-white"
        aria-label="Notifications"
      >
        <svg className="h-[18px] w-[18px] lg:h-5 lg:w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
          <path d="M18 8a6 6 0 10-12 0c0 7-3 7-3 7h18s-3 0-3-7" />
          <path d="M13.7 21a2 2 0 01-3.4 0" />
        </svg>
        {unreadCount > 0 ? (
          <span className="absolute -bottom-1 right-0 rounded border border-sb-line bg-red-700/80 px-1 py-0 text-[10px] font-semibold text-white lg:px-1.5 lg:py-0.5 lg:text-[11px]">
            {unreadCount > 99 ? '99+' : unreadCount}
          </span>
        ) : null}
      </button>

      {open ? (
        <div className="absolute right-0 mt-2 w-[22rem] overflow-hidden rounded-2xl border border-white/[0.08] bg-panel shadow-2xl shadow-black/35">
          <div className="flex items-center justify-between border-b border-white/[0.06] px-4 py-3">
            <div>
              <h3 className="text-sm font-semibold text-white">Notifications</h3>
              <p className="text-xs text-white/35">Recent follows, likes, comments, and unlocks.</p>
            </div>
            {unreadCount > 0 ? (
              <button type="button" onClick={markAllRead} className="text-xs font-medium text-sky-300 transition hover:text-sky-200">
                Mark all read
              </button>
            ) : null}
          </div>

          <div className="max-h-[28rem] overflow-y-auto">
            {loading ? <div className="px-4 py-6 text-sm text-white/45">Loading notifications…</div> : null}
            {!loading && items.length === 0 ? <div className="px-4 py-6 text-sm text-white/45">No notifications yet.</div> : null}
            {!loading && items.map((item) => (
              <a
                key={item.id}
                href={item.url || '/dashboard/comments/received'}
                onClick={(event) => handleNotificationClick(event, item)}
                className={[
                  'flex gap-3 border-b border-white/[0.05] px-4 py-3 transition hover:bg-white/[0.04]',
                  item.read ? 'bg-transparent' : 'bg-sky-500/[0.06]',
                ].join(' ')}
              >
                <img
                  src={item.actor?.avatar_url || 'https://files.skinbase.org/default/avatar_default.webp'}
                  alt={item.actor?.name || 'Notification'}
                  className="h-10 w-10 rounded-full object-cover ring-1 ring-white/10"
                />
                <div className="min-w-0 flex-1">
                  <p className="text-sm text-white/85">{item.message}</p>
                  <p className="mt-1 text-xs uppercase tracking-[0.16em] text-white/30">{item.time_ago || ''}</p>
                </div>
              </a>
            ))}
          </div>

          <div className="border-t border-white/[0.06] bg-white/[0.02] px-4 py-3">
            <a href="/dashboard/notifications" className="inline-flex items-center gap-2 text-sm font-medium text-sky-300 transition hover:text-sky-200">
              <i className="fa-solid fa-arrow-right" aria-hidden="true" />
              View all notifications
            </a>
          </div>
        </div>
      ) : null}
    </div>
  )
}
