import { useState, useMemo, useEffect, useCallback } from 'react';
import { Typography, Badge, Button, Select, List, Card, Tag, Empty, message } from 'antd';
import {
  CheckOutlined,
  ShoppingOutlined,
  MessageOutlined,
  DollarOutlined,
  StarOutlined,
  CarOutlined,
  CreditCardOutlined,
  SettingOutlined,
  GiftOutlined,
} from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { NotificationsService } from '@/services/notifications';
import { useAppContext } from '@/store/AppStore';
import { parseError } from '@/utils/errorHandler';
import { ROUTES } from '@/constants/routes';

interface Notification {
  id: string;
  user_id: string;
  notification_type: 'ORDER' | 'MESSAGE' | 'OFFER' | 'REVIEW' | 'SHIPMENT' | 'PAYMENT' | 'SYSTEM' | 'PROMOTION';
  title: string;
  message: string;
  action_url: string | null;
  related_entity_type: string | null;
  related_entity_id: string | null;
  is_read: boolean;
  read_at: string | null;
  created_at: string;
  updated_at: string;
}

const NotificationsPagePage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();

  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [filterType, setFilterType] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);
  const [markingAllRead, setMarkingAllRead] = useState<boolean>(false);
  const [offset, setOffset] = useState<number>(0);
  const [hasMore, setHasMore] = useState<boolean>(true);

  const { data: fetchedNotifications, loading: fetchLoading, error: fetchError, execute: fetchNotifications } = useApi(
    NotificationsService.list
  );

  const filteredNotifications = useMemo(() => {
    return filterType ? notifications.filter((n) => n.notification_type === filterType) : notifications;
  }, [notifications, filterType]);

  const unreadCount = useMemo(() => {
    return notifications.filter((n) => !n.is_read).length;
  }, [notifications]);

  useEffect(() => {
    if (currentUser?.id) {
      void fetchNotifications({ user_id: currentUser.id, limit: 20, offset: 0 });
    }
  }, [currentUser, fetchNotifications]);

  useEffect(() => {
    if (fetchedNotifications) {
      if (offset === 0) {
        setNotifications(fetchedNotifications as Notification[]);
      } else {
        setNotifications((prev) => [...prev, ...(fetchedNotifications as Notification[])]);
      }
      if ((fetchedNotifications as Notification[]).length < 20) {
        setHasMore(false);
      }
      setLoading(false);
    }
  }, [fetchedNotifications, offset]);

  useEffect(() => {
    if (fetchError) {
      const { message: errorMessage } = parseError(fetchError);
      messageApi.error(errorMessage || 'Failed to load notifications');
      setLoading(false);
    }
  }, [fetchError, messageApi]);

  const handleLoadMore = async () => {
    if (!currentUser?.id) return;
    const newOffset = offset + 20;
    setOffset(newOffset);
    setLoading(true);
    try {
      await fetchNotifications({ user_id: currentUser.id, limit: 20, offset: newOffset });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to load more notifications');
      setLoading(false);
    }
  };

  const handleMarkAllAsRead = async () => {
    if (!currentUser?.id) return;
    setMarkingAllRead(true);
    try {
      await NotificationsService.createUsersMarkAllRead(currentUser.id);
      setNotifications((prev) => prev.map((n) => ({ ...n, is_read: true })));
      messageApi.success('All notifications marked as read');
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to mark notifications as read');
    } finally {
      setMarkingAllRead(false);
    }
  };

  const handleNotificationClick = async (item: Notification) => {
    if (!item.is_read) {
      try {
        await NotificationsService.createMarkRead(item.id);
        setNotifications((prev) => prev.map((n) => (n.id === item.id ? { ...n, is_read: true } : n)));
      } catch (e) {
        const { message: errorMessage } = parseError(e);
        messageApi.error(errorMessage);
      }
    }

    if (item.action_url) {
      navigate(item.action_url);
      return;
    }

    if (item.related_entity_type && item.related_entity_id) {
      switch (item.related_entity_type.toUpperCase()) {
        case 'ORDER':
          navigate(ROUTES.ORDER_DETAIL.replace(':orderId', item.related_entity_id));
          break;
        case 'LISTING':
          navigate(ROUTES.LISTING_DETAIL.replace(':listingId', item.related_entity_id));
          break;
        case 'MESSAGE':
          navigate(ROUTES.MESSAGES);
          break;
        case 'OFFER':
          navigate(ROUTES.SELLER_OFFERS);
          break;
        default:
          break;
      }
    }
  };

  const getNotificationIcon = (type: string) => {
    const iconStyle = { fontSize: 24 };
    switch (type) {
      case 'ORDER':
        return <ShoppingOutlined style={{ ...iconStyle, color: '#1677ff' }} />;
      case 'MESSAGE':
        return <MessageOutlined style={{ ...iconStyle, color: '#52c41a' }} />;
      case 'OFFER':
        return <DollarOutlined style={{ ...iconStyle, color: '#faad14' }} />;
      case 'REVIEW':
        return <StarOutlined style={{ ...iconStyle, color: '#eb2f96' }} />;
      case 'SHIPMENT':
        return <CarOutlined style={{ ...iconStyle, color: '#722ed1' }} />;
      case 'PAYMENT':
        return <CreditCardOutlined style={{ ...iconStyle, color: '#13c2c2' }} />;
      case 'SYSTEM':
        return <SettingOutlined style={{ ...iconStyle, color: '#8c8c8c' }} />;
      case 'PROMOTION':
        return <GiftOutlined style={{ ...iconStyle, color: '#E3350D' }} />;
      default:
        return <SettingOutlined style={{ ...iconStyle, color: '#8c8c8c' }} />;
    }
  };

  const formatTimestamp = (timestamp: string) => {
    const date = new Date(timestamp);
    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 < 1) return 'Just now';
    if (diffMins < 60) return `${diffMins}m ago`;
    if (diffHours < 24) return `${diffHours}h ago`;
    if (diffDays < 7) return `${diffDays}d ago`;
    return date.toLocaleDateString();
  };

  return (
    <div
      style={{
        minHeight: '100vh',
        width: '100%',
        backgroundColor: '#f5f5f5',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {contextHolder}
      <div
        style={{
          maxWidth: 800,
          width: '100%',
          margin: '0 auto',
          padding: '24px 16px',
        }}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            marginBottom: 24,
          }}
        >
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <Typography.Title level={2} style={{ margin: 0 }}>
              Notifications
            </Typography.Title>
            {unreadCount > 0 && (
              <Badge count={unreadCount} showZero={false} style={{ backgroundColor: '#E3350D', marginLeft: 8 }} />
            )}
          </div>
          <Button
            type="primary"
            icon={<CheckOutlined />}
            loading={markingAllRead}
            disabled={unreadCount === 0}
            onClick={handleMarkAllAsRead}
          >
            Mark All as Read
          </Button>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
          <Typography.Text strong style={{ whiteSpace: 'nowrap' }}>
            Filter by type:
          </Typography.Text>
          <Select
            placeholder="All Notifications"
            allowClear
            value={filterType || undefined}
            onChange={(value) => setFilterType(value || '')}
            style={{ minWidth: 200 }}
            options={[
              { label: 'Order Updates', value: 'ORDER' },
              { label: 'Messages', value: 'MESSAGE' },
              { label: 'Offers', value: 'OFFER' },
              { label: 'Reviews', value: 'REVIEW' },
              { label: 'Shipments', value: 'SHIPMENT' },
              { label: 'Payments', value: 'PAYMENT' },
              { label: 'System', value: 'SYSTEM' },
              { label: 'Promotions', value: 'PROMOTION' },
            ]}
          />
        </div>

        {filteredNotifications.length === 0 && !fetchLoading ? (
          <Empty
            description="You're all caught up! No notifications to show."
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            style={{ padding: '60px 0' }}
          />
        ) : (
          <List
            dataSource={filteredNotifications}
            loading={fetchLoading}
            locale={{ emptyText: 'No notifications yet' }}
            renderItem={(item) => (
              <Card
                hoverable
                bordered
                size="small"
                style={{ cursor: 'pointer', marginBottom: 8 }}
                onClick={() => void handleNotificationClick(item)}
              >
                <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16, width: '100%' }}>
                  <div
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      width: 48,
                      height: 48,
                      borderRadius: '50%',
                      backgroundColor: '#f0f0f0',
                      flexShrink: 0,
                    }}
                  >
                    {getNotificationIcon(item.notification_type)}
                  </div>
                  <div style={{ display: 'flex', flexDirection: 'column', flex: 1, gap: 4 }}>
                    <Typography.Text strong ellipsis style={{ fontSize: 15 }}>
                      {item.title}
                    </Typography.Text>
                    <Typography.Text type="secondary" ellipsis={{ rows: 2 }} style={{ fontSize: 13 }}>
                      {item.message}
                    </Typography.Text>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                      <Tag color="default" style={{ fontSize: 11 }}>
                        {item.notification_type}
                      </Tag>
                      <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                        {formatTimestamp(item.created_at)}
                      </Typography.Text>
                    </div>
                  </div>
                  {!item.is_read && <Badge dot status="error" style={{ marginLeft: 'auto' }} />}
                </div>
              </Card>
            )}
          />
        )}

        {hasMore && filteredNotifications.length > 0 && (
          <div style={{ display: 'flex', justifyContent: 'center', marginTop: 24 }}>
            <Button type="default" loading={loading} disabled={!hasMore} onClick={handleLoadMore}>
              Load More
            </Button>
          </div>
        )}
      </div>
    </div>
  );
};

export default NotificationsPagePage;