import { useState, useEffect, useCallback } from 'react';
import { Timeline, Typography, Select, Button, Spin, Empty, Tag, Space } from 'antd';
import {
  MailOutlined,
  MessageOutlined,
  ScheduleOutlined,
  EnvironmentOutlined,
  DollarOutlined,
  ShoppingOutlined,
  PhoneOutlined,
  PlaySquareOutlined,
  EditOutlined,
  MergeCellsOutlined,
  ClockCircleOutlined,
  LoginOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { api } from '@/lib/api';
import type { ContactActivityItem, ContactActivityResponse, ContactActivityType } from '@/types/api';

dayjs.extend(relativeTime);

const ACTIVITY_TYPE_CONFIG: Record<
  ContactActivityType,
  { icon: React.ReactNode; color: string; label: string }
> = {
  EMAIL_SENT: { icon: <MailOutlined />, color: '#1890ff', label: 'Email Sent' },
  RESPONSE_SUBMITTED: { icon: <MessageOutlined />, color: '#52c41a', label: 'Response Submitted' },
  SHIFT_SIGNUP: { icon: <ScheduleOutlined />, color: '#13c2c2', label: 'Shift Signup' },
  CANVASS_VISIT: { icon: <EnvironmentOutlined />, color: '#722ed1', label: 'Canvass Visit' },
  DONATION: { icon: <DollarOutlined />, color: '#fadb14', label: 'Donation' },
  PURCHASE: { icon: <ShoppingOutlined />, color: '#fa8c16', label: 'Purchase' },
  SMS_SENT: { icon: <PhoneOutlined />, color: '#2f54eb', label: 'SMS Sent' },
  SMS_RECEIVED: { icon: <PhoneOutlined />, color: '#eb2f96', label: 'SMS Received' },
  VIDEO_VIEW: { icon: <PlaySquareOutlined />, color: '#a0d911', label: 'Video View' },
  NOTE_ADDED: { icon: <EditOutlined />, color: '#8c8c8c', label: 'Note Added' },
  CONTACT_MERGED: { icon: <MergeCellsOutlined />, color: '#faad14', label: 'Contact Merged' },
  PROFILE_SELF_EDIT: { icon: <EditOutlined />, color: '#597ef7', label: 'Profile Self-Edit' },
  PROFILE_PHOTO_UPDATED: { icon: <EditOutlined />, color: '#36cfc9', label: 'Photo Updated' },
  USER_LOGIN: { icon: <LoginOutlined />, color: '#595959', label: 'User Login' },
};

const activityTypeOptions = Object.entries(ACTIVITY_TYPE_CONFIG).map(([value, cfg]) => ({
  value,
  label: cfg.label,
}));

interface PersonActivityTimelineProps {
  personId: string;
  filterType?: string;
}

export default function PersonActivityTimeline({ personId, filterType: initialFilter }: PersonActivityTimelineProps) {
  const [activities, setActivities] = useState<ContactActivityItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [filterType, setFilterType] = useState<string | undefined>(initialFilter);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);

  const parsePersonId = (id: string): { type: string; sourceId: string } => {
    const colonIdx = id.indexOf(':');
    if (colonIdx === -1) return { type: 'contact', sourceId: id };
    return { type: id.substring(0, colonIdx), sourceId: id.substring(colonIdx + 1) };
  };

  const fetchActivities = useCallback(
    async (pageNum: number, append = false) => {
      if (append) setLoadingMore(true);
      else setLoading(true);

      try {
        const { type, sourceId } = parsePersonId(personId);
        const { data } = await api.get<ContactActivityResponse>(
          `/people/${type}/${sourceId}/activity`,
          {
            params: {
              page: pageNum,
              limit: 20,
              type: filterType,
            },
          },
        );

        if (append) {
          setActivities((prev) => [...prev, ...data.activities]);
        } else {
          setActivities(data.activities);
        }
        setPage(pageNum);
        setHasMore(pageNum < data.pagination.totalPages);
      } catch {
        if (!append) setActivities([]);
      } finally {
        setLoading(false);
        setLoadingMore(false);
      }
    },
    [personId, filterType],
  );

  useEffect(() => {
    fetchActivities(1);
  }, [personId, filterType]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleLoadMore = () => {
    fetchActivities(page + 1, true);
  };

  if (loading) {
    return (
      <div style={{ textAlign: 'center', padding: 32 }}>
        <Spin />
      </div>
    );
  }

  return (
    <div>
      <div style={{ marginBottom: 16 }}>
        <Select
          placeholder="Filter by type"
          options={activityTypeOptions}
          value={filterType}
          onChange={setFilterType}
          allowClear
          style={{ width: 200 }}
        />
      </div>

      {activities.length === 0 ? (
        <Empty description="No activity found" image={Empty.PRESENTED_IMAGE_SIMPLE} />
      ) : (
        <>
          <Timeline
            items={activities.map((activity) => {
              const config = ACTIVITY_TYPE_CONFIG[activity.type] || {
                icon: <ClockCircleOutlined />,
                color: '#8c8c8c',
                label: activity.type,
              };
              return {
                dot: <span style={{ color: config.color }}>{config.icon}</span>,
                children: (
                  <div>
                    <Space size={6} style={{ marginBottom: 2 }}>
                      <Typography.Text strong style={{ fontSize: 13 }}>
                        {activity.title}
                      </Typography.Text>
                      <Tag style={{ fontSize: 10, margin: 0 }}>{config.label}</Tag>
                    </Space>
                    {activity.description && (
                      <Typography.Paragraph
                        type="secondary"
                        style={{ fontSize: 12, margin: 0 }}
                        ellipsis={{ rows: 2 }}
                      >
                        {activity.description}
                      </Typography.Paragraph>
                    )}
                    <Typography.Text type="secondary" style={{ fontSize: 11 }}>
                      {dayjs(activity.occurredAt).fromNow()} ({dayjs(activity.occurredAt).format('MMM D, YYYY h:mm A')})
                    </Typography.Text>
                  </div>
                ),
              };
            })}
          />

          {hasMore && (
            <div style={{ textAlign: 'center', marginTop: 12 }}>
              <Button onClick={handleLoadMore} loading={loadingMore} size="small">
                Load More
              </Button>
            </div>
          )}
        </>
      )}
    </div>
  );
}
