import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Table, Button, Select, DatePicker, Modal, Form, Input, Switch, Typography, message, Tag, Space, Tooltip } from 'antd';
import { ArrowLeftOutlined, SendOutlined, ReloadOutlined, DeleteOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
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;
}

interface MemberResponse {
  id: string;
  user_id: string;
  membership_number: string;
  membership_date: string;
  membership_expiry: string | null;
  borrowing_limit: number;
  account_standing: string;
  created_at: string;
  updated_at: string;
}

interface PaginationState {
  current: number;
  pageSize: number;
  total: number;
}

export default function NotificationsMgmtPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const [form] = Form.useForm();

  const [notifications, setNotifications] = useState<NotificationResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [filterType, setFilterType] = useState<string>('');
  const [filterStatus, setFilterStatus] = useState<string>('');
  const [filterDateRange, setFilterDateRange] = useState<[any, any] | null>(null);
  const [pagination, setPagination] = useState<PaginationState>({
    current: 1,
    pageSize: 20,
    total: 0,
  });
  const [sendModalVisible, setSendModalVisible] = useState<boolean>(false);
  const [sendingNotification, setSendingNotification] = useState<boolean>(false);
  const [retryingId, setRetryingId] = useState<string | null>(null);
  const [members, setMembers] = useState<MemberResponse[]>([]);

  const totalNotifications = useMemo(() => pagination.total, [pagination.total]);

  const fetchNotifications = useCallback(async () => {
    setLoading(true);
    try {
      const queryParams: Record<string, string | number> = {
        limit: pagination.pageSize,
        offset: (pagination.current - 1) * pagination.pageSize,
      };
      if (filterType) {
        queryParams.notification_type = filterType;
      }
      if (filterStatus) {
        queryParams.status = filterStatus;
      }

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

      setNotifications(result.data);
      setPagination(prev => ({ ...prev, total: result.data.length }));
    } catch (error) {
      messageApi.error('Failed to load notifications');
    } finally {
      setLoading(false);
    }
  }, [pagination.current, pagination.pageSize, filterType, filterStatus, messageApi]);

  const fetchMembers = useCallback(async () => {
    try {
      const result = await request<MemberResponse[]>({
        method: 'GET',
        path: '/users/members',
        query: { limit: 100, offset: 0 },
      });
      setMembers(result.data);
    } catch (error) {
      messageApi.error('Failed to load members');
    }
  }, [messageApi]);

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

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

  const handleFilterTypeChange = (value: string) => {
    setFilterType(value || '');
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handleFilterStatusChange = (value: string) => {
    setFilterStatus(value || '');
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handleDateRangeChange = (dates: [any, any] | null) => {
    setFilterDateRange(dates);
    setPagination(prev => ({ ...prev, current: 1 }));
  };

  const handlePageChange = (page: number, pageSize: number) => {
    setPagination(prev => ({ ...prev, current: page, pageSize }));
  };

  const openSendModal = () => {
    setSendModalVisible(true);
  };

  const closeSendModal = () => {
    setSendModalVisible(false);
    form.resetFields();
  };

  const handleSendNotification = async () => {
    try {
      const formValues = await form.validateFields();
      setSendingNotification(true);

      const body = {
        member_id: formValues.member_id,
        notification_type: formValues.notification_type || 'GENERAL',
        title: formValues.title,
        message: formValues.message,
        status: 'UNREAD' as NotificationStatus,
        sent_date: new Date().toISOString(),
      };

      await request<NotificationResponse>({
        method: 'POST',
        path: '/engagement/notifications',
        body,
      });

      messageApi.success('Notification sent successfully!');
      setSendModalVisible(false);
      setSendingNotification(false);
      form.resetFields();
      fetchNotifications();
    } catch (error) {
      messageApi.error('Failed to send notification. Please try again.');
      setSendingNotification(false);
    }
  };

  const handleRetryNotification = (id: string) => {
    Modal.confirm({
      title: 'Retry Notification',
      content: 'Are you sure you want to retry sending this notification?',
      onOk: async () => {
        try {
          setRetryingId(id);
          const body = {
            status: 'UNREAD' as NotificationStatus,
            sent_date: new Date().toISOString(),
          };

          await request<NotificationResponse>({
            method: 'PATCH',
            path: '/engagement/notifications/{notification_id}',
            pathParams: { notification_id: id },
            body,
          });

          messageApi.success('Notification retry initiated');
          setRetryingId(null);
          fetchNotifications();
        } catch (error) {
          messageApi.error('Failed to retry notification');
          setRetryingId(null);
        }
      },
    });
  };

  const handleDeleteNotification = (id: string) => {
    Modal.confirm({
      title: 'Delete Notification',
      content: 'Are you sure you want to delete this notification?',
      onOk: async () => {
        try {
          await request({
            method: 'DELETE',
            path: '/engagement/notifications/{notification_id}',
            pathParams: { notification_id: id },
          });

          messageApi.success('Notification deleted');
          fetchNotifications();
        } catch (error) {
          messageApi.error('Failed to delete notification');
        }
      },
    });
  };

  const navigateToDashboard = () => {
    navigate(ROUTES.ADMIN_DASHBOARD || '/admin/dashboard');
  };

  const getStatusTag = (status: NotificationStatus) => {
    const colorMap: Record<NotificationStatus, string> = {
      UNREAD: 'blue',
      READ: 'green',
      ARCHIVED: 'default',
    };
    return <Tag color={colorMap[status]}>{status}</Tag>;
  };

  const getTypeTag = (type: NotificationType) => {
    const colorMap: Record<NotificationType, string> = {
      DUE_DATE: 'orange',
      OVERDUE: 'red',
      RESERVATION_READY: 'green',
      FINE_ASSESSED: 'volcano',
      GENERAL: 'blue',
      ANNOUNCEMENT: 'purple',
    };
    return <Tag color={colorMap[type]}>{type.replace(/_/g, ' ')}</Tag>;
  };

  const columns = useMemo(() => [
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      width: 80,
      ellipsis: true,
      render: (text: string) => (
        <Tooltip title={text}>
          <span>{text.substring(0, 8)}...</span>
        </Tooltip>
      ),
    },
    {
      title: 'Recipient',
      dataIndex: 'member_id',
      key: 'member_id',
      width: 140,
      ellipsis: true,
      render: (text: string) => (
        <Tooltip title={text}>
          <span>{text.substring(0, 12)}...</span>
        </Tooltip>
      ),
    },
    {
      title: 'Type',
      dataIndex: 'notification_type',
      key: 'notification_type',
      width: 150,
      render: (type: NotificationType) => getTypeTag(type),
    },
    {
      title: 'Subject',
      dataIndex: 'title',
      key: 'title',
      width: 200,
      ellipsis: true,
    },
    {
      title: 'Sent Date',
      dataIndex: 'sent_date',
      key: 'sent_date',
      width: 160,
      render: (date: string) => new Date(date).toLocaleString(),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      render: (status: NotificationStatus) => getStatusTag(status),
    },
    {
      title: 'Read Status',
      dataIndex: 'read_date',
      key: 'read_date',
      width: 120,
      render: (date: string | null) => (date ? new Date(date).toLocaleDateString() : '-'),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 120,
      fixed: 'right' as const,
      render: (_: unknown, record: NotificationResponse) => (
        <Space size="small">
          <Tooltip title="Retry">
            <Button
              type="text"
              size="small"
              icon={<ReloadOutlined />}
              loading={retryingId === record.id}
              onClick={() => handleRetryNotification(record.id)}
            />
          </Tooltip>
          <Tooltip title="Delete">
            <Button
              type="text"
              size="small"
              danger
              icon={<DeleteOutlined />}
              onClick={() => handleDeleteNotification(record.id)}
            />
          </Tooltip>
        </Space>
      ),
    },
  ], [retryingId]);

  const memberOptions = useMemo(() => {
    return members.map(member => ({
      label: `${member.membership_number} (${member.id.substring(0, 8)}...)`,
      value: member.id,
    }));
  }, [members]);

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

  const headerStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '24px',
  };

  const headerLeftStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '12px',
  };

  const filtersContentStyle: CSSProperties = {
    display: 'flex',
    gap: '16px',
    flexWrap: 'wrap',
    alignItems: 'center',
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={headerStyle}>
        <div style={headerLeftStyle}>
          <Button type="text" icon={<ArrowLeftOutlined />} onClick={navigateToDashboard}>
            Back
          </Button>
          <Typography.Title level={3} style={{ margin: 0 }}>
            Notifications Management
          </Typography.Title>
        </div>
        <Button type="primary" icon={<SendOutlined />} onClick={openSendModal}>
          Send Custom Notification
        </Button>
      </div>

      <Card size="small" style={{ marginBottom: '16px' }}>
        <div style={filtersContentStyle}>
          <Select
            placeholder="All Types"
            allowClear
            value={filterType || undefined}
            onChange={handleFilterTypeChange}
            style={{ width: '180px' }}
            options={[
              { label: 'Due Date', value: 'DUE_DATE' },
              { label: 'Overdue', 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 Statuses"
            allowClear
            value={filterStatus || undefined}
            onChange={handleFilterStatusChange}
            style={{ width: '160px' }}
            options={[
              { label: 'Unread', value: 'UNREAD' },
              { label: 'Read', value: 'READ' },
              { label: 'Archived', value: 'ARCHIVED' },
            ]}
          />
          <DatePicker.RangePicker
            placeholder={['Start Date', 'End Date']}
            value={filterDateRange}
            onChange={handleDateRangeChange}
            style={{ width: '280px' }}
          />
        </div>
      </Card>

      <Card>
        <Table
          rowKey="id"
          dataSource={notifications}
          columns={columns}
          loading={loading}
          pagination={{
            current: pagination.current,
            pageSize: pagination.pageSize,
            total: pagination.total,
            showSizeChanger: true,
            showTotal: (total) => `Total ${total} notifications`,
            onChange: handlePageChange,
          }}
          scroll={{ x: 1200 }}
        />
      </Card>

      <Modal
        title="Send Custom Notification"
        open={sendModalVisible}
        onOk={handleSendNotification}
        onCancel={closeSendModal}
        width={600}
        okText="Send Now"
        cancelText="Cancel"
        confirmLoading={sendingNotification}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="member_id"
            label="Recipient"
            rules={[{ required: true, message: 'Please select a recipient' }]}
          >
            <Select
              placeholder="Search and select member or 'All Members'"
              showSearch
              filterOption={(input, option) =>
                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
              }
              options={memberOptions}
              style={{ width: '100%' }}
            />
          </Form.Item>

          <Form.Item name="notification_type" label="Notification Type" initialValue="GENERAL">
            <Select
              style={{ width: '100%' }}
              options={[
                { label: 'General', value: 'GENERAL' },
                { label: 'Announcement', value: 'ANNOUNCEMENT' },
                { label: 'Due Date', value: 'DUE_DATE' },
                { label: 'Overdue', value: 'OVERDUE' },
                { label: 'Reservation Ready', value: 'RESERVATION_READY' },
                { label: 'Fine Assessed', value: 'FINE_ASSESSED' },
              ]}
            />
          </Form.Item>

          <Form.Item
            name="title"
            label="Subject"
            rules={[{ required: true, message: 'Subject is required' }]}
          >
            <Input placeholder="Enter notification subject" />
          </Form.Item>

          <Form.Item
            name="message"
            label="Message"
            rules={[{ required: true, message: 'Message body is required' }]}
          >
            <Input.TextArea
              placeholder="Enter notification message body"
              rows={5}
              maxLength={1000}
              showCount
            />
          </Form.Item>

          <Form.Item name="schedule" label="Schedule for later" valuePropName="checked">
            <Switch />
          </Form.Item>

          <Form.Item noStyle shouldUpdate={(prevValues, currentValues) => prevValues.schedule !== currentValues.schedule}>
            {({ getFieldValue }) =>
              getFieldValue('schedule') ? (
                <Form.Item name="scheduled_date" label="Scheduled Date">
                  <DatePicker showTime placeholder="Select date and time" style={{ width: '100%' }} />
                </Form.Item>
              ) : null
            }
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}