"use client"

import type { INotificationPopupProps } from "./NotificationPopup.d"
import type { JSX } from "react"

import cs from "classnames"
import Cookies from "js-cookie"
import { useRouter } from "next/navigation"
import { FunctionComponent, useCallback, useEffect, useRef } from "react"
import { useDispatch } from "react-redux"

import { useAppSelector } from "@shared/hooks/useAppSelector"
import { formatNotificationRelativeTime } from "@shared/lib/dates"
import { API_URL } from "@shared/lib/constants"
import {
	markAllRead,
	markRead,
	NotificationItem,
} from "@shared/store/notifications"
import { Badge } from "@shared/ui"

import { getNotificationPresentation } from "./presentation"

const apiBase = API_URL || "http://localhost:8000"

function authHeaders(): HeadersInit {
	const token = Cookies.get("access_token")
	return token ? { Authorization: `Bearer ${token}` } : {}
}

import styles from "./NotificationPopup.module.scss"

export const NotificationPopup: FunctionComponent<INotificationPopupProps> = ({
	onClose,
	anchorRef,
}): JSX.Element => {
	const items = useAppSelector((state) => state.notifications.items)
	const dispatch = useDispatch()
	const router = useRouter()
	const popupRef = useRef<HTMLDivElement>(null)

	useEffect(() => {
		const handleClickOutside = (e: MouseEvent) => {
			if (
				popupRef.current &&
				!popupRef.current.contains(e.target as Node) &&
				anchorRef.current &&
				!anchorRef.current.contains(e.target as Node)
			) {
				onClose()
			}
		}
		document.addEventListener("mousedown", handleClickOutside)
		return () => document.removeEventListener("mousedown", handleClickOutside)
	}, [onClose, anchorRef])

	const handleMarkAllRead = useCallback(() => {
		dispatch(markAllRead())
		fetch(`${apiBase}/api/notifications/read-all/`, {
			method: "POST",
			headers: authHeaders(),
		}).catch(() => {})
	}, [dispatch])

	const handleItemClick = useCallback(
		(item: NotificationItem) => {
			if (item.notification_id && !item.is_read) {
				dispatch(markRead(item.notification_id))
				fetch(`${apiBase}/api/notifications/${item.notification_id}/read/`, {
					method: "POST",
					headers: authHeaders(),
				}).catch(() => {})
			}
			if (item.project_id) {
				router.push(`/projects/${item.project_id}`)
				onClose()
			}
		},
		[dispatch, router, onClose],
	)

	return (
		<div className={styles.root} ref={popupRef}>
			<div className={styles.header}>
				<span className={styles.title}>Уведомления</span>
				<button
					className={styles.readAllBtn}
					onClick={handleMarkAllRead}
					type="button"
				>
					Прочитать все
				</button>
			</div>
			<div className={styles.list}>
				{items.length === 0 ? (
					<div className={styles.empty}>Нет уведомлений</div>
				) : (
					items.map((item, idx) => {
						const presentation = getNotificationPresentation(item)

						return (
							<div
								key={item.notification_id || `${item.job_id}-${idx}`}
								className={cs(styles.item, {
									[styles.itemUnread]: !item.is_read,
								})}
								onClick={() => handleItemClick(item)}
							>
								<div className={styles.itemContent}>
									<div className={styles.itemHeader}>
										<div className={styles.itemHeadline}>
											<div className={styles.itemTitle}>
												<span className={styles.itemTitleText}>
													{presentation.title}
												</span>
											</div>
											{presentation.statusText &&
												presentation.statusVariant && (
													<Badge
														variant={presentation.statusVariant}
														className={styles.itemStatusBadge}
													>
														{presentation.statusText}
													</Badge>
												)}
										</div>
										<span className={styles.itemTime}>
											{formatNotificationRelativeTime(item.created_at)}
										</span>
									</div>
									{presentation.detailText && (
										<div className={styles.itemMessage}>
											{presentation.detailText}
										</div>
									)}
									{item.status === "RUNNING" &&
										item.progress_pct != null && (
											<div className={styles.progressBar}>
												<div
													className={styles.progressFill}
													style={{
														width: `${item.progress_pct}%`,
													}}
												/>
											</div>
										)}
								</div>
							</div>
						)
					})
				)}
			</div>
		</div>
	)
}
