//
// Copyright 2023 DXOS.org
//
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { GraphModel } from '@dxos/graph';
import { useMembers } from '@dxos/react-client/echo';
import { useIdentity } from '@dxos/react-client/halo';
import { Toolbar } from '@dxos/react-ui';
import { GraphForceProjector, SVG } from '@dxos/react-ui-graph';
import { PanelContainer } from '../../../components';
import { DataSpaceSelector } from '../../../containers';
import { useDevtoolsState } from '../../../hooks';
// TODO(burdon): Update to use new GraphModel.
class NetworkGraphModel extends GraphModel.GraphModel {
    setData(graph) {
        // this._graph = graph;
    }
    setFromMemberList(members) {
        // const nodes = new Map<string, NetworkGraphNode>();
        // const edges: GraphEdge[] = [];
        // for (const member of members) {
        //   for (const peer of member.peerStates ?? []) {
        //     if (!peer.peerId) {
        //       continue;
        //     }
        //     const node = defaultMap(nodes, peer.peerId.toHex(), { id: peer.peerId.toHex() });
        //     node.peer ??= peer;
        //     node.member ??= member;
        //     for (const other of peer.connections ?? []) {
        //       defaultMap(nodes, peer.peerId.toHex(), { id: peer.peerId.toHex() });
        //       defaultMap(nodes, other.toHex(), { id: other.toHex() });
        //       edges.push({
        //         id: `${peer.peerId.toHex()}-${other.toHex()}`,
        //         source: peer.peerId.toHex(),
        //         target: other.toHex(),
        //       });
        //     }
        //   }
        // }
        // this.setData({ nodes: Array.from(nodes.values()), edges });
    }
}
const _classes = {
    default: '[&>circle]:fill-zinc-300 [&>circle]:stroke-zinc-400 [&>circle]:stroke-2',
    nodes: [
        '[&>circle]:fill-red-300',
        '[&>circle]:fill-green-300',
        '[&>circle]:fill-blue-300',
        '[&>circle]:fill-indigo-300',
        '[&>circle]:fill-teal-300',
        '[&>circle]:fill-cyan-300',
        '[&>circle]:fill-orange-300',
    ],
};
export const NetworkPanel = (props) => {
    const state = useDevtoolsState();
    const space = props.space ?? state.space;
    const identity = useIdentity();
    const isMe = (node) => identity ? node?.member?.identity.identityKey.equals(identity.identityKey) : false;
    const members = useMembers(space?.key);
    const [model] = useState(() => new NetworkGraphModel());
    useEffect(() => {
        if (members) {
            model.setFromMemberList(members);
        }
    }, [members]);
    const context = useRef(null);
    const projector = useMemo(() => context.current
        ? new GraphForceProjector(context.current, {
            forces: {
                manyBody: {
                    strength: -160,
                },
                link: {
                    distance: 120,
                    iterations: 5,
                },
                radial: {
                    radius: 60,
                    strength: 0.2,
                },
            },
            attributes: {
                radius: (node) => (isMe(node.data) ? 24 : 16),
            },
        })
        : undefined, [context]);
    // TODO(dmaretskyi): Highlight our direct connections.
    // TODO(dmaretskyi): Visualize data flowing: line thickness, running ticks, text stats.
    // TODO(dmaretskyi): Show connections that are forming.
    return (React.createElement(PanelContainer, { toolbar: props.space ? undefined : (React.createElement(Toolbar.Root, null,
            React.createElement(DataSpaceSelector, null))) },
        React.createElement(SVG.Root, { ref: context },
            React.createElement(SVG.Markers, null),
            React.createElement(SVG.Graph, { model: model, drag: true, arrows: true, projector: projector, labels: {
                    text: (node, highlight) => {
                        const identity = node.data.member?.identity.profile?.displayName ?? node.data.member?.identity.identityKey.truncate();
                        const peer = node.data.peer?.peerId?.truncate();
                        return `${peer} [${identity}]`;
                    },
                } }))));
};
//# sourceMappingURL=NetworkPanel.js.map