import { useState, useMemo, useEffect, useCallback } from 'react';
import { Card, Button, Select, List, Badge, Empty, Typography, Avatar, Modal, message } from 'antd';
import { ArrowLeftOutlined, CheckOutlined, ClockCircleOutlined, ExclamationCircleOutlined, BookOutlined, DollarOutlined, BellOutlined, SoundOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { useAppContext } from '../store/AppContext';
import { ROUTES } from '../router/routes.constant';

type NotificationType = 'DUE_DATE' | 'OVERDUE' | 'RESERVATION_READY' | 'FINE_ASSESSED' | 'GENERAL' | 'ANNOUNCEMENT';
type NotificationStatus = 'UNREAD' | 'READ' | 'ARCHIVED';

interface NotificationResponse {
  id: string;
  member_id: string;
  notification_type: NotificationType;
  title: string;
  message: string;
  status: NotificationStatus;
  sent_date: string;
  read_date: string | null;
  created_at: string;
  updated_at: string;
}

export default function MemberNotificationsPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();

  const [notifications, setNotifications] = useState<NotificationResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [filterType, setFilterType] = useState<string>('');
  const [filterStatus, setFilterStatus] = useState<string>('');
  const [expandedNotificationId, setExpandedNotificationId] = useState<string>('');
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [totalCount, setTotalCount] = useState<number>(0);
  const [pageSize] = useState<number>(20);

  const unreadCount = useMemo(() => {
    return notifications.filter(n => n.status === 'UNREAD').length;
  }, [notifications]);

  const hasUnread = useMemo(() => {
    return notifications.some(n => n.status === 'UNREAD');
  }, [notifications]);

  const fetchNotifications = useCallback(async () => {
    setLoading(true);
    try {
      const query: Record<string, string | number> = {
        limit: pageSize,
        offset: (currentPage - 1) * pageSize
      };

      if (currentUser?.memberId) {
        query.member_id = currentUser.memberId;
      }

      if (filterType) {
        query.notification_type = filterType;
      }

      if (filterStatus) {
        query.status = filterStatus;
      }

      const result = await request<NotificationResponse[]>({
        method: 'GET',
        path: '/engagement/notifications',
        query
      });

      setNotifications(result.data);
      setTotalCount(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load notifications');
    } finally {
      setLoading(false);
    }
  }, [currentPage, pageSize, filterType, filterStatus, currentUser, messageApi]);

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

  const handleFilterTypeChange = (value: string) => {
    setFilterType(value || '');
    setCurrentPage(1);
  };

  const handleFilterStatusChange = (value: string) => {
    setFilterStatus(value || '');
    setCurrentPage(1);
  };

  const handlePageChange = (page: number) => {
    setCurrentPage(page);
  };

  const handleExpandNotification = async (notificationId: string) => {
    const newExpandedId = expandedNotificationId === notificationId ? '' : notificationId;
    setExpandedNotificationId(newExpandedId);

    if (newExpandedId) {
      const notification = notifications.find(n => n.id === notificationId);
      if (notification && notification.status === 'UNREAD') {
        try {
          await request<NotificationResponse>({
            method: 'POST',
            path: '/engagement/notifications/{notification_id}/mark-read',
            pathParams: { notification_id: notificationId }
          });

          setNotifications(prev =>
            prev.map(n =>
              n.id === notificationId
                ? { ...n, status: 'READ' as NotificationStatus, read_date: new Date().toISOString() }
                : n
            )
          );
        } catch (error) {
          messageApi.error('Failed to mark notification as read');
        }
      }
    }
  };

  const handleMarkAllAsRead = () => {
    Modal.confirm({
      title: 'Mark All as Read',
      content: 'Are you sure you want to mark all notifications as read?',
      onOk: async () => {
        try {
          const unreadNotifications = notifications.filter(n => n.status === 'UNREAD');

          for (const notification of unreadNotifications) {
            await request<NotificationResponse>({
              method: 'POST',
              path: '/engagement/notifications/{notification_id}/mark-read',
              pathParams: { notification_id: notification.id }
            });
          }

          setNotifications(prev =>
            prev.map(n => ({
              ...n,
              status: 'READ' as NotificationStatus,
              read_date: n.read_date || new Date().toISOString()
            }))
          );

          messageApi.success('All notifications marked as read');
        } catch (error) {
          messageApi.error('Failed to mark all notifications as read');
        }
      }
    });
  };

  const handleNavigateBack = () => {
    navigate(ROUTES.MEMBER_DASHBOARD);
  };

  const getNotificationIcon = (type: NotificationType) => {
    const iconMap: Record<NotificationType, React.ReactNode> = {
      DUE_DATE: <ClockCircleOutlined />,
      OVERDUE: <ExclamationCircleOutlined />,
      RESERVATION_READY: <BookOutlined />,
      FINE_ASSESSED: <DollarOutlined />,
      GENERAL: <BellOutlined />,
      ANNOUNCEMENT: <SoundOutlined />
    };
    return iconMap[type];
  };

  const getNotificationColor = (type: NotificationType): string => {
    const colorMap: Record<NotificationType, string> = {
      DUE_DATE: '#faad14',
      OVERDUE: '#ff4d4f',
      RESERVATION_READY: '#52c41a',
      FINE_ASSESSED: '#ff7a45',
      GENERAL: '#1677ff',
      ANNOUNCEMENT: '#722ed1'
    };
    return colorMap[type];
  };

  const formatDate = (dateString: string): string => {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now.getTime() - date.getTime();
    const diffMins = Math.floor(diffMs / 60000);
    const diffHours = Math.floor(diffMs / 3600000);
    const diffDays = Math.floor(diffMs / 86400000);

    if (diffMins < 60) {
      return `${diffMins} minute${diffMins !== 1 ? 's' : ''} ago`;
    } else if (diffHours < 24) {
      return `${diffHours} hour${diffHours !== 1 ? 's' : ''} ago`;
    } else if (diffDays < 7) {
      return `${diffDays} day${diffDays !== 1 ? 's' : ''} ago`;
    } else {
      return date.toLocaleDateString();
    }
  };

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', padding: '24px', backgroundColor: '#f5f5f5' }}>
      {contextHolder}
      
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
          <Button type="text" icon={<ArrowLeftOutlined />} onClick={handleNavigateBack}>
            Back to Dashboard
          </Button>
          <Typography.Title level={2} style={{ margin: '0' }}>
            My Notifications
          </Typography.Title>
          {unreadCount > 0 && (
            <Badge count={unreadCount} showZero={false} color="#1677ff" style={{ marginLeft: '8px' }} />
          )}
        </div>
        <Button
          type="primary"
          icon={<CheckOutlined />}
          disabled={!hasUnread}
          onClick={handleMarkAllAsRead}
        >
          Mark All as Read
        </Button>
      </div>

      <Card size="small" style={{ marginBottom: '16px' }}>
        <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap', alignItems: 'center' }}>
          <Select
            placeholder="All Types"
            allowClear
            style={{ width: '200px' }}
            value={filterType || undefined}
            onChange={handleFilterTypeChange}
            options={[
              { label: 'Due Date Reminder', value: 'DUE_DATE' },
              { label: 'Overdue Alert', value: 'OVERDUE' },
              { label: 'Reservation Ready', value: 'RESERVATION_READY' },
              { label: 'Fine Assessed', value: 'FINE_ASSESSED' },
              { label: 'General', value: 'GENERAL' },
              { label: 'Announcement', value: 'ANNOUNCEMENT' }
            ]}
          />
          <Select
            placeholder="All"
            allowClear
            style={{ width: '160px' }}
            value={filterStatus || undefined}
            onChange={handleFilterStatusChange}
            options={[
              { label: 'Unread', value: 'UNREAD' },
              { label: 'Read', value: 'READ' },
              { label: 'Archived', value: 'ARCHIVED' }
            ]}
          />
        </div>
      </Card>

      <Card>
        {notifications.length === 0 && !loading ? (
          <Empty description="No notifications found" style={{ padding: '48px 0' }} />
        ) : (
          <List
            loading={loading}
            dataSource={notifications}
            pagination={{
              current: currentPage,
              pageSize: pageSize,
              total: totalCount,
              onChange: handlePageChange
            }}
            renderItem={(item) => (
              <List.Item
                style={{
                  cursor: 'pointer',
                  backgroundColor: expandedNotificationId === item.id ? '#f0f5ff' : 'transparent',
                  padding: '16px',
                  borderRadius: '4px'
                }}
                onClick={() => handleExpandNotification(item.id)}
              >
                <List.Item.Meta
                  avatar={
                    <Avatar
                      style={{ backgroundColor: getNotificationColor(item.notification_type) }}
                      icon={getNotificationIcon(item.notification_type)}
                    />
                  }
                  title={
                    <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                      <span style={{ fontWeight: item.status === 'UNREAD' ? 'bold' : 'normal' }}>
                        {item.title}
                      </span>
                      {item.status === 'UNREAD' && (
                        <Badge status="processing" />
                      )}
                    </div>
                  }
                  description={
                    <div>
                      <div style={{ marginBottom: '4px' }}>
                        {expandedNotificationId === item.id ? item.message : item.message.substring(0, 100) + (item.message.length > 100 ? '...' : '')}
                      </div>
                      <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                        {formatDate(item.sent_date)}
                      </Typography.Text>
                    </div>
                  }
                />
              </List.Item>
            )}
          />
        )}
      </Card>
    </div>
  );
}