/**
 * Chat TypeScript Types
 * Types for the Zeiterfassung chat feature
 */

export interface ChatUser {
  id: number;
  name: string;
  avatar: string | null;
  email?: string;
  isOnline?: boolean;
  lastSeen?: string;
}

// User with conversation info for the user list
export interface ChatUserWithConversation extends ChatUser {
  conversationId?: string;
  lastMessage?: ChatMessage;
  unreadCount?: number;
}

export interface ChatMessage {
  id: string;
  conversationId: string;
  senderId: number;
  content: string;
  timestamp: string;
  status: 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
  type: 'text' | 'image' | 'file';
}

export interface ChatConversation {
  id: string;
  type: 'direct' | 'group';
  name?: string; // For group chats
  participants: ChatUser[];
  lastMessage?: ChatMessage;
  unreadCount: number;
  createdAt: string;
  updatedAt: string;
}

export interface ChatBoxState {
  conversationId: string;
  conversation: ChatConversation | null;
  minimized: boolean;
  position: number; // Index from right (0 = rightmost)
  unreadCount: number;
}

export interface ChatToken {
  token: string;
  expiresAt: string | null;
  chatServerUrl: string;
  userId: number;
}

export interface WebSocketMessage {
  type: 'message' | 'typing' | 'read' | 'online' | 'offline' | 'error';
  payload: any;
}

export interface TypingIndicator {
  conversationId: string;
  userId: number;
  isTyping: boolean;
}

// Chat container responsive settings
export interface ChatResponsiveSettings {
  boxWidth: number;
  boxHeight: number;
  minimizedHeight: number;
  maxVisibleBoxes: number;
  isMobile: boolean;
}

// Chat hook return types
export interface UseChatWebSocketReturn {
  connected: boolean;
  connecting: boolean;
  error: string | null;
  sendMessage: (conversationId: string, content: string) => void;
  createAndSendMessage: (recipientUserId: number, content: string) => Promise<{ success: boolean; conversation?: any; message?: any; error?: string }>;
  sendTyping: (conversationId: string, isTyping: boolean) => void;
  markAsRead: (conversationId: string) => void;
  onlineUsers: Set<number>;
  disconnect: () => void;
  joinConversation: (conversationId: string) => void;
  leaveConversation: (conversationId: string) => void;
  getPresence: (userIds: number[]) => void;
  chatToken: string | null;
  chatServerUrl: string | null;
  socket: import('socket.io-client').Socket | null;
}

export interface UseChatConversationsReturn {
  openChats: ChatBoxState[];
  openChat: (userId: number, existingConversationId?: string, userName?: string, userAvatar?: string | null) => Promise<void>;
  closeChat: (conversationId: string) => void;
  minimizeChat: (conversationId: string) => void;
  expandChat: (conversationId: string) => void;
  messages: Record<string, ChatMessage[]>;
  loadingMessages: Record<string, boolean>;
  sendMessage: (conversationId: string, content: string) => void;
}

export interface UseChatUsersReturn {
  users: ChatUserWithConversation[];
  loading: boolean;
  error: string | null;
  refresh: () => void;
  searchUsers: (query: string) => ChatUserWithConversation[];
  totalUnreadCount: number;
}

// Call Types
export type CallStatus =
  | 'idle'
  | 'calling'
  | 'ringing'
  | 'connecting'
  | 'connected'
  | 'ended'
  | 'declined'
  | 'cancelled'
  | 'timeout'
  | 'busy'
  | 'failed';

export type CallType = 'audio' | 'video';

export interface CallState {
  callId: string | null;
  status: CallStatus;
  type: CallType;
  isIncoming: boolean;
  remoteUserId: number | null;
  remoteUserName: string | null;
  remoteUserAvatar: string | null;
  startTime: Date | null;
  localStream: MediaStream | null;
  remoteStream: MediaStream | null;
  isMuted: boolean;
  isVideoOff: boolean;
  isSpeakerOn: boolean;
}

export interface CallOffer {
  calleeExternalId: string;
  type?: CallType;
}

export interface IncomingCall {
  callId: string;
  callerExternalId: string;
  callerName?: string;
  callerAvatar?: string;
  type: CallType;
}

export interface UseChatCallReturn {
  callState: CallState;
  startCall: (userId: number, type: CallType) => void;
  acceptCall: () => void;
  declineCall: () => void;
  endCall: () => void;
  toggleMute: () => void;
  toggleVideo: () => void;
  toggleSpeaker: () => void;
}
