/**
 * NotificationList Component
 * Displays a list of notifications with infinite scroll
 */

import React, { useState, useEffect } from 'react';
import { NotificationItem } from './NotificationItem';

interface Notification {
  id: string;
  type: string;
  title: string;
  message: string;
  actionUrl?: string;
  read: boolean;
  createdAt: string;
}

interface NotificationListProps {
  userId?: string;
  onNotificationRead?: () => void;
  onAllRead?: () => void;
  compact?: boolean;
  showFilters?: boolean;
}

export function NotificationList({
  userId = 'demo-user',
  onNotificationRead,
  onAllRead,
  compact = false,
  showFilters = false
}: NotificationListProps) {
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [filter, setFilter] = useState<'all' | 'unread'>('all');
  const [hasMore, setHasMore] = useState(false);
  const [offset, setOffset] = useState(0);

  const limit = compact ? 5 : 20;

  useEffect(() => {
    fetchNotifications(true);
  }, [userId, filter]);

  async function fetchNotifications(reset = false) {
    try {
      setIsLoading(true);
      const currentOffset = reset ? 0 : offset;
      const unreadOnly = filter === 'unread';

      const response = await fetch(
        `/api/notifications?userId=${userId}&limit=${limit}&offset=${currentOffset}&unreadOnly=${unreadOnly}`
      );
      const data = await response.json();

      if (data.success) {
        if (reset) {
          setNotifications(data.data.notifications);
        } else {
          setNotifications(prev => [...prev, ...data.data.notifications]);
        }
        setHasMore(data.data.pagination.hasMore);
        setOffset(currentOffset + limit);
      } else {
        setError(data.error);
      }
    } catch (err: any) {
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  }

  async function handleMarkAsRead(notificationId: string) {
    try {
      const response = await fetch(`/api/notifications/${notificationId}?userId=${userId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ read: true, userId })
      });

      if (response.ok) {
        setNotifications(prev =>
          prev.map(n => (n.id === notificationId ? { ...n, read: true } : n))
        );
        onNotificationRead?.();
      }
    } catch (error) {
      console.error('Failed to mark as read:', error);
    }
  }

  async function handleMarkAllAsRead() {
    try {
      const response = await fetch('/api/notifications/read-all', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ userId })
      });

      if (response.ok) {
        setNotifications(prev => prev.map(n => ({ ...n, read: true })));
        onAllRead?.();
      }
    } catch (error) {
      console.error('Failed to mark all as read:', error);
    }
  }

  async function handleDelete(notificationId: string) {
    try {
      const response = await fetch(`/api/notifications/${notificationId}?userId=${userId}`, {
        method: 'DELETE'
      });

      if (response.ok) {
        setNotifications(prev => prev.filter(n => n.id !== notificationId));
      }
    } catch (error) {
      console.error('Failed to delete notification:', error);
    }
  }

  if (error) {
    return (
      <div className="p-4 text-center text-red-600">
        <p>Failed to load notifications</p>
        <button
          onClick={() => fetchNotifications(true)}
          className="mt-2 text-sm text-green-600 hover:text-green-700"
        >
          Try again
        </button>
      </div>
    );
  }

  return (
    <div className={compact ? '' : 'max-w-2xl mx-auto'}>
      {showFilters && (
        <div className="flex items-center justify-between mb-4 p-4 bg-white rounded-lg border">
          <div className="flex space-x-2">
            <button
              onClick={() => setFilter('all')}
              className={`px-3 py-1 rounded-full text-sm ${
                filter === 'all'
                  ? 'bg-green-100 text-green-800'
                  : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
              }`}
            >
              All
            </button>
            <button
              onClick={() => setFilter('unread')}
              className={`px-3 py-1 rounded-full text-sm ${
                filter === 'unread'
                  ? 'bg-green-100 text-green-800'
                  : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
              }`}
            >
              Unread
            </button>
          </div>
          <button
            onClick={handleMarkAllAsRead}
            className="text-sm text-green-600 hover:text-green-700"
          >
            Mark all as read
          </button>
        </div>
      )}

      {isLoading && notifications.length === 0 ? (
        <div className="p-8 text-center">
          <div className="inline-block animate-spin rounded-full h-8 w-8 border-4 border-gray-200 border-t-green-500"></div>
          <p className="mt-2 text-gray-500">Loading notifications...</p>
        </div>
      ) : notifications.length === 0 ? (
        <div className="p-8 text-center text-gray-500">
          <svg
            className="w-12 h-12 mx-auto mb-4 text-gray-300"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
            />
          </svg>
          <p>No notifications yet</p>
        </div>
      ) : (
        <div className="divide-y divide-gray-100">
          {notifications.map(notification => (
            <NotificationItem
              key={notification.id}
              notification={notification}
              onMarkAsRead={handleMarkAsRead}
              onDelete={handleDelete}
              compact={compact}
            />
          ))}
        </div>
      )}

      {hasMore && !isLoading && (
        <div className="p-4 text-center">
          <button
            onClick={() => fetchNotifications(false)}
            className="text-sm text-green-600 hover:text-green-700"
          >
            Load more
          </button>
        </div>
      )}

      {isLoading && notifications.length > 0 && (
        <div className="p-4 text-center">
          <div className="inline-block animate-spin rounded-full h-4 w-4 border-2 border-gray-200 border-t-green-500"></div>
        </div>
      )}
    </div>
  );
}
