import React, { useState, useEffect, useContext, useCallback } from 'react'
import {
  Typography,
  Space,
  Button,
  Empty,
  Spin,
  message,
  Popconfirm,
  Flex,
  Badge,
  Dropdown
} from 'antd'
import {
  BellOutlined,
  DeleteOutlined,
  CheckOutlined,
  ReloadOutlined
} from '@ant-design/icons'
import axios from 'axios'
import PropTypes from 'prop-types'
import { AuthContext } from '../context/AuthContext'
import config from '../../../config'
import Notification from './Notification'

const { Text } = Typography

const NotificationCenter = ({ visible }) => {
  const [notifications, setNotifications] = useState([])
  const [loading, setLoading] = useState(false)
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
  const [messageApi, contextHolder] = message.useMessage()

  const { authenticated } = useContext(AuthContext)

  const fetchNotifications = useCallback(async () => {
    if (!authenticated) return

    setLoading(true)
    try {
      const response = await axios.get(`${config.backendUrl}/notifications`, {
        headers: {
          Accept: 'application/json'
        },
        withCredentials: true
      })
      setNotifications(response.data)
    } catch (error) {
      console.error('Error fetching notifications:', error)
      messageApi.error('Failed to fetch notifications')
    } finally {
      setLoading(false)
    }
  }, [authenticated, messageApi])

  const markAsRead = useCallback(
    async (notificationId) => {
      try {
        await axios.put(
          `${config.backendUrl}/notifications/${notificationId}/read`,
          {},
          {
            headers: {
              Accept: 'application/json'
            },
            withCredentials: true
          }
        )

        // Update local state
        setNotifications((prev) =>
          prev.map((notification) => {
            if (notification._id === notificationId) {
              return { ...notification, read: true }
            }
            return notification
          })
        )

        messageApi.success('Notification marked as read')
      } catch (error) {
        console.error('Error marking notification as read:', error)
        messageApi.error('Failed to mark notification as read')
      }
    },
    [messageApi]
  )

  const markAllAsRead = useCallback(async () => {
    try {
      await axios.put(
        `${config.backendUrl}/notifications/read-all`,
        {},
        {
          headers: {
            Accept: 'application/json'
          },
          withCredentials: true
        }
      )

      // Update local state
      setNotifications((prev) =>
        prev.map((notification) => ({ ...notification, read: true }))
      )

      messageApi.success('All notifications marked as read')
    } catch (error) {
      console.error('Error marking all notifications as read:', error)
      messageApi.error('Failed to mark all notifications as read')
    }
  }, [messageApi])

  const deleteAllNotifications = useCallback(async () => {
    try {
      await axios.delete(`${config.backendUrl}/notifications`, {
        headers: {
          Accept: 'application/json'
        },
        withCredentials: true
      })

      setNotifications([])
      messageApi.success('All notifications deleted')
    } catch (error) {
      console.error('Error deleting all notifications:', error)
      messageApi.error('Failed to delete all notifications')
    } finally {
      setShowDeleteConfirm(false)
    }
  }, [messageApi])

  useEffect(() => {
    if (visible && authenticated) {
      fetchNotifications()
    }
  }, [visible, authenticated, fetchNotifications])

  const unreadCount = notifications.filter(
    (notification) => !notification.read
  ).length

  const actionItems = {
    items: [
      {
        label: 'Mark All Read',
        key: 'markAllRead',
        icon: <CheckOutlined />,
        disabled: unreadCount === 0
      },
      {
        label: 'Reload Notifications',
        key: 'reloadNotifications',
        icon: <ReloadOutlined />
      },
      { type: 'divider' },
      {
        label: 'Delete All',
        key: 'deleteAll',
        icon: <DeleteOutlined />,
        danger: true,
        disabled: notifications.length === 0
      }
    ],
    onClick: ({ key }) => {
      if (key === 'markAllRead') {
        markAllAsRead()
      } else if (key === 'reloadNotifications') {
        fetchNotifications()
      } else if (key === 'deleteAll') {
        setShowDeleteConfirm(true)
      }
    }
  }

  if (!visible) {
    return null
  }

  return (
    <>
      {contextHolder}
      <Flex justify='space-between' align='center'>
        <Space size='middle'>
          <Dropdown menu={actionItems}>
            <Button>Actions</Button>
          </Dropdown>
          <Badge count={unreadCount} size='small'>
            <BellOutlined style={{ fontSize: '18px' }} />
          </Badge>
        </Space>
        <Space>
          <Button icon={<DeleteOutlined />} danger />
        </Space>
      </Flex>

      <div style={{ maxHeight: 500, overflow: 'auto' }}>
        {loading ? (
          <div style={{ padding: '40px', textAlign: 'center' }}>
            <Spin size='large' />
            <div style={{ marginTop: 16 }}>
              <Text type='secondary'>Loading notifications...</Text>
            </div>
          </div>
        ) : notifications.length === 0 ? (
          <Empty
            image={Empty.PRESENTED_IMAGE_SIMPLE}
            description='No notifications'
            style={{ padding: '40px 20px' }}
          />
        ) : (
          <Flex vertical gap='small' style={{ padding: '16px' }}>
            {notifications.map((notification) => (
              <Notification
                key={notification._id}
                notification={notification}
                onMarkAsRead={markAsRead}
              />
            ))}
          </Flex>
        )}
      </div>

      <Popconfirm
        title='Delete all notifications?'
        description='This action cannot be undone.'
        open={showDeleteConfirm}
        onConfirm={deleteAllNotifications}
        onCancel={() => setShowDeleteConfirm(false)}
        okText='Yes'
        cancelText='No'
      />
    </>
  )
}

NotificationCenter.propTypes = {
  visible: PropTypes.bool.isRequired
}

export default NotificationCenter
