/**
 * Tests for commStore — Phase 7 Task 7.7
 *
 * Tests: Initial state, setConversations, setActiveConversation,
 * addMessage, setMessages, updateConversation, setTyping, setUnread, setLoading
 */
import { describe, it, expect, beforeEach } from 'vitest';
import { useCommStore, type Conversation, type Message } from '../commStore';

const mockConversation: Conversation = {
  id: 'conv-1',
  title: 'Test Conversation',
  is_locked: false,
  locked_by: null,
  is_direct: false,
  is_archived: false,
  is_pinned: false,
  created_by: 'user-1',
  created_by_type: 'user',
  last_msg_at: null,
  last_msg_preview: null,
  last_msg_sender_type: null,
  participants: [],
  unread_count: 0,
  metadata: {},
};

const mockMessage: Message = {
  id: 'msg-1',
  conversation_id: 'conv-1',
  sender_id: 'user-1',
  sender_type: 'user',
  content: 'Hello World',
  content_format: 'text',
  metadata: {},
  reply_to_id: null,
  is_pinned: false,
  created_at: '2024-01-01T00:00:00Z',
  edited_at: null,
  blocks: [],
  attachments: [],
  reactions: [],
};

describe('commStore', () => {
  beforeEach(() => {
    useCommStore.setState({
      conversations: [],
      activeConversationId: null,
      messages: {},
      typingUsers: {},
      unreadCounts: {},
      loading: false,
    });
  });

  describe('initial state', () => {
    it('starts with empty conversations', () => {
      expect(useCommStore.getState().conversations).toEqual([]);
    });

    it('starts with null activeConversationId', () => {
      expect(useCommStore.getState().activeConversationId).toBeNull();
    });

    it('starts with empty messages map', () => {
      expect(useCommStore.getState().messages).toEqual({});
    });

    it('starts with empty typingUsers map', () => {
      expect(useCommStore.getState().typingUsers).toEqual({});
    });

    it('starts with empty unreadCounts map', () => {
      expect(useCommStore.getState().unreadCounts).toEqual({});
    });

    it('starts not loading', () => {
      expect(useCommStore.getState().loading).toBe(false);
    });
  });

  describe('setConversations', () => {
    it('sets conversations list', () => {
      useCommStore.getState().setConversations([mockConversation]);
      expect(useCommStore.getState().conversations).toHaveLength(1);
      expect(useCommStore.getState().conversations[0].id).toBe('conv-1');
    });

    it('replaces existing conversations', () => {
      useCommStore.getState().setConversations([mockConversation]);
      useCommStore.getState().setConversations([]);
      expect(useCommStore.getState().conversations).toEqual([]);
    });
  });

  describe('setActiveConversation', () => {
    it('sets active conversation id', () => {
      useCommStore.getState().setActiveConversation('conv-1');
      expect(useCommStore.getState().activeConversationId).toBe('conv-1');
    });

    it('sets active conversation to null', () => {
      useCommStore.getState().setActiveConversation('conv-1');
      useCommStore.getState().setActiveConversation(null);
      expect(useCommStore.getState().activeConversationId).toBeNull();
    });
  });

  describe('addMessage', () => {
    it('adds message to empty conversation', () => {
      useCommStore.getState().addMessage('conv-1', mockMessage);
      expect(useCommStore.getState().messages['conv-1']).toHaveLength(1);
      expect(useCommStore.getState().messages['conv-1'][0].id).toBe('msg-1');
    });

    it('appends message to existing conversation messages', () => {
      useCommStore.getState().addMessage('conv-1', mockMessage);
      useCommStore.getState().addMessage('conv-1', { ...mockMessage, id: 'msg-2' });
      expect(useCommStore.getState().messages['conv-1']).toHaveLength(2);
    });

    it('does not affect other conversations', () => {
      useCommStore.getState().addMessage('conv-1', mockMessage);
      useCommStore.getState().addMessage('conv-2', { ...mockMessage, id: 'msg-3', conversation_id: 'conv-2' });
      expect(useCommStore.getState().messages['conv-1']).toHaveLength(1);
      expect(useCommStore.getState().messages['conv-2']).toHaveLength(1);
    });
  });

  describe('setMessages', () => {
    it('sets messages for a conversation', () => {
      const msgs = [mockMessage, { ...mockMessage, id: 'msg-2' }];
      useCommStore.getState().setMessages('conv-1', msgs);
      expect(useCommStore.getState().messages['conv-1']).toHaveLength(2);
    });

    it('replaces existing messages for a conversation', () => {
      useCommStore.getState().addMessage('conv-1', mockMessage);
      useCommStore.getState().setMessages('conv-1', []);
      expect(useCommStore.getState().messages['conv-1']).toEqual([]);
    });
  });

  describe('updateConversation', () => {
    it('updates an existing conversation by id', () => {
      useCommStore.getState().setConversations([mockConversation]);
      useCommStore.getState().updateConversation({ ...mockConversation, title: 'Updated Title' });
      expect(useCommStore.getState().conversations[0].title).toBe('Updated Title');
    });

    it('does not add new conversation if id does not match', () => {
      useCommStore.getState().setConversations([mockConversation]);
      useCommStore.getState().updateConversation({ ...mockConversation, id: 'nonexistent' });
      expect(useCommStore.getState().conversations).toHaveLength(1);
    });
  });

  describe('setTyping', () => {
    it('sets typing users for a conversation', () => {
      useCommStore.getState().setTyping('conv-1', ['user-1', 'user-2']);
      expect(useCommStore.getState().typingUsers['conv-1']).toEqual(['user-1', 'user-2']);
    });

    it('overwrites existing typing users', () => {
      useCommStore.getState().setTyping('conv-1', ['user-1']);
      useCommStore.getState().setTyping('conv-1', []);
      expect(useCommStore.getState().typingUsers['conv-1']).toEqual([]);
    });
  });

  describe('setUnread', () => {
    it('sets unread count for a conversation', () => {
      useCommStore.getState().setUnread('conv-1', 5);
      expect(useCommStore.getState().unreadCounts['conv-1']).toBe(5);
    });

    it('sets unread count to 0', () => {
      useCommStore.getState().setUnread('conv-1', 5);
      useCommStore.getState().setUnread('conv-1', 0);
      expect(useCommStore.getState().unreadCounts['conv-1']).toBe(0);
    });
  });

  describe('setLoading', () => {
    it('sets loading to true', () => {
      useCommStore.getState().setLoading(true);
      expect(useCommStore.getState().loading).toBe(true);
    });

    it('sets loading to false', () => {
      useCommStore.getState().setLoading(true);
      useCommStore.getState().setLoading(false);
      expect(useCommStore.getState().loading).toBe(false);
    });
  });
});
