/**
 * Notifications Feed Component
 *
 * Displays notifications from backend API with filtering,
 * error handling, bulk actions, and auto-refresh
 */

import { useState, useEffect, useCallback, useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import {
  Card,
  CardBody,
  Button,
  Spinner,
  SelectControl,
  Flex,
  FlexItem,
  FlexBlock,
  Icon,
} from '@wordpress/components';
import { close, external, update, info, check, warning, backup } from '@wordpress/icons';
import { useNotification } from '../../contexts/NotificationContext';
import './styles.css';

// Polling interval in milliseconds (60 seconds)
const POLLING_INTERVAL = 60000;

const NotificationsFeed = ({ maxItems = 10, filters = {}, onCountChange }) => {
  const [notifications, setNotifications] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [filterType, setFilterType] = useState(filters.type ?? '');
  const [filterPriority, setFilterPriority] = useState(filters.priority ?? '');
  const [dismissing, setDismissing] = useState({});
  const [dismissingAll, setDismissingAll] = useState(false);
  const [refreshing, setRefreshing] = useState(false);
  const pollingRef = useRef(null);
  const notificationListRef = useRef(null);

  const { showNotification } = useNotification();

  const loadNotifications = useCallback(async ({ isPolling = false, forceRefresh = false } = {}) => {
    if (!isPolling) {
      setLoading(true);
    } else {
      setRefreshing(true);
    }
    setError(null);

    try {
      const params = new URLSearchParams();
      if (filterType !== '') {
        params.append('type', filterType);
      }
      if (filterPriority !== '') {
        params.append('priority', filterPriority);
      }
      if (forceRefresh) {
        params.append('refresh', '1');
      }

      const path = `/prorank-seo/v1/notifications${
        params.toString() !== '' ? `?${params.toString()}` : ''
      }`;
      const response = await apiFetch({ path });

      if (Array.isArray(response?.notifications)) {
        const notificationList = response.notifications.slice(0, maxItems);
        setNotifications(notificationList);

        // Notify parent of count change for badge
        if (onCountChange) {
          onCountChange(response.count || notificationList.length);
        }
      }
    } catch (err) {
      console.error('Failed to load notifications:', err);
      setError(__('Failed to load notifications. Please try again.', 'prorank-seo'));
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, [filterType, filterPriority, maxItems, onCountChange]);

  // Initial load and filter changes
  useEffect(() => {
    loadNotifications();
  }, [loadNotifications]);

  // Set up polling
  useEffect(() => {
    pollingRef.current = setInterval(() => {
      loadNotifications({ isPolling: true });
    }, POLLING_INTERVAL);

    return () => {
      if (pollingRef.current) {
        clearInterval(pollingRef.current);
      }
    };
  }, [loadNotifications]);

  const handleDismiss = async (notificationId, notificationIndex) => {
    setDismissing((prev) => ({ ...prev, [notificationId]: true }));

    try {
      await apiFetch({
        path: `/prorank-seo/v1/notifications/${notificationId}/dismiss`,
        method: 'POST',
      });

      // Remove from list
      setNotifications((prev) => {
        const newList = prev.filter((n) => n.id !== notificationId);
        if (onCountChange) {
          onCountChange(newList.length);
        }
        return newList;
      });

      showNotification(__('Notification dismissed', 'prorank-seo'), 'success');

      // Focus management - move focus to next notification or list
      if (notificationListRef.current) {
        const buttons = notificationListRef.current.querySelectorAll('.prorank-dismiss-btn');
        const nextButton = buttons[notificationIndex] || buttons[notificationIndex - 1];
        if (nextButton) {
          nextButton.focus();
        }
      }
    } catch (err) {
      console.error('Failed to dismiss notification:', err);
      showNotification(__('Failed to dismiss notification. Please try again.', 'prorank-seo'), 'error');
      setDismissing((prev) => ({ ...prev, [notificationId]: false }));
    }
  };

  const handleDismissAll = async () => {
    const dismissibleNotifications = notifications.filter((n) => n.dismissible === true);

    if (dismissibleNotifications.length === 0) {
      return;
    }

    setDismissingAll(true);

    try {
      // Dismiss all notifications one by one
      // In future, backend could have a bulk dismiss endpoint
      const dismissPromises = dismissibleNotifications.map((n) =>
        apiFetch({
          path: `/prorank-seo/v1/notifications/${n.id}/dismiss`,
          method: 'POST',
        }).catch(() => null) // Ignore individual failures
      );

      await Promise.all(dismissPromises);

      // Remove all dismissible from list
      setNotifications((prev) => {
        const newList = prev.filter((n) => n.dismissible !== true);
        if (onCountChange) {
          onCountChange(newList.length);
        }
        return newList;
      });

      showNotification(
        sprintf(__('%d notifications dismissed', 'prorank-seo'), dismissibleNotifications.length),
        'success'
      );
    } catch (err) {
      console.error('Failed to dismiss all notifications:', err);
      showNotification(__('Failed to dismiss some notifications', 'prorank-seo'), 'error');
    } finally {
      setDismissingAll(false);
    }
  };

  const handleRetry = () => {
    loadNotifications();
  };

  const handleRefresh = () => {
    loadNotifications({ forceRefresh: true });
  };

  const getIcon = (type) => {
    switch (type) {
      case 'error':
        return warning;
      case 'warning':
        return warning;
      case 'success':
        return check;
      case 'update':
        return update;
      case 'info':
      case 'tip':
      case 'promo':
      default:
        return info;
    }
  };

  const getTypeClass = (type) => {
    return `prorank-notification--${type}`;
  };

  const getPriorityBadge = (priority) => {
    const badges = {
      critical: { label: __('Critical', 'prorank-seo'), className: 'prorank-priority--critical' },
      high: { label: __('High', 'prorank-seo'), className: 'prorank-priority--high' },
      medium: { label: __('Medium', 'prorank-seo'), className: 'prorank-priority--medium' },
      low: { label: __('Low', 'prorank-seo'), className: 'prorank-priority--low' },
    };

    const badge = badges[priority] ?? badges.low;
    return <span className={`prorank-priority-badge ${badge.className}`}>{badge.label}</span>;
  };

  const formatTimestamp = (timestamp) => {
    if (timestamp === null || timestamp === undefined) {
      return '';
    }

    // Handle both Unix timestamps (seconds) and ISO strings
    const date = typeof timestamp === 'number'
      ? new Date(timestamp * 1000)
      : new Date(timestamp);
    const now = new Date();
    const diffMs = now - date;

    const diffMins = Math.floor(diffMs / 60000);
    if (diffMins < 1) {
      return __('Just now', 'prorank-seo');
    }
    if (diffMins < 60) {
      return sprintf(__('%d minutes ago', 'prorank-seo'), diffMins);
    }

    const diffHours = Math.floor(diffMs / 3600000);
    if (diffHours < 24) {
      return sprintf(__('%d hours ago', 'prorank-seo'), diffHours);
    }

    const diffDays = Math.floor(diffMs / 86400000);
    if (diffDays < 7) {
      return sprintf(__('%d days ago', 'prorank-seo'), diffDays);
    }

    return date.toLocaleDateString();
  };

  const dismissibleCount = notifications.filter((n) => n.dismissible === true).length;

  // Loading state with skeleton
  if (loading === true) {
    return (
      <div className="prorank-notifications-feed">
        <div className="prorank-notifications-loading">
          <Spinner />
          <p>{__('Loading notifications...', 'prorank-seo')}</p>
        </div>
        {/* Skeleton placeholders */}
        <div className="prorank-notifications-skeleton">
          {[1, 2, 3].map((i) => (
            <div key={i} className="prorank-notification-skeleton">
              <div className="prorank-skeleton-icon" />
              <div className="prorank-skeleton-content">
                <div className="prorank-skeleton-title" />
                <div className="prorank-skeleton-message" />
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // Error state with retry button
  if (error) {
    return (
      <div className="prorank-notifications-feed">
        <Card>
          <CardBody>
            <div className="prorank-notifications-error">
              <Icon icon={warning} size={32} />
              <p>{error}</p>
              <Button
                variant="primary"
                onClick={handleRetry}
                icon={backup}
              >
                {__('Try Again', 'prorank-seo')}
              </Button>
            </div>
          </CardBody>
        </Card>
      </div>
    );
  }

  return (
    <div
      className="prorank-notifications-feed"
      role="region"
      aria-label={__('Notifications', 'prorank-seo')}
    >
      {/* Filters and Actions */}
      <div className="prorank-notifications-filters">
        <Flex gap={3} align="center" justify="space-between" wrap>
          <FlexItem>
            <Flex gap={2} align="center">
              <SelectControl
                label={__('Type', 'prorank-seo')}
                hideLabelFromVision
                value={filterType}
                options={[
                  { label: __('All Types', 'prorank-seo'), value: '' },
                  { label: __('Error', 'prorank-seo'), value: 'error' },
                  { label: __('Warning', 'prorank-seo'), value: 'warning' },
                  { label: __('Success', 'prorank-seo'), value: 'success' },
                  { label: __('Update', 'prorank-seo'), value: 'update' },
                  { label: __('Info', 'prorank-seo'), value: 'info' },
                  { label: __('Tip', 'prorank-seo'), value: 'tip' },
                  { label: __('Promo', 'prorank-seo'), value: 'promo' },
                ]}
                onChange={setFilterType}
                __nextHasNoMarginBottom
                __next40pxDefaultSize
              />
              <SelectControl
                label={__('Priority', 'prorank-seo')}
                hideLabelFromVision
                value={filterPriority}
                options={[
                  { label: __('All Priorities', 'prorank-seo'), value: '' },
                  { label: __('Critical', 'prorank-seo'), value: 'critical' },
                  { label: __('High', 'prorank-seo'), value: 'high' },
                  { label: __('Medium', 'prorank-seo'), value: 'medium' },
                  { label: __('Low', 'prorank-seo'), value: 'low' },
                ]}
                onChange={setFilterPriority}
                __nextHasNoMarginBottom
                __next40pxDefaultSize
              />
            </Flex>
          </FlexItem>
          <FlexItem>
            <Flex gap={2} align="center">
              <Button
                variant="tertiary"
                size="compact"
                onClick={handleRefresh}
                icon={backup}
                disabled={refreshing}
              >
                {refreshing ? __('Refreshing...', 'prorank-seo') : __('Refresh', 'prorank-seo')}
              </Button>
              {dismissibleCount > 0 && (
                <Button
                  variant="secondary"
                  size="compact"
                  onClick={handleDismissAll}
                  disabled={dismissingAll}
                  isBusy={dismissingAll}
                >
                  {dismissingAll
                    ? __('Dismissing...', 'prorank-seo')
                    : sprintf(__('Dismiss All (%d)', 'prorank-seo'), dismissibleCount)}
                </Button>
              )}
            </Flex>
          </FlexItem>
        </Flex>
      </div>

      {/* Notifications List */}
      <div
        aria-live="polite"
        aria-atomic="false"
        aria-relevant="additions removals"
      >
        {Array.isArray(notifications) && notifications.length === 0 ? (
          <Card>
            <CardBody>
              <div className="prorank-notifications-empty">
                <div className="prorank-empty-icon">
                  <Icon icon={check} size={48} />
                </div>
                <h3>{__('All caught up!', 'prorank-seo')}</h3>
                <p>{__('No notifications to display. Check back later for updates and tips.', 'prorank-seo')}</p>
                <Button
                  variant="secondary"
                  onClick={handleRefresh}
                  icon={backup}
                  className="prorank-empty-refresh"
                >
                  {__('Check for new notifications', 'prorank-seo')}
                </Button>
              </div>
            </CardBody>
          </Card>
        ) : (
          <div
            className="prorank-notifications-list"
            ref={notificationListRef}
            role="list"
            aria-label={sprintf(__('%d notifications', 'prorank-seo'), notifications.length)}
          >
            {Array.isArray(notifications) &&
              notifications.map((notification, index) => (
                <div
                  key={notification.id}
                  className={`prorank-notification ${getTypeClass(notification.type)}`}
                  role="listitem"
                  aria-label={sprintf(
                    __('%s notification: %s', 'prorank-seo'),
                    notification.type,
                    notification.title
                  )}
                >
                  <div className="prorank-notification-icon" aria-hidden="true">
                    <Icon icon={getIcon(notification.type)} size={24} />
                  </div>

                  <div className="prorank-notification-content">
                    <div className="prorank-notification-header">
                      <Flex justify="space-between" align="start">
                        <FlexBlock>
                          <h4>{notification.title}</h4>
                        </FlexBlock>
                        <FlexItem>
                          <Flex gap={2} align="center">
                            {getPriorityBadge(notification.priority)}
                            {notification.dismissible === true && (
                              <Button
                                className="prorank-dismiss-btn"
                                icon={close}
                                label={__('Dismiss notification', 'prorank-seo')}
                                onClick={() => handleDismiss(notification.id, index)}
                                isSmall
                                isBusy={dismissing[notification.id] === true}
                                disabled={dismissing[notification.id] === true}
                                aria-label={sprintf(
                                  __('Dismiss: %s', 'prorank-seo'),
                                  notification.title
                                )}
                              />
                            )}
                          </Flex>
                        </FlexItem>
                      </Flex>
                    </div>

                    <span className="prorank-notification-message">{notification.message}</span>

                    <div className="prorank-notification-footer">
                      <Flex justify="space-between" align="center">
                        <FlexItem>
                          {notification.action && notification.action.url && (
                            <Button
                              variant={notification.type === 'error' ? 'primary' : 'secondary'}
                              href={notification.action.url}
                              target={
                                notification.action.url.startsWith('http') ? '_blank' : undefined
                              }
                              rel={
                                notification.action.url.startsWith('http')
                                  ? 'noopener noreferrer'
                                  : undefined
                              }
                              icon={notification.action.url.startsWith('http') ? external : null}
                              iconPosition="right"
                              isSmall
                            >
                              {notification.action.label || __('View', 'prorank-seo')}
                            </Button>
                          )}
                        </FlexItem>
                        <FlexItem>
                          {notification.timestamp && (
                            <span className="prorank-notification-time">
                              {formatTimestamp(notification.timestamp)}
                            </span>
                          )}
                        </FlexItem>
                      </Flex>
                    </div>
                  </div>
                </div>
              ))}
          </div>
        )}
      </div>
    </div>
  );
};

export default NotificationsFeed;
