import React, { useState, useRef, useEffect } from 'react';
import {
    BellIcon,
    CheckIcon,
    XMarkIcon,
    InformationCircleIcon,
    ExclamationTriangleIcon,
    ExclamationCircleIcon,
    CheckCircleIcon,
} from '@heroicons/react/24/outline';
import { useTranslation } from 'react-i18next';
import { useNavigate, useLocation } from 'react-router-dom';
import { getApiPath } from '../../config/paths';
import { fetchWithCsrf } from '../../utils/csrfService';

interface Notification {
    id: number;
    title: string;
    message: string;
    level: 'info' | 'warning' | 'error' | 'success';
    source: string;
    read_at: string | null;
    created_at: string;
    data?: {
        taskUid?: string;
        projectUid?: string;
        [key: string]: any;
    };
}

interface NotificationsDropdownProps {
    isDarkMode: boolean;
}

const NotificationsDropdown: React.FC<NotificationsDropdownProps> = ({
    isDarkMode,
}) => {
    const { t } = useTranslation();
    const navigate = useNavigate();
    const location = useLocation();
    const [isOpen, setIsOpen] = useState(false);
    const [unreadCount, setUnreadCount] = useState(0);
    const [notifications, setNotifications] = useState<Notification[]>([]);
    const [loading, setLoading] = useState(false);
    const dropdownRef = useRef<HTMLDivElement>(null);

    const fetchUnreadCount = async () => {
        try {
            const response = await fetch(
                getApiPath('notifications/unread-count'),
                {
                    credentials: 'include',
                }
            );
            if (response.ok) {
                const data = await response.json();
                setUnreadCount(data.count || 0);
            }
        } catch (error) {
            console.error('Error fetching unread count:', error);
        }
    };

    const fetchNotifications = async () => {
        setLoading(true);
        try {
            const response = await fetch(
                getApiPath('notifications?limit=20&includeRead=true'),
                {
                    credentials: 'include',
                }
            );
            if (response.ok) {
                const data = await response.json();
                setNotifications(data.notifications || []);
            }
        } catch (error) {
            console.error('Error fetching notifications:', error);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchUnreadCount();
        const interval = setInterval(fetchUnreadCount, 30000);
        return () => clearInterval(interval);
    }, []);

    useEffect(() => {
        if (isOpen) {
            fetchNotifications();
        }
    }, [isOpen]);

    const handleToggle = () => {
        setIsOpen(!isOpen);
    };

    const handleMarkAsRead = async (id: number) => {
        try {
            const response = await fetchWithCsrf(
                getApiPath(`notifications/${id}/read`),
                {
                    method: 'POST',
                    credentials: 'include',
                }
            );

            if (response.ok) {
                const data = await response.json();
                const updatedNotification: Notification | undefined =
                    data.notification;
                if (updatedNotification) {
                    setNotifications((prev) =>
                        prev.map((n) =>
                            n.id === id
                                ? {
                                      ...n,
                                      read_at: updatedNotification.read_at,
                                  }
                                : n
                        )
                    );
                }
                fetchUnreadCount();
            }
        } catch (error) {
            console.error('Error marking notification as read:', error);
        }
    };

    const handleMarkAllAsRead = async () => {
        try {
            const response = await fetchWithCsrf(
                getApiPath('notifications/mark-all-read'),
                {
                    method: 'POST',
                    credentials: 'include',
                }
            );

            if (response.ok) {
                const now = new Date().toISOString();
                setNotifications((prev) =>
                    prev.map((n) => ({ ...n, read_at: now }))
                );
                setUnreadCount(0);
            }
        } catch (error) {
            console.error('Error marking all notifications as read:', error);
        }
    };

    const handleDelete = async (id: number) => {
        try {
            const response = await fetchWithCsrf(getApiPath(`notifications/${id}`), {
                method: 'DELETE',
                credentials: 'include',
            });
            if (response.ok) {
                setNotifications((prev) => prev.filter((n) => n.id !== id));
                fetchUnreadCount();
            }
        } catch (error) {
            console.error('Error deleting notification:', error);
        }
    };

    const getLevelIcon = (level: string) => {
        switch (level) {
            case 'success':
                return (
                    <CheckCircleIcon className="h-5 w-5 text-green-500 flex-shrink-0" />
                );
            case 'warning':
                return (
                    <ExclamationTriangleIcon className="h-5 w-5 text-yellow-500 flex-shrink-0" />
                );
            case 'error':
                return (
                    <ExclamationCircleIcon className="h-5 w-5 text-red-500 flex-shrink-0" />
                );
            default:
                return (
                    <InformationCircleIcon className="h-5 w-5 text-blue-500 flex-shrink-0" />
                );
        }
    };

    const formatTimestamp = (timestamp: string) => {
        const date = new Date(timestamp);
        const now = new Date();
        const diff = now.getTime() - date.getTime();
        const minutes = Math.floor(diff / 60000);
        const hours = Math.floor(diff / 3600000);
        const days = Math.floor(diff / 86400000);

        if (minutes < 1) return t('notifications.justNow', 'Just now');
        if (minutes < 60)
            return t('notifications.minutesAgo', '{{count}} min ago', {
                count: minutes,
            });
        if (hours < 24)
            return t('notifications.hoursAgo', '{{count}}h ago', {
                count: hours,
            });
        if (days < 7)
            return t('notifications.daysAgo', '{{count}}d ago', {
                count: days,
            });
        return date.toLocaleDateString();
    };

    const handleNotificationClick = (notification: Notification) => {
        if (notification.data?.taskUid) {
            setIsOpen(false);
            navigate(`/task/${notification.data.taskUid}`, { state: { from: location.pathname + location.search } });
        } else if (notification.data?.projectUid) {
            setIsOpen(false);
            navigate(`/project/${notification.data.projectUid}`);
        }
    };

    useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
            if (
                dropdownRef.current &&
                !dropdownRef.current.contains(event.target as Node)
            ) {
                setIsOpen(false);
            }
        };

        if (isOpen) {
            document.addEventListener('mousedown', handleClickOutside);
        }

        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, [isOpen]);

    return (
        <div className="relative" ref={dropdownRef}>
            <button
                onClick={handleToggle}
                className="relative flex items-center focus:outline-none"
                aria-label="Notifications"
            >
                <BellIcon className="h-6 w-6 text-gray-700 dark:text-gray-300" />
                {unreadCount > 0 && (
                    <span className="absolute -top-0.5 -right-0.5 bg-red-500 text-white text-[10px] rounded-full h-4 min-w-4 px-1 flex items-center justify-center font-medium">
                        {unreadCount > 99 ? '99+' : unreadCount}
                    </span>
                )}
            </button>

            {isOpen && (
                <div
                    className={`absolute right-0 mt-2 w-96 rounded-lg shadow-lg z-50 ${
                        isDarkMode ? 'bg-gray-800' : 'bg-white'
                    } border ${
                        isDarkMode ? 'border-gray-700' : 'border-gray-200'
                    }`}
                >
                    <div
                        className={`p-4 border-b flex items-center justify-between ${
                            isDarkMode ? 'border-gray-700' : 'border-gray-200'
                        }`}
                    >
                        <h3 className="text-lg font-semibold">
                            {t('notifications.title', 'Notifications')}
                        </h3>
                        {unreadCount > 0 && (
                            <button
                                onClick={handleMarkAllAsRead}
                                className="text-xs text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300"
                            >
                                {t(
                                    'notifications.markAllRead',
                                    'Mark all as read'
                                )}
                            </button>
                        )}
                    </div>
                    <div className="max-h-96 overflow-y-auto">
                        {loading ? (
                            <div className="p-4 text-center">
                                <p className="text-sm text-gray-500 dark:text-gray-400">
                                    {t('notifications.loading', 'Loading...')}
                                </p>
                            </div>
                        ) : notifications.length === 0 ? (
                            <div className="p-4 text-center">
                                <p className="text-sm text-gray-500 dark:text-gray-400">
                                    {t(
                                        'notifications.noNotifications',
                                        'No notifications yet'
                                    )}
                                </p>
                            </div>
                        ) : (
                            notifications.map((notification) => (
                                <div
                                    key={notification.id}
                                    className={`p-4 border-b ${
                                        isDarkMode
                                            ? 'border-gray-700'
                                            : 'border-gray-200'
                                    } ${
                                        !notification.read_at
                                            ? isDarkMode
                                                ? 'bg-gray-700/50'
                                                : 'bg-blue-50'
                                            : ''
                                    } hover:${
                                        isDarkMode
                                            ? 'bg-gray-700'
                                            : 'bg-gray-50'
                                    } transition-colors`}
                                >
                                    <div className="flex items-start space-x-3">
                                        {getLevelIcon(notification.level)}
                                        <div className="flex-1 min-w-0">
                                            <div className="flex items-start justify-between">
                                                <div
                                                    className={`flex-1 ${
                                                        notification.data
                                                            ?.taskUid ||
                                                        notification.data
                                                            ?.projectUid
                                                            ? 'cursor-pointer'
                                                            : ''
                                                    }`}
                                                    onClick={() =>
                                                        handleNotificationClick(
                                                            notification
                                                        )
                                                    }
                                                >
                                                    <p className="text-sm font-medium">
                                                        {notification.title}
                                                    </p>
                                                    <p className="text-xs text-gray-600 dark:text-gray-400 mt-1">
                                                        {notification.message}
                                                    </p>
                                                    <p className="text-xs text-gray-500 dark:text-gray-500 mt-1">
                                                        {formatTimestamp(
                                                            notification.created_at
                                                        )}
                                                    </p>
                                                </div>
                                                <div className="flex items-center space-x-1 ml-2">
                                                    {!notification.read_at && (
                                                        <button
                                                            onClick={(e) => {
                                                                e.stopPropagation();
                                                                handleMarkAsRead(
                                                                    notification.id
                                                                );
                                                            }}
                                                            className="p-1 hover:bg-gray-200 dark:hover:bg-gray-600 rounded"
                                                            title={t(
                                                                'notifications.markAsRead',
                                                                'Mark as read'
                                                            )}
                                                        >
                                                            <CheckIcon className="h-4 w-4 text-gray-500 dark:text-gray-400" />
                                                        </button>
                                                    )}
                                                    <button
                                                        onClick={(e) => {
                                                            e.stopPropagation();
                                                            handleDelete(
                                                                notification.id
                                                            );
                                                        }}
                                                        className="p-1 hover:bg-gray-200 dark:hover:bg-gray-600 rounded"
                                                        title={t(
                                                            'notifications.delete',
                                                            'Delete'
                                                        )}
                                                    >
                                                        <XMarkIcon className="h-4 w-4 text-gray-500 dark:text-gray-400" />
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            ))
                        )}
                    </div>
                </div>
            )}
        </div>
    );
};

export default NotificationsDropdown;
