import { CheckCircle2, Info, LoaderCircle, TriangleAlert, XCircle, } from 'lucide-react' import { motion } from 'motion/react' import { createPortal } from 'react-dom' import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' import { NOTIFICATION_EXIT_DURATION_MS } from '@/constants' import { useNotificationStore } from '@/lib/notify' import { cn } from '@/lib/utils' const TONE_CLASS_BY_TYPE = { error: { alert: 'border-[#E37284]/38 bg-[linear-gradient(180deg,rgba(46,11,18,0.96),rgba(23,7,11,0.98))] shadow-[0_calc(var(--design-unit)*18)_calc(var(--design-unit)*44)_rgba(118,18,40,0.34)]', glow: 'from-[#FF7D93]/20 via-[#FF7D93]/8 to-transparent', icon: , iconShell: 'border-[rgba(255,154,168,0.26)] bg-[linear-gradient(180deg,rgba(124,34,46,0.42),rgba(76,19,29,0.3))] shadow-[inset_0_1px_0_rgba(255,224,228,0.16)]', line: 'bg-[#FF7D93]', title: 'text-[#FFF5F7]', }, info: { alert: 'border-[rgba(114,226,243,0.34)] bg-[linear-gradient(180deg,rgba(5,30,43,0.96),rgba(4,17,26,0.98))] shadow-[0_calc(var(--design-unit)*18)_calc(var(--design-unit)*44)_rgba(9,78,108,0.34)]', glow: 'from-[#6FEAFF]/20 via-[#6FEAFF]/8 to-transparent', icon: , iconShell: 'border-[rgba(121,228,238,0.24)] bg-[linear-gradient(180deg,rgba(17,85,98,0.38),rgba(10,53,63,0.28))] shadow-[inset_0_1px_0_rgba(227,252,255,0.14)]', line: 'bg-[#73ECFF]', title: 'text-[#F2FEFF]', }, loading: { alert: 'border-[rgba(114,226,243,0.34)] bg-[linear-gradient(180deg,rgba(5,30,43,0.96),rgba(4,17,26,0.98))] shadow-[0_calc(var(--design-unit)*18)_calc(var(--design-unit)*44)_rgba(9,78,108,0.34)]', glow: 'from-[#6FEAFF]/20 via-[#6FEAFF]/8 to-transparent', icon: ( ), iconShell: 'border-[rgba(121,228,238,0.24)] bg-[linear-gradient(180deg,rgba(17,85,98,0.38),rgba(10,53,63,0.28))] shadow-[inset_0_1px_0_rgba(227,252,255,0.14)]', line: 'bg-[#73ECFF]', title: 'text-[#F2FEFF]', }, success: { alert: 'border-[rgba(121,229,171,0.34)] bg-[linear-gradient(180deg,rgba(8,36,29,0.96),rgba(5,18,14,0.98))] shadow-[0_calc(var(--design-unit)*18)_calc(var(--design-unit)*44)_rgba(12,89,53,0.34)]', glow: 'from-[#73F0B0]/18 via-[#73F0B0]/7 to-transparent', icon: , iconShell: 'border-[rgba(127,236,177,0.24)] bg-[linear-gradient(180deg,rgba(24,98,66,0.38),rgba(15,60,40,0.28))] shadow-[inset_0_1px_0_rgba(232,255,242,0.14)]', line: 'bg-[#73F0B0]', title: 'text-[#F4FFF8]', }, warning: { alert: 'border-[rgba(239,197,103,0.36)] bg-[linear-gradient(180deg,rgba(48,31,10,0.96),rgba(25,17,7,0.98))] shadow-[0_calc(var(--design-unit)*18)_calc(var(--design-unit)*44)_rgba(109,72,12,0.34)]', glow: 'from-[#FFD66E]/20 via-[#FFD66E]/8 to-transparent', icon: , iconShell: 'border-[rgba(255,214,110,0.24)] bg-[linear-gradient(180deg,rgba(110,77,26,0.38),rgba(66,46,15,0.28))] shadow-[inset_0_1px_0_rgba(255,247,223,0.14)]', line: 'bg-[#FFD66E]', title: 'text-[#FFFAEF]', }, } as const export function AppNotificationAlert() { const activeDialog = useNotificationStore((state) => state.activeDialog) const closingDialogId = useNotificationStore((state) => state.closingDialogId) if (!activeDialog || typeof document === 'undefined') { return null } const tone = TONE_CLASS_BY_TYPE[activeDialog.type] const isClosing = closingDialogId === activeDialog.id const isMobileViewport = typeof window !== 'undefined' ? window.innerWidth <= 768 : false const motionState = isClosing ? 'closing' : 'visible' const motionVariants = { closing: { filter: 'blur(1px)', opacity: 0, scale: 0.985, y: -8, transition: { duration: NOTIFICATION_EXIT_DURATION_MS / 1000, ease: [0.22, 1, 0.36, 1], }, }, hidden: { filter: 'blur(3px)', opacity: 0, scale: 0.94, y: -18, }, visible: { filter: 'blur(0px)', opacity: 1, scale: 1, y: 0, transition: { type: 'spring', damping: 26, mass: 0.72, stiffness: 360, }, }, } as const return createPortal(