import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import {
  Typography,
  Badge,
  Space,
  Button,
  Tabs,
  List,
  Avatar,
  Drawer,
  Form,
  Switch,
  Card,
  message,
  Grid,
} from 'antd';
import {
  CheckOutlined,
  SettingOutlined,
  UserAddOutlined,
  SwapOutlined,
  SyncOutlined,
  MessageOutlined,
  ClockCircleOutlined,
  ExclamationCircleOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
} from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { JobsService } from '@/services/jobs';
import { ROUTES } from '@/constants/routes';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';

dayjs.extend(relativeTime);

const { useBreakpoint } = Grid;

interface Job {
  id: string;
  title: string;
  job_status_id: string;
  due_date: string | null;
  assigned_to_user_id: string;
}

interface JobListResponse {
  items: Job[];
  total: number;
  limit: number;
  offset: number;
}

interface Notification {
  id: string;
  type: 'assignment' | 'reassignment' | 'status_change' | 'mention' | 'due_soon' | 'overdue' | 'completion' | 'cancellation';
  message: string;
  job_id: string;
  read: boolean;
  created_at: string;
}

interface NotificationPreferences {
  job_assignment: { in_app: boolean; email: boolean };
  job_reassignment: { in_app: boolean; email: boolean };
  status_change: { in_app: boolean; email: boolean };
  mention: { in_app: boolean; email: boolean };
  due_soon: { in_app: boolean; email: boolean };
  overdue: { in_app: boolean; email: boolean };
  job_completion: { in_app: boolean; email: boolean };
  job_cancellation: { in_app: boolean; email: boolean };
}

interface PreferenceSectionProps {
  label: string;
  type: keyof NotificationPreferences;
  preferences: NotificationPreferences;
  onToggle: (type: keyof NotificationPreferences, channel: 'in_app' | 'email', value: boolean) => void;
}

const PreferenceSection = ({ label, type, preferences, onToggle }: PreferenceSectionProps) => {
  return (
    <div
      style={{
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        padding: '12px 0',
        borderBottom: '1px solid #f0f0f0',
      }}
    >
      <Typography.Text strong>{label}</Typography.Text>
      <Space size="large">
        <Space>
          <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
            In-App
          </Typography.Text>
          <Switch
            checked={preferences[type]?.in_app ?? false}
            onChange={(value) => onToggle(type, 'in_app', value)}
            size="small"
          />
        </Space>
        <Space>
          <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
            Email
          </Typography.Text>
          <Switch
            checked={preferences[type]?.email ?? false}
            onChange={(value) => onToggle(type, 'email', value)}
            size="small"
          />
        </Space>
      </Space>
    </div>
  );
};

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

  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [filterTab, setFilterTab] = useState<'all' | 'unread' | 'read'>('all');
  const [loading, setLoading] = useState(false);
  const [preferencesDrawerVisible, setPreferencesDrawerVisible] = useState(false);
  const [preferences, setPreferences] = useState<NotificationPreferences>({
    job_assignment: { in_app: true, email: true },
    job_reassignment: { in_app: true, email: true },
    status_change: { in_app: true, email: false },
    mention: { in_app: true, email: true },
    due_soon: { in_app: true, email: true },
    overdue: { in_app: true, email: true },
    job_completion: { in_app: true, email: false },
    job_cancellation: { in_app: true, email: false },
  });

  const {
    data: jobsData,
    loading: jobsLoading,
    error: jobsError,
    execute: fetchJobs,
  } = useApi<JobListResponse>(JobsService.list);

  useEffect(() => {
    if (currentUser?.id) {
      void fetchJobs({ limit: 50, assigned_to_user_id: currentUser.id });
    }
  }, [fetchJobs, currentUser?.id]);

  useEffect(() => {
    if (jobsError) {
      const { message: errorMessage } = parseError(jobsError);
      messageApi.error(errorMessage);
    }
  }, [jobsError, messageApi]);

  useEffect(() => {
    if (jobsData?.items) {
      const generatedNotifications: Notification[] = [];
      const now = dayjs();

      (jobsData.items ?? []).forEach((job) => {
        if (job.due_date) {
          const dueDate = dayjs(job.due_date);
          const hoursUntilDue = dueDate.diff(now, 'hour');

          if (hoursUntilDue > 0 && hoursUntilDue <= 24) {
            generatedNotifications.push({
              id: `due_soon_${job.id}`,
              type: 'due_soon',
              message: `Job "${job.title}" is due within 24 hours`,
              job_id: job.id,
              read: false,
              created_at: now.toISOString(),
            });
          } else if (hoursUntilDue < 0) {
            generatedNotifications.push({
              id: `overdue_${job.id}`,
              type: 'overdue',
              message: `Job "${job.title}" is overdue`,
              job_id: job.id,
              read: false,
              created_at: now.toISOString(),
            });
          }
        }
      });

      setNotifications(generatedNotifications);
    }
  }, [jobsData]);

  const filteredNotifications = useMemo(() => {
    if (filterTab === 'all') {
      return notifications;
    } else if (filterTab === 'unread') {
      return notifications.filter((n) => !n.read);
    } else {
      return notifications.filter((n) => n.read);
    }
  }, [notifications, filterTab]);

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

  const handleMarkAllAsRead = useCallback(() => {
    setNotifications((prev) => prev.map((n) => ({ ...n, read: true })));
    messageApi.success('All notifications marked as read');
  }, [messageApi]);

  const handleOpenPreferencesDrawer = useCallback(() => {
    setPreferencesDrawerVisible(true);
  }, []);

  const handleClosePreferencesDrawer = useCallback(() => {
    setPreferencesDrawerVisible(false);
  }, []);

  const handleMarkAsReadAndNavigate = useCallback(
    (notification: Notification) => {
      setNotifications((prev) =>
        prev.map((n) => (n.id === notification.id ? { ...n, read: true } : n))
      );
      navigate(ROUTES.JOB_DETAILS.replace(':id', notification.job_id));
    },
    [navigate]
  );

  const handleTogglePreference = useCallback(
    (type: keyof NotificationPreferences, channel: 'in_app' | 'email', value: boolean) => {
      setPreferences((prev) => ({
        ...prev,
        [type]: {
          ...(prev[type] ?? {}),
          [channel]: value,
        },
      }));
    },
    []
  );

  const handleSavePreferences = useCallback(() => {
    messageApi.success('Notification preferences saved');
    setPreferencesDrawerVisible(false);
  }, [messageApi]);

  const getNotificationIcon = useCallback((type: Notification['type']) => {
    const iconMap = {
      assignment: <UserAddOutlined />,
      reassignment: <SwapOutlined />,
      status_change: <SyncOutlined />,
      mention: <MessageOutlined />,
      due_soon: <ClockCircleOutlined />,
      overdue: <ExclamationCircleOutlined />,
      completion: <CheckCircleOutlined />,
      cancellation: <CloseCircleOutlined />,
    };
    return iconMap[type];
  }, []);

  const padding = screens.xs ? 12 : 24;

  return (
    <div
      style={{
        minHeight: '100vh',
        width: '100%',
        padding: `${padding}px`,
        backgroundColor: '#f5f5f5',
      }}
    >
      {contextHolder}

      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginBottom: '24px',
          flexWrap: screens.xs ? 'wrap' : 'nowrap',
          gap: screens.xs ? '12px' : '0',
        }}
      >
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '12px',
          }}
        >
          <Typography.Title level={2} style={{ margin: 0, fontSize: screens.xs ? '18px' : '24px' }}>
            Notifications
          </Typography.Title>
          <Badge count={unreadCount} style={{ backgroundColor: '#1677ff' }} />
        </div>

        <Space>
          <Button
            type="primary"
            icon={<CheckOutlined />}
            onClick={handleMarkAllAsRead}
            disabled={unreadCount === 0}
          >
            {screens.xs ? '' : 'Mark All as Read'}
          </Button>
          <Button
            type="text"
            icon={<SettingOutlined />}
            shape="circle"
            size="large"
            onClick={handleOpenPreferencesDrawer}
          />
        </Space>
      </div>

      <Card bordered={false} style={{ borderRadius: '6px' }}>
        <Tabs
          activeKey={filterTab}
          onChange={(key) => setFilterTab(key as 'all' | 'unread' | 'read')}
          style={{ marginBottom: '16px' }}
          items={[
            { key: 'all', label: 'All' },
            { key: 'unread', label: 'Unread' },
            { key: 'read', label: 'Read' },
          ]}
        />

        <List
          dataSource={filteredNotifications}
          loading={jobsLoading}
          locale={{ emptyText: 'No notifications' }}
          renderItem={(item) => (
            <List.Item
              onClick={() => handleMarkAsReadAndNavigate(item)}
              style={{
                cursor: 'pointer',
                padding: '16px',
                borderRadius: '6px',
                marginBottom: '8px',
                backgroundColor: item.read ? '#ffffff' : '#e6f4ff',
                fontWeight: item.read ? 'normal' : 'bold',
              }}
            >
              <List.Item.Meta
                avatar={<Avatar size={40} icon={getNotificationIcon(item.type)} />}
                title={
                  <Typography.Text strong={!item.read}>{item.message}</Typography.Text>
                }
                description={
                  <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                    {dayjs(item.created_at).fromNow()}
                  </Typography.Text>
                }
              />
              {!item.read && <Badge dot status="processing" />}
            </List.Item>
          )}
        />
      </Card>

      <Drawer
        title="Notification Preferences"
        open={preferencesDrawerVisible}
        onClose={handleClosePreferencesDrawer}
        width={screens.xs ? '100%' : 480}
        placement="right"
      >
        <Form layout="vertical">
          <PreferenceSection
            label="Job Assignment"
            type="job_assignment"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Job Reassignment"
            type="job_reassignment"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Status Change"
            type="status_change"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="@Mention in Comment"
            type="mention"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Job Due Within 24 Hours"
            type="due_soon"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Overdue Job Alert"
            type="overdue"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Job Completion"
            type="job_completion"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
          <PreferenceSection
            label="Job Cancellation"
            type="job_cancellation"
            preferences={preferences}
            onToggle={handleTogglePreference}
          />
        </Form>

        <div
          style={{
            display: 'flex',
            justifyContent: 'flex-end',
            gap: '8px',
            paddingTop: '16px',
            marginTop: '16px',
            borderTop: '1px solid #f0f0f0',
          }}
        >
          <Button onClick={handleClosePreferencesDrawer}>Cancel</Button>
          <Button type="primary" onClick={handleSavePreferences}>
            Save Preferences
          </Button>
        </div>
      </Drawer>
    </div>
  );
};

export default NotificationsPage;