import type { Room, User } from './index';

export type DebugLogLevel = 'event' | 'info' | 'warn' | 'error' | 'debug';
export type DebugNetworkNodeKind = 'local-client' | 'remote-client' | 'signaling-server' | 'app-server';
export type DebugNetworkEdgeKind = 'peer' | 'signaling' | 'membership';
export type DebugNetworkMessageDirection = 'inbound' | 'outbound';
export type DebugNetworkMessageScope = 'data-channel' | 'signaling';

export interface DebugLogEntry {
  id: number;
  timestamp: number;
  timeLabel: string;
  dateTimeLabel: string;
  level: DebugLogLevel;
  source: string;
  message: string;
  payload: unknown | null;
  payloadText: string | null;
  count: number;
}

export interface DebugNetworkMessageGroup {
  id: string;
  scope: DebugNetworkMessageScope;
  direction: DebugNetworkMessageDirection;
  type: string;
  count: number;
  lastSeen: number;
}

export interface DebugNetworkHandshakeStats {
  answersReceived: number;
  answersSent: number;
  iceReceived: number;
  iceSent: number;
  offersReceived: number;
  offersSent: number;
}

export interface DebugNetworkTextStats {
  received: number;
  sent: number;
}

export interface DebugNetworkStreamStats {
  audio: number;
  video: number;
}

export interface DebugNetworkDownloadStats {
  audioMbps: number | null;
  fileMbps: number | null;
  videoMbps: number | null;
}

export interface DebugNetworkNode {
  id: string;
  identity: string | null;
  userId: string | null;
  kind: DebugNetworkNodeKind;
  label: string;
  secondaryLabel: string;
  title: string;
  statuses: string[];
  isActive: boolean;
  isVoiceConnected: boolean;
  isTyping: boolean;
  isSpeaking: boolean;
  isMuted: boolean;
  isDeafened: boolean;
  isStreaming: boolean;
  connectionDrops: number;
  downloads: DebugNetworkDownloadStats;
  handshake: DebugNetworkHandshakeStats;
  pingMs: number | null;
  streams: DebugNetworkStreamStats;
  textMessages: DebugNetworkTextStats;
  lastSeen: number;
}

export interface DebugNetworkEdge {
  id: string;
  kind: DebugNetworkEdgeKind;
  sourceId: string;
  targetId: string;
  sourceLabel: string;
  targetLabel: string;
  label: string;
  stateLabel: string;
  isActive: boolean;
  pingMs: number | null;
  lastSeen: number;
  messageTotal: number;
  messageGroups: DebugNetworkMessageGroup[];
}

export interface DebugNetworkSummary {
  clientCount: number;
  serverCount: number;
  signalingServerCount: number;
  peerConnectionCount: number;
  membershipCount: number;
  messageCount: number;
  typingCount: number;
  speakingCount: number;
  streamingCount: number;
}

export interface DebugNetworkSnapshot {
  nodes: DebugNetworkNode[];
  edges: DebugNetworkEdge[];
  summary: DebugNetworkSummary;
  generatedAt: number;
}

export interface DebuggingSettingsState {
  enabled?: boolean;
}

export interface PendingDebugEntry {
  level: DebugLogLevel;
  source: string;
  message: string;
  payload?: unknown;
  payloadText?: string | null;
  timestamp?: number;
}

export type ConsoleMethodName = 'debug' | 'log' | 'info' | 'warn' | 'error';
export type ConsoleMethod = (...args: unknown[]) => void;

export interface MutableDebugNetworkMessageGroup {
  id: string;
  scope: DebugNetworkMessageScope;
  direction: DebugNetworkMessageDirection;
  type: string;
  count: number;
  lastSeen: number;
}

export interface MutableDebugNetworkNode {
  id: string;
  identity: string | null;
  userId: string | null;
  kind: DebugNetworkNodeKind;
  label: string;
  secondaryLabel: string;
  title: string;
  lastSeen: number;
  isActive: boolean;
  isVoiceConnected: boolean;
  typingExpiresAt: number | null;
  isSpeaking: boolean;
  isMuted: boolean;
  isDeafened: boolean;
  isStreaming: boolean;
  connectionDrops: number;
  downloads: DebugNetworkDownloadStats;
  downloadsUpdatedAt: number | null;
  fileTransferSamples: DebugNetworkTransferSample[];
  handshake: DebugNetworkHandshakeStats;
  pingMs: number | null;
  streams: DebugNetworkStreamStats;
  textMessages: DebugNetworkTextStats;
}

export interface DebugNetworkTransferSample {
  bytes: number;
  timestamp: number;
}

export interface MutableDebugNetworkEdge {
  id: string;
  kind: DebugNetworkEdgeKind;
  sourceId: string;
  targetId: string;
  stateLabel: string;
  isActive: boolean;
  pingMs: number | null;
  lastSeen: number;
  messageTotal: number;
  messageGroups: Map<string, MutableDebugNetworkMessageGroup>;
}

export interface DebugNetworkBuildState {
  currentRoom: Room | null;
  currentUser: User | null;
  edges: Map<string, MutableDebugNetworkEdge>;
  localIds: Set<string>;
  nodes: Map<string, MutableDebugNetworkNode>;
  users: readonly User[];
  userLookup: Map<string, User>;
}
