import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Layout, Typography, Space, Button, Tabs, Table, Select, Input, DatePicker, Modal, Form, InputNumber, message } from 'antd';
import { ArrowLeftOutlined, PlusOutlined, CheckOutlined, CloseOutlined, DeleteOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';
import { useAppContext } from '../store/AppContext';
import { ROUTES } from '../router/routes.constant';

interface NotificationsResponse {
  submenu_id: number;
  message: string | null;
  user_id: number | null;
  notes: string | null;
  metadata: string | null;
  id: string;
  version: number;
  deleted_at: string | null;
  created_at: string;
  updated_at: string;
}

interface AuditlogResponse {
  submenu_id: number;
  actor_id: string;
  action: string;
  entity_name: string;
  entity_id: string;
  notes: string | null;
  metadata: string | null;
  id: string;
  version: number;
  deleted_at: string | null;
  created_at: string;
  updated_at: string;
}

interface PaginationState {
  limit: number;
  offset: number;
}

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

  const [notificationsList, setNotificationsList] = useState<NotificationsResponse[]>([]);
  const [auditLogsList, setAuditLogsList] = useState<AuditlogResponse[]>([]);
  const [activeTab, setActiveTab] = useState<string>('notifications');
  const [filterType, setFilterType] = useState<string>('');
  const [filterReadStatus, setFilterReadStatus] = useState<string>('');
  const [auditSearchText, setAuditSearchText] = useState<string>('');
  const [auditDateRange, setAuditDateRange] = useState<[string, string] | []>([]);
  const [createModalVisible, setCreateModalVisible] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [selectedNotificationId, setSelectedNotificationId] = useState<string>('');
  const [notificationsPagination, setNotificationsPagination] = useState<PaginationState>({
    limit: 20,
    offset: 0,
  });
  const [auditLogsPagination, setAuditLogsPagination] = useState<PaginationState>({
    limit: 20,
    offset: 0,
  });

  const [form] = Form.useForm();

  const fetchNotifications = useCallback(async () => {
    setLoading(true);
    try {
      const queryParams: Record<string, string | number> = {
        limit: notificationsPagination.limit,
        offset: notificationsPagination.offset,
      };
      if (filterType) {
        queryParams.user_id = filterType;
      }
      const result = await request<NotificationsResponse[]>({
        method: 'GET',
        path: '/notifications/',
        query: queryParams,
      });
      setNotificationsList(result.data);
    } catch (error) {
      messageApi.error('Failed to fetch notifications');
    } finally {
      setLoading(false);
    }
  }, [notificationsPagination, filterType, messageApi]);

  const fetchAuditLogs = useCallback(async () => {
    setLoading(true);
    try {
      const queryParams: Record<string, string | number> = {
        limit: auditLogsPagination.limit,
        offset: auditLogsPagination.offset,
      };
      if (auditSearchText) {
        queryParams.action = auditSearchText;
        queryParams.entity_name = auditSearchText;
      }
      const result = await request<AuditlogResponse[]>({
        method: 'GET',
        path: '/notifications/audit-logs',
        query: queryParams,
      });
      setAuditLogsList(result.data);
    } catch (error) {
      messageApi.error('Failed to fetch audit logs');
    } finally {
      setLoading(false);
    }
  }, [auditLogsPagination, auditSearchText, messageApi]);

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

  useEffect(() => {
    if (activeTab === 'audit_logs') {
      fetchAuditLogs();
    }
  }, [activeTab, fetchAuditLogs]);

  const openCreateModal = useCallback(() => {
    setCreateModalVisible(true);
  }, []);

  const closeCreateModal = useCallback(() => {
    setCreateModalVisible(false);
    form.resetFields();
  }, [form]);

  const handleCreateNotification = useCallback(async () => {
    try {
      const values = await form.validateFields();
      setLoading(true);
      await request<NotificationsResponse>({
        method: 'POST',
        path: '/notifications/',
        body: {
          submenu_id: 1,
          message: values.message,
          user_id: values.user_id,
          notes: values.notes,
          metadata: values.metadata,
        },
      });
      messageApi.success('Notification created successfully');
      setCreateModalVisible(false);
      form.resetFields();
      fetchNotifications();
    } catch (error) {
      messageApi.error('Failed to create notification');
    } finally {
      setLoading(false);
    }
  }, [form, messageApi, fetchNotifications]);

  const handleMarkAsRead = useCallback(async (id: string) => {
    setSelectedNotificationId(id);
    setLoading(true);
    try {
      await request<NotificationsResponse>({
        method: 'PUT',
        path: '/notifications/{notification_id}',
        pathParams: { notification_id: id },
        body: { metadata: 'read' },
      });
      messageApi.success('Notification marked as read');
      fetchNotifications();
    } catch (error) {
      messageApi.error('Failed to update notification');
    } finally {
      setLoading(false);
    }
  }, [messageApi, fetchNotifications]);

  const handleMarkAsUnread = useCallback(async (id: string) => {
    setSelectedNotificationId(id);
    setLoading(true);
    try {
      await request<NotificationsResponse>({
        method: 'PUT',
        path: '/notifications/{notification_id}',
        pathParams: { notification_id: id },
        body: { metadata: 'unread' },
      });
      messageApi.success('Notification marked as unread');
      fetchNotifications();
    } catch (error) {
      messageApi.error('Failed to update notification');
    } finally {
      setLoading(false);
    }
  }, [messageApi, fetchNotifications]);

  const handleDeleteNotification = useCallback((id: string) => {
    Modal.confirm({
      title: 'Delete Notification',
      content: 'Are you sure you want to delete this notification?',
      okText: 'Delete',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        setSelectedNotificationId(id);
        setLoading(true);
        try {
          await request({
            method: 'DELETE',
            path: '/notifications/{notification_id}',
            pathParams: { notification_id: id },
          });
          messageApi.success('Notification deleted successfully');
          fetchNotifications();
        } catch (error) {
          messageApi.error('Failed to delete notification');
        } finally {
          setLoading(false);
        }
      },
    });
  }, [messageApi, fetchNotifications]);

  const navigateToDashboard = useCallback(() => {
    navigate(ROUTES.DASHBOARD || '/');
  }, [navigate]);

  const handleTabChange = useCallback((key: string) => {
    setActiveTab(key);
  }, []);

  const handleFilterTypeChange = useCallback((value: string) => {
    setFilterType(value);
  }, []);

  const handleFilterReadStatusChange = useCallback((value: string) => {
    setFilterReadStatus(value);
  }, []);

  const handleAuditSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setAuditSearchText(e.target.value);
  }, []);

  const notificationsColumns = useMemo(() => [
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      width: 80,
    },
    {
      title: 'Message',
      dataIndex: 'message',
      key: 'message',
    },
    {
      title: 'Type',
      dataIndex: 'metadata',
      key: 'metadata',
      width: 100,
    },
    {
      title: 'Read Status',
      dataIndex: 'notes',
      key: 'notes',
      width: 120,
    },
    {
      title: 'User ID',
      dataIndex: 'user_id',
      key: 'user_id',
      width: 100,
    },
    {
      title: 'Created Date',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 180,
      render: (text: string) => new Date(text).toLocaleString(),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 250,
      render: (_: unknown, record: NotificationsResponse) => (
        <Space size="small">
          <Button
            size="small"
            icon={<CheckOutlined />}
            onClick={() => handleMarkAsRead(record.id)}
          >
            Read
          </Button>
          <Button
            size="small"
            icon={<CloseOutlined />}
            onClick={() => handleMarkAsUnread(record.id)}
          >
            Unread
          </Button>
          <Button
            size="small"
            danger
            icon={<DeleteOutlined />}
            onClick={() => handleDeleteNotification(record.id)}
          >
            Delete
          </Button>
        </Space>
      ),
    },
  ], [handleMarkAsRead, handleMarkAsUnread, handleDeleteNotification]);

  const auditLogsColumns = useMemo(() => [
    {
      title: 'Log ID',
      dataIndex: 'id',
      key: 'id',
      width: 80,
    },
    {
      title: 'Action',
      dataIndex: 'action',
      key: 'action',
      width: 120,
    },
    {
      title: 'Module',
      dataIndex: 'entity_name',
      key: 'entity_name',
      width: 150,
    },
    {
      title: 'User',
      dataIndex: 'actor_id',
      key: 'actor_id',
      width: 120,
    },
    {
      title: 'Timestamp',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 180,
      render: (text: string) => new Date(text).toLocaleString(),
    },
    {
      title: 'Details',
      dataIndex: 'notes',
      key: 'notes',
    },
  ], []);

  const filteredNotifications = useMemo(() => {
    return notificationsList.filter((notification) => {
      if (filterReadStatus && notification.metadata !== filterReadStatus) {
        return false;
      }
      return true;
    });
  }, [notificationsList, filterReadStatus]);

  const tabItems = useMemo(() => [
    {
      key: 'notifications',
      label: 'Notifications',
      children: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
            <Select
              placeholder="All Types"
              allowClear
              style={{ width: 200 }}
              value={filterType || undefined}
              onChange={handleFilterTypeChange}
              options={[
                { label: 'System', value: 'system' },
                { label: 'User', value: 'user' },
                { label: 'Alert', value: 'alert' },
              ]}
            />
            <Select
              placeholder="All Status"
              allowClear
              style={{ width: 200 }}
              value={filterReadStatus || undefined}
              onChange={handleFilterReadStatusChange}
              options={[
                { label: 'Read', value: 'read' },
                { label: 'Unread', value: 'unread' },
              ]}
            />
          </div>
          <Table
            columns={notificationsColumns}
            dataSource={filteredNotifications}
            rowKey="id"
            pagination={{ pageSize: 20 }}
            loading={loading}
          />
        </div>
      ),
    },
    {
      key: 'audit_logs',
      label: 'Audit Logs',
      children: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
            <Input.Search
              placeholder="Search by action or module..."
              allowClear
              style={{ width: 300 }}
              value={auditSearchText}
              onChange={handleAuditSearchChange}
              onSearch={fetchAuditLogs}
            />
            <DatePicker.RangePicker
              style={{ width: 300 }}
              onChange={(dates) => {
                if (dates && dates[0] && dates[1]) {
                  setAuditDateRange([dates[0].toISOString(), dates[1].toISOString()]);
                } else {
                  setAuditDateRange([]);
                }
              }}
            />
          </div>
          <Table
            columns={auditLogsColumns}
            dataSource={auditLogsList}
            rowKey="id"
            pagination={{ pageSize: 20 }}
            loading={loading}
          />
        </div>
      ),
    },
  ], [
    filterType,
    filterReadStatus,
    auditSearchText,
    notificationsColumns,
    auditLogsColumns,
    filteredNotifications,
    auditLogsList,
    loading,
    handleFilterTypeChange,
    handleFilterReadStatusChange,
    handleAuditSearchChange,
    fetchAuditLogs,
  ]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    padding: '24px',
    background: '#f5f5f5',
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px' }}>
        <Typography.Title level={2} style={{ margin: 0 }}>
          Notifications
        </Typography.Title>
        <Space>
          <Button type="default" icon={<ArrowLeftOutlined />} onClick={navigateToDashboard}>
            Back to Dashboard
          </Button>
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreateModal}>
            Create Notification
          </Button>
        </Space>
      </div>
      <Tabs activeKey={activeTab} items={tabItems} onChange={handleTabChange} />
      <Modal
        title="Create Notification"
        open={createModalVisible}
        onOk={handleCreateNotification}
        onCancel={closeCreateModal}
        okText="Create"
        cancelText="Cancel"
        width={600}
        confirmLoading={loading}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="message"
            label="Message"
            rules={[{ required: true, message: 'Message is required' }]}
          >
            <Input.TextArea placeholder="Enter notification message" rows={4} />
          </Form.Item>
          <Form.Item name="user_id" label="Target User ID">
            <InputNumber placeholder="Enter target user ID" style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="notes" label="Type">
            <Select
              placeholder="Select notification type"
              options={[
                { label: 'System', value: 'system' },
                { label: 'User', value: 'user' },
                { label: 'Alert', value: 'alert' },
              ]}
            />
          </Form.Item>
          <Form.Item name="metadata" label="Additional Metadata">
            <Input placeholder="Optional metadata" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}