import { useState, useEffect, useCallback } from 'react';
import { useOutletContext } from 'react-router-dom';
import {
  Segmented, Select, Input, Button, Drawer, Typography, Tag, Space, Avatar, Descriptions,
} from 'antd';
import {
  ReloadOutlined,
  ApartmentOutlined,
  HeartOutlined,
  TrophyOutlined,
  UsergroupAddOutlined,
} from '@ant-design/icons';
import { ReactFlowProvider } from '@xyflow/react';
import SocialNetworkGraph, { type GraphData } from '@/components/social/SocialNetworkGraph';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/types/api';
import { ROLE_COLORS, ROLE_FILTER_OPTIONS } from '@/utils/role-constants';

const { Text, Title } = Typography;

type LayoutMode = 'force' | 'radial';

interface SelectedUser {
  id: string;
  name: string | null;
  email: string;
  role: string;
  isOnline: boolean;
  friendCount: number;
  achievementCount: number;
  groups: string[];
}

/** Inner component that uses useReactFlow (must be inside ReactFlowProvider) */
function GraphPageInner() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const [loading, setLoading] = useState(true);
  const [graphData, setGraphData] = useState<GraphData | null>(null);
  const [layoutMode, setLayoutMode] = useState<LayoutMode>('force');
  const [roleFilter, setRoleFilter] = useState('');
  const [search, setSearch] = useState('');
  const [centerUserId, setCenterUserId] = useState<string | undefined>();
  const [selectedUser, setSelectedUser] = useState<SelectedUser | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);

  useEffect(() => {
    setPageHeader({ title: 'Social Network Graph', fullBleed: true });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  const fetchGraph = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string> = {};
      if (roleFilter) params.role = roleFilter;
      const { data } = await api.get('/social/admin/graph', { params });
      setGraphData(data);
    } catch {
      // ignore
    } finally {
      setLoading(false);
    }
  }, [roleFilter]);

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

  // Client-side name filter
  const filteredData: GraphData | null = (() => {
    if (!graphData || !search.trim()) return graphData;
    const q = search.toLowerCase();
    const matchedIds = new Set(
      graphData.nodes
        .filter((n) => (n.name?.toLowerCase().includes(q)) || n.email.toLowerCase().includes(q))
        .map((n) => n.id),
    );
    // Include friends of matched nodes so edges show
    for (const edge of graphData.edges) {
      if (edge.status !== 'accepted') continue;
      if (matchedIds.has(edge.source)) matchedIds.add(edge.target);
      if (matchedIds.has(edge.target)) matchedIds.add(edge.source);
    }
    return {
      nodes: graphData.nodes.filter((n) => matchedIds.has(n.id)),
      edges: graphData.edges.filter((e) => matchedIds.has(e.source) && matchedIds.has(e.target)),
    };
  })();

  const handleNodeClick = useCallback((userId: string) => {
    const node = graphData?.nodes.find((n) => n.id === userId);
    if (node) {
      setSelectedUser(node);
      setDrawerOpen(true);
    }
  }, [graphData]);

  const handleCenterOnUser = useCallback((userId: string) => {
    setLayoutMode('radial');
    setCenterUserId(userId);
  }, []);

  const nodeCount = filteredData?.nodes.length ?? 0;
  const edgeCount = filteredData?.edges.filter((e) => e.status === 'accepted').length ?? 0;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: 'calc(100vh - 64px)' }}>
      {/* Toolbar */}
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          padding: '8px 16px',
          borderBottom: '1px solid rgba(255,255,255,0.08)',
          flexWrap: 'wrap',
        }}
      >
        <Segmented
          options={[
            { label: 'Force', value: 'force', icon: <ApartmentOutlined /> },
            { label: 'Radial', value: 'radial', icon: <ApartmentOutlined /> },
          ]}
          value={layoutMode}
          onChange={(v) => {
            setLayoutMode(v as LayoutMode);
            if (v === 'force') setCenterUserId(undefined);
          }}
        />
        <Select
          value={roleFilter}
          onChange={setRoleFilter}
          options={ROLE_FILTER_OPTIONS}
          style={{ width: 150 }}
          size="small"
        />
        <Input.Search
          placeholder="Filter by name..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          allowClear
          style={{ width: 200 }}
          size="small"
        />
        <Button icon={<ReloadOutlined />} onClick={fetchGraph} size="small" loading={loading}>
          Refresh
        </Button>
        <div style={{ flex: 1 }} />
        <Text type="secondary" style={{ fontSize: 12 }}>
          {nodeCount} users, {edgeCount} friendships
        </Text>
      </div>

      {/* Graph */}
      <div style={{ flex: 1, position: 'relative' }}>
        <SocialNetworkGraph
          graphData={filteredData}
          loading={loading}
          layoutMode={layoutMode}
          centerUserId={centerUserId}
          onNodeClick={handleNodeClick}
        />
      </div>

      {/* User Detail Drawer */}
      <Drawer
        title="User Details"
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        width={360}
        placement="right"
      >
        {selectedUser && (
          <Space direction="vertical" style={{ width: '100%' }} size="middle">
            <div style={{ textAlign: 'center' }}>
              <Avatar
                size={64}
                style={{
                  backgroundColor: selectedUser.isOnline ? '#52c41a' : '#722ed1',
                  fontWeight: 600,
                  fontSize: 24,
                }}
              >
                {selectedUser.name?.[0]?.toUpperCase() || selectedUser.email[0]?.toUpperCase()}
              </Avatar>
              <Title level={4} style={{ margin: '8px 0 0' }}>
                {selectedUser.name || selectedUser.email.split('@')[0]}
              </Title>
              <Text type="secondary">{selectedUser.email}</Text>
            </div>

            <Descriptions column={1} size="small">
              <Descriptions.Item label="Role">
                <Tag color={ROLE_COLORS[selectedUser.role]}>{selectedUser.role}</Tag>
              </Descriptions.Item>
              <Descriptions.Item label="Status">
                <Tag color={selectedUser.isOnline ? 'green' : 'default'}>
                  {selectedUser.isOnline ? 'Online' : 'Offline'}
                </Tag>
              </Descriptions.Item>
              <Descriptions.Item label={<><HeartOutlined /> Friends</>}>
                {selectedUser.friendCount}
              </Descriptions.Item>
              <Descriptions.Item label={<><TrophyOutlined /> Achievements</>}>
                {selectedUser.achievementCount}
              </Descriptions.Item>
            </Descriptions>

            {selectedUser.groups.length > 0 && (
              <div>
                <Text strong><UsergroupAddOutlined /> Groups</Text>
                <div style={{ marginTop: 4 }}>
                  {selectedUser.groups.map((g, i) => (
                    <Tag key={i} color="purple" style={{ marginBottom: 4 }}>{g}</Tag>
                  ))}
                </div>
              </div>
            )}

            <Button
              block
              type="primary"
              icon={<ApartmentOutlined />}
              onClick={() => {
                handleCenterOnUser(selectedUser.id);
                setDrawerOpen(false);
              }}
            >
              Center in Radial View
            </Button>
          </Space>
        )}
      </Drawer>
    </div>
  );
}

export default function SocialGraphPage() {
  return (
    <ReactFlowProvider>
      <GraphPageInner />
    </ReactFlowProvider>
  );
}
