import { useState, useEffect, useCallback } from 'react';
import {
  Typography,
  Table,
  Input,
  Select,
  Segmented,
  Button,
  Tag,
  Space,
  Badge,
  Grid,
  Row,
  Col,
  Switch,
  theme,
  Tooltip,
  Progress,
  Pagination,
  Spin,
  Empty,
  message,
} from 'antd';
import {
  ContactsOutlined,
  AppstoreOutlined,
  ApartmentOutlined,
  SearchOutlined,
  PlusOutlined,
  StarFilled,
  StarOutlined,
  UsergroupDeleteOutlined,
  TagsOutlined,
} from '@ant-design/icons';
import { useOutletContext } from 'react-router-dom';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { api } from '@/lib/api';
import { useDebounce } from '@/hooks/useDebounce';
import type {
  AppOutletContext,
  UnifiedPerson,
  PeopleListResponse,
  PeopleStats,
  ContactSource,
  SupportLevel,
  CrmTag,
} from '@/types/api';
import {
  CONTACT_SOURCE_LABELS,
  CONTACT_SOURCE_COLORS,
  SUPPORT_LEVEL_LABELS,
  SUPPORT_LEVEL_COLORS,
} from '@/types/api';
import PersonDetailDrawer from '@/components/people/PersonDetailDrawer';
import PersonCard from '@/components/people/PersonCard';
import ConnectionGraph from '@/components/people/ConnectionGraph';
import DuplicateDetectionDrawer from '@/components/people/DuplicateDetectionDrawer';
import TagManagementDrawer from '@/components/people/TagManagementModal';

dayjs.extend(relativeTime);

type ViewMode = 'Table' | 'Cards' | 'Graph';

const sourceOptions: { value: ContactSource; label: string }[] = Object.entries(CONTACT_SOURCE_LABELS).map(
  ([value, label]) => ({ value: value as ContactSource, label }),
);

const supportLevelOptions: { value: SupportLevel; label: string }[] = Object.entries(SUPPORT_LEVEL_LABELS).map(
  ([value, label]) => ({ value: value as SupportLevel, label }),
);

export default function PeoplePage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const { token } = theme.useToken();

  const [viewMode, setViewMode] = useState<ViewMode>('Table');
  const [people, setPeople] = useState<UnifiedPerson[]>([]);
  const [_stats, setStats] = useState<PeopleStats | null>(null);
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({ page: 1, limit: 20, total: 0, totalPages: 0 });

  // Filters
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 300);
  const [sourceFilter, setSourceFilter] = useState<ContactSource | undefined>();
  const [supportFilter, setSupportFilter] = useState<SupportLevel | undefined>();
  const [tagFilter, setTagFilter] = useState<string | undefined>();
  const [managedOnly, setManagedOnly] = useState(false);

  // Drawers & modals
  const [selectedPersonId, setSelectedPersonId] = useState<string | null>(null);
  const [detailDrawerOpen, setDetailDrawerOpen] = useState(false);
  const [duplicateDrawerOpen, setDuplicateDrawerOpen] = useState(false);
  const [tagModalOpen, setTagModalOpen] = useState(false);

  // Registered tags from API
  const [registeredTags, setRegisteredTags] = useState<CrmTag[]>([]);

  // Bulk selection
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);

  useEffect(() => {
    setPageHeader({ title: 'People' });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  const fetchPeople = useCallback(
    async (page?: number) => {
      setLoading(true);
      try {
        const { data } = await api.get<PeopleListResponse>('/people', {
          params: {
            page: page ?? pagination.page,
            limit: pagination.limit,
            search: debouncedSearch || undefined,
            source: sourceFilter,
            supportLevel: supportFilter,
            tag: tagFilter,
            managedOnly: managedOnly || undefined,
          },
        });
        setPeople(data.people);
        setPagination(data.pagination);
      } catch {
        message.error('Failed to load people');
      } finally {
        setLoading(false);
      }
    },
    [pagination.page, pagination.limit, debouncedSearch, sourceFilter, supportFilter, tagFilter, managedOnly],
  );

  const fetchRegisteredTags = useCallback(async () => {
    try {
      const { data } = await api.get<{ tags: CrmTag[] }>('/people/tags');
      setRegisteredTags(data.tags);
    } catch {
      // non-critical
    }
  }, []);

  const fetchStats = useCallback(async () => {
    try {
      const { data } = await api.get<PeopleStats>('/people/stats');
      setStats(data);
    } catch {
      // Stats are non-critical
    }
  }, []);

  useEffect(() => {
    fetchPeople(1);
  }, [debouncedSearch, sourceFilter, supportFilter, tagFilter, managedOnly]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    fetchStats();
    fetchRegisteredTags();
  }, [fetchStats, fetchRegisteredTags]);

  const handleTableChange = (pag: TablePaginationConfig) => {
    fetchPeople(pag.current ?? 1);
  };

  const openDetail = (personId: string) => {
    setSelectedPersonId(personId);
    setDetailDrawerOpen(true);
  };

  const handleManage = async (person: UnifiedPerson) => {
    try {
      const [sourceType, sourceId] = person.id.split(':');
      await api.post('/people/manage', {
        sourceType,
        sourceId,
        displayName: person.displayName,
        email: person.email,
        phone: person.phone,
      });
      message.success('Contact is now managed');
      fetchPeople();
    } catch {
      message.error('Failed to manage contact');
    }
  };

  const handleBulkTag = async (tagName: string, action: 'add' | 'remove') => {
    // Extract contactIds from selected managed rows
    const contactIds = people
      .filter((p) => selectedRowKeys.includes(p.id) && p.contactId)
      .map((p) => p.contactId!);
    if (contactIds.length === 0) {
      message.warning('No managed contacts selected');
      return;
    }
    try {
      const endpoint = action === 'add' ? '/people/tags/bulk-add' : '/people/tags/bulk-remove';
      await api.post(endpoint, { tagName, contactIds });
      message.success(`${action === 'add' ? 'Added' : 'Removed'} tag "${tagName}" on ${contactIds.length} contacts`);
      setSelectedRowKeys([]);
      fetchPeople();
      fetchRegisteredTags();
    } catch {
      message.error(`Failed to ${action} tag`);
    }
  };

  const columns: ColumnsType<UnifiedPerson> = [
    {
      title: 'Name',
      dataIndex: 'displayName',
      key: 'displayName',
      render: (name: string, record: UnifiedPerson) => (
        <Button type="link" style={{ padding: 0 }} onClick={() => openDetail(record.id)}>
          {name || '--'}
        </Button>
      ),
    },
    {
      title: 'Email',
      dataIndex: 'email',
      key: 'email',
      render: (email: string | null) => email || '--',
      ellipsis: true,
    },
    {
      title: 'Phone',
      dataIndex: 'phone',
      key: 'phone',
      responsive: ['md'] as unknown as undefined,
      render: (phone: string | null) => phone || '--',
    },
    {
      title: 'Source',
      dataIndex: 'source',
      key: 'source',
      render: (source: ContactSource) => (
        <Tag color={CONTACT_SOURCE_COLORS[source]}>{CONTACT_SOURCE_LABELS[source]}</Tag>
      ),
    },
    {
      title: 'Support',
      dataIndex: 'supportLevel',
      key: 'supportLevel',
      render: (level: SupportLevel | null) =>
        level ? (
          <Badge
            color={SUPPORT_LEVEL_COLORS[level]}
            text={<span style={{ fontSize: 12 }}>{SUPPORT_LEVEL_LABELS[level]}</span>}
          />
        ) : (
          '--'
        ),
    },
    {
      title: 'Tags',
      dataIndex: 'tags',
      key: 'tags',
      responsive: ['lg'] as unknown as undefined,
      render: (tags: string[]) =>
        tags && tags.length > 0 ? (
          <Space size={2} wrap>
            {tags.slice(0, 2).map((t) => (
              <Tag key={t} style={{ fontSize: 11 }}>
                {t}
              </Tag>
            ))}
            {tags.length > 2 && (
              <Tooltip title={tags.slice(2).join(', ')}>
                <Tag style={{ fontSize: 11 }}>+{tags.length - 2}</Tag>
              </Tooltip>
            )}
          </Space>
        ) : (
          '--'
        ),
    },
    {
      title: 'Last Activity',
      dataIndex: 'lastActivity',
      key: 'lastActivity',
      responsive: ['md'] as unknown as undefined,
      render: (date: string | null) => (date ? dayjs(date).fromNow() : '--'),
    },
    {
      title: 'Score',
      dataIndex: 'engagementScore',
      key: 'engagementScore',
      responsive: ['lg'] as unknown as undefined,
      width: 80,
      render: (score: number | null) =>
        score != null ? (
          <Progress
            percent={score}
            size="small"
            strokeColor={score >= 70 ? '#52c41a' : score >= 40 ? '#faad14' : '#ff4d4f'}
            format={(p) => `${p}`}
          />
        ) : (
          '--'
        ),
    },
    {
      title: '',
      key: 'managed',
      width: 40,
      render: (_: unknown, record: UnifiedPerson) =>
        record.isManaged ? (
          <Tooltip title="Managed contact">
            <StarFilled style={{ color: '#faad14' }} />
          </Tooltip>
        ) : (
          <Tooltip title="Click to manage">
            <StarOutlined
              style={{ color: 'rgba(255,255,255,0.25)', cursor: 'pointer' }}
              onClick={() => handleManage(record)}
            />
          </Tooltip>
        ),
    },
  ];

  const activeDrawerWidth = !isMobile
    ? detailDrawerOpen ? 640 : tagModalOpen ? 640 : duplicateDrawerOpen ? 560 : 0
    : 0;

  return (
    <>
      <div
        style={{
          marginRight: isMobile ? 0 : activeDrawerWidth,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        {/* Header */}
        <Row justify="space-between" align="middle" style={{ marginBottom: 16 }} wrap>
          <Col>
            <Space>
              <Typography.Title level={4} style={{ margin: 0 }}>
                People
              </Typography.Title>
              <Badge
                count={pagination.total}
                style={{ backgroundColor: token.colorPrimary }}
                overflowCount={99999}
                showZero
              />
            </Space>
          </Col>
          <Col>
            <Space wrap>
              <Segmented
                value={viewMode}
                onChange={(val) => setViewMode(val as ViewMode)}
                options={[
                  { value: 'Table', icon: <ContactsOutlined /> },
                  { value: 'Cards', icon: <AppstoreOutlined /> },
                  { value: 'Graph', icon: <ApartmentOutlined /> },
                ]}
              />
              <Button icon={<TagsOutlined />} onClick={() => setTagModalOpen(true)}>
                {!isMobile && 'Manage Tags'}
              </Button>
              <Button icon={<UsergroupDeleteOutlined />} onClick={() => setDuplicateDrawerOpen(true)}>
                {!isMobile && 'Find Duplicates'}
              </Button>
              <Button type="primary" icon={<PlusOutlined />} onClick={() => openDetail('new')}>
                {!isMobile && 'Add Contact'}
              </Button>
            </Space>
          </Col>
        </Row>

        {/* Filters */}
        {viewMode !== 'Graph' && (
          <Row gutter={[12, 12]} style={{ marginBottom: 16 }} align="middle">
            <Col xs={24} sm={10} md={6}>
              <Input
                placeholder="Search by name, email, phone..."
                prefix={<SearchOutlined />}
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                allowClear
              />
            </Col>
            <Col xs={12} sm={7} md={4}>
              <Select
                placeholder="Source"
                options={sourceOptions}
                value={sourceFilter}
                onChange={setSourceFilter}
                allowClear
                style={{ width: '100%' }}
              />
            </Col>
            <Col xs={12} sm={7} md={4}>
              <Select
                placeholder="Support Level"
                options={supportLevelOptions}
                value={supportFilter}
                onChange={setSupportFilter}
                allowClear
                style={{ width: '100%' }}
              />
            </Col>
            {!isMobile && (
              <Col md={4}>
                <Select
                  placeholder="Tag"
                  options={registeredTags.map((t) => ({ value: t.name, label: t.name }))}
                  value={tagFilter}
                  onChange={setTagFilter}
                  allowClear
                  showSearch
                  style={{ width: '100%' }}
                />
              </Col>
            )}
            <Col>
              <Space>
                <Switch
                  checked={managedOnly}
                  onChange={setManagedOnly}
                  size="small"
                />
                <Typography.Text style={{ fontSize: 12 }}>Managed only</Typography.Text>
              </Space>
            </Col>
          </Row>
        )}

        {/* Bulk Action Bar */}
        {viewMode === 'Table' && selectedRowKeys.length > 0 && (
          <div
            style={{
              padding: '8px 16px',
              marginBottom: 12,
              background: token.colorBgElevated,
              borderRadius: token.borderRadiusLG,
              border: `1px solid ${token.colorBorderSecondary}`,
              display: 'flex',
              alignItems: 'center',
              gap: 12,
              flexWrap: 'wrap',
            }}
          >
            <Typography.Text strong style={{ fontSize: 13 }}>
              {selectedRowKeys.length} selected
            </Typography.Text>
            <Select
              placeholder="Add tag..."
              size="small"
              style={{ minWidth: 140 }}
              options={registeredTags.map((t) => ({ value: t.name, label: t.name }))}
              showSearch
              onSelect={(val) => val && handleBulkTag(val, 'add')}
              value={undefined}
            />
            <Select
              placeholder="Remove tag..."
              size="small"
              style={{ minWidth: 140 }}
              options={registeredTags.map((t) => ({ value: t.name, label: t.name }))}
              showSearch
              onSelect={(val) => val && handleBulkTag(val, 'remove')}
              value={undefined}
            />
            <Button size="small" onClick={() => setSelectedRowKeys([])}>
              Clear selection
            </Button>
          </div>
        )}

        {/* Table View */}
        {viewMode === 'Table' && (
          <Table<UnifiedPerson>
            columns={columns}
            dataSource={people}
            rowKey="id"
            loading={loading}
            rowSelection={{
              selectedRowKeys,
              onChange: setSelectedRowKeys,
            }}
            pagination={{
              current: pagination.page,
              pageSize: pagination.limit,
              total: pagination.total,
              showSizeChanger: true,
              showTotal: (total) => `${total} people`,
            }}
            onChange={handleTableChange}
            scroll={{ x: 'max-content' }}
            locale={{ emptyText: 'No people found' }}
          />
        )}

        {/* Cards View */}
        {viewMode === 'Cards' && (
          <>
            {loading ? (
              <div style={{ textAlign: 'center', padding: 48 }}>
                <Spin size="large" />
              </div>
            ) : people.length === 0 ? (
              <Empty description="No people found" />
            ) : (
              <>
                <Row gutter={[16, 16]}>
                  {people.map((person) => (
                    <Col key={person.id} xs={24} sm={12} md={8} lg={6}>
                      <PersonCard
                        person={person}
                        onClick={() => openDetail(person.id)}
                        onManage={() => handleManage(person)}
                      />
                    </Col>
                  ))}
                </Row>
                <div style={{ display: 'flex', justifyContent: 'center', marginTop: 24 }}>
                  <Pagination
                    current={pagination.page}
                    pageSize={pagination.limit}
                    total={pagination.total}
                    showSizeChanger
                    showTotal={(total) => `${total} people`}
                    onChange={(page, pageSize) => {
                      setPagination((prev) => ({ ...prev, limit: pageSize }));
                      fetchPeople(page);
                    }}
                  />
                </div>
              </>
            )}
          </>
        )}

        {/* Graph View */}
        {viewMode === 'Graph' && (
          <div style={{ height: 'calc(100vh - 220px)', minHeight: 400 }}>
            <ConnectionGraph onNodeClick={openDetail} />
          </div>
        )}
      </div>

      {/* Person Detail Drawer */}
      <PersonDetailDrawer
        open={detailDrawerOpen}
        personId={selectedPersonId}
        onClose={() => {
          setDetailDrawerOpen(false);
          setSelectedPersonId(null);
        }}
        onRefresh={() => {
          fetchPeople();
          fetchStats();
        }}
      />

      {/* Duplicate Detection Drawer */}
      <DuplicateDetectionDrawer
        open={duplicateDrawerOpen}
        onClose={() => setDuplicateDrawerOpen(false)}
        onMerge={(personA) => {
          setDuplicateDrawerOpen(false);
          openDetail(personA.id);
        }}
      />

      {/* Tag Management Drawer */}
      <TagManagementDrawer
        open={tagModalOpen}
        onClose={() => setTagModalOpen(false)}
        onTagsChanged={() => {
          fetchRegisteredTags();
          fetchPeople();
        }}
      />
    </>
  );
}
