// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========

import { act, renderHook, waitFor } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

// Import proxy mock to enable API mocking
import '../../mocks/proxy.mock';
// Also Mock authStore & sse
import '../../mocks/authStore.mock';
import '../../mocks/sse.mock';

// Import chat store to ensure it's available
import '../../../src/store/chatStore';

import useChatStoreAdapter from '../../../src/hooks/useChatStoreAdapter';
import { useProjectStore } from '../../../src/store/projectStore';
import { createSSESequence, mockFetchEventSource } from '../../mocks/sse.mock';

// Mock electron IPC
(global as any).ipcRenderer = {
  invoke: vi.fn((channel) => {
    if (channel === 'get-system-language') return Promise.resolve('en');
    if (channel === 'get-browser-port') return Promise.resolve(9222);
    if (channel === 'get-env-path') return Promise.resolve('/path/to/env');
    if (channel === 'mcp-list') return Promise.resolve({});
    if (channel === 'get-file-list') return Promise.resolve([]);
    return Promise.resolve();
  }),
};

// Mock window.electronAPI
Object.defineProperty(window, 'electronAPI', {
  value: {
    uploadLog: vi.fn().mockResolvedValue(undefined),
    // Add other electronAPI methods as needed
  },
  writable: true,
});

describe('Case 3: Add to the workforce queue', () => {
  beforeEach(() => {
    vi.clearAllMocks();

    const { result } = renderHook(() => useProjectStore());
    //Reset projectStore
    result.current.getAllProjects().forEach((project) => {
      result.current.removeProject(project.id);
    });

    //Create initial Project
    const projectId = result.current.createProject(
      'Queue Test Project',
      'Testing message queue functionality'
    );
    expect(projectId).toBeDefined();

    // Get chatStore (automatically created)
    let chatStore = result.current.getActiveChatStore(projectId)!;
    expect(chatStore).toBeDefined();
    const initiatorTaskId = chatStore.getState().activeTaskId!;
    expect(initiatorTaskId).toBeDefined();
  });

  afterEach(() => {
    vi.clearAllMocks();
  });

  it('should queue messages when task is busy and process them after completion', async () => {
    const { result, rerender } = renderHook(() => useChatStoreAdapter());

    let sseCallCount = 0;
    let queuedTaskIds: string[] = [];

    // Mock SSE stream with controlled events - delay setup until after task IDs are available
    mockFetchEventSource.mockImplementation(
      async (url: string, options: any) => {
        sseCallCount++;
        console.log(`SSE Call #${sseCallCount} initiated`);

        if (options.onmessage) {
          // First send the immediate events (confirmed, to_sub_tasks, end)
          const immediateSequence = createSSESequence([
            {
              event: {
                step: 'confirmed',
                data: { question: 'Build a calculator app' },
              },
              delay: 100,
            },
            {
              event: {
                step: 'to_sub_tasks',
                data: {
                  summary_task: 'Calculator App|Build a simple calculator',
                  sub_tasks: [
                    {
                      id: 'task-1',
                      content: 'Create UI components',
                      status: '',
                    },
                    {
                      id: 'task-2',
                      content: 'Implement calculator logic',
                      status: '',
                    },
                  ],
                },
              },
              delay: 200,
            },
            {
              event: {
                step: 'end',
                data: '--- Calculator Task Result ---\nCalculator app completed successfully!',
              },
              delay: 300,
            },
          ]);
          await immediateSequence(options.onmessage);

          // Wait for queuedTaskIds to be populated, then send queue-related events
          const checkForTaskIds = () => {
            return new Promise<void>((resolve, reject) => {
              const startTime = Date.now();
              const timeout = 5000; // 5 second timeout
              const pollForIds = () => {
                if (queuedTaskIds.length > 0) {
                  console.log(`Found queued task IDs: ${queuedTaskIds}`);
                  resolve();
                } else if (Date.now() - startTime > timeout) {
                  reject(new Error('Timeout waiting for queued task IDs'));
                } else {
                  setTimeout(pollForIds, 50); // Check every 50ms
                }
              };
              pollForIds();
            });
          };

          await checkForTaskIds();

          // Now send the queue-related events with actual task IDs
          const queueSequence = createSSESequence([
            {
              event: {
                step: 'new_task_state',
                data: {
                  task_id: queuedTaskIds[0], // First queued task ID
                  content: 'Build a calculator app 2',
                  project_id: currentProjectId,
                },
              },
              delay: 100,
            },
            {
              event: {
                step: 'remove_task',
                data: {
                  task_id: queuedTaskIds[0], // Remove first task from queue
                  project_id: currentProjectId,
                },
              },
              delay: 200,
            },
            {
              event: {
                step: 'confirmed',
                data: { question: 'Build a calculator app 2' },
              },
              delay: 100,
            },
            {
              event: {
                step: 'to_sub_tasks',
                data: {
                  summary_task: 'Calculator App|Build a simple calculator 2',
                  sub_tasks: [
                    {
                      id: 'task-1',
                      content: 'Create UI components 2',
                      status: '',
                    },
                    {
                      id: 'task-2',
                      content: 'Implement calculator logic 2',
                      status: '',
                    },
                  ],
                },
              },
              delay: 200,
            },
            {
              event: {
                step: 'end',
                data: '--- Queue Result ---\nCalculator app completed successfully!',
              },
              delay: 300,
            },
          ]);
          await queueSequence(options.onmessage);
        }
      }
    );

    // Get initial state
    const { chatStore: initialChatStore, projectStore } = result.current;
    const projectId = projectStore.activeProjectId as string;
    const initiatorTaskId = initialChatStore.activeTaskId;

    // Verify initial queue is empty
    expect(projectStore.getProjectById(projectId)?.queuedMessages).toEqual([]);

    // Store projectId in outer scope for use in SSE mock
    let currentProjectId = projectId;

    // Step 1: Start first task
    await act(async () => {
      const userMessage = 'Build a calculator app';
      await initialChatStore.startTask(
        initiatorTaskId,
        undefined,
        undefined,
        undefined,
        userMessage
      );
      rerender();
    });

    // Wait for task to start and reach 'to_sub_tasks' phase (task becomes busy)
    await waitFor(
      () => {
        rerender();
        const { chatStore, projectStore: _projectStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        // Task should have subtasks (making it busy)
        expect(task.summaryTask).toBe(
          'Calculator App|Build a simple calculator'
        );
        expect(task.taskInfo).toHaveLength(3);
        console.log('Task reached to_sub_tasks phase - now busy');
      },
      { timeout: 1500 }
    );

    // Step 2: Add messages to queue while task is busy
    await act(async () => {
      rerender();
      const { projectStore } = result.current;
      const projectId = projectStore.activeProjectId as string;

      // Add first queued message
      const tempMessageContent1 = 'Build a todo app';
      const currentAttaches1: any[] = [];
      const new_task_id_1 = projectStore.addQueuedMessage(
        projectId,
        tempMessageContent1,
        currentAttaches1
      );

      // Add second queued message
      const tempMessageContent2 = 'Create a weather app';
      const currentAttaches2: any[] = [];
      const new_task_id_2 = projectStore.addQueuedMessage(
        projectId,
        tempMessageContent2,
        currentAttaches2
      );

      expect(new_task_id_1).toBeDefined();
      expect(new_task_id_2).toBeDefined();
      expect(new_task_id_1).not.toBe(new_task_id_2);

      // Store task IDs for SSE events
      queuedTaskIds = [new_task_id_1!, new_task_id_2!];

      console.log('Added messages to queue:', { new_task_id_1, new_task_id_2 });
    });

    // Step 3: Verify messages are in queue
    await waitFor(() => {
      rerender();
      const { projectStore } = result.current;
      const project = projectStore.getProjectById(projectId);

      expect(project?.queuedMessages).toHaveLength(2);
      expect(project?.queuedMessages?.[0].content).toBe('Build a todo app');
      expect(project?.queuedMessages?.[1].content).toBe('Create a weather app');

      console.log('Queue verified with 2 messages');
    });

    // Step 4: Wait for task completion
    await waitFor(
      () => {
        rerender();
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        expect(task.status).toBe('finished');
        console.log('Main task completed');
      },
      { timeout: 2000 }
    );

    // Step 5: Wait for new_task_state event to process queue
    await waitFor(
      () => {
        rerender();
        //Get new appended chatStore
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        // Look for new_task_state in messages
        const hasNewTaskState = task.messages.some(
          (m: any) => m.content === 'Build a calculator app 2'
        );
        expect(hasNewTaskState).toBe(true);
        console.log('new_task_state event detected - new chat created');
      },
      { timeout: 3000 }
    );

    // Step 6: Wait for remove_task event to clear queue
    await waitFor(
      () => {
        rerender();
        const { projectStore } = result.current;
        const project = projectStore.getProjectById(projectId);

        // After remove_task event, first queued message should be removed, leaving 1 message
        expect(project?.queuedMessages).toHaveLength(1);
        expect(project?.queuedMessages?.[0].content).toBe(
          'Create a weather app'
        );

        console.log('Queue processed - first message removed');
      },
      { timeout: 4000 }
    );

    //Waitfor end sse
    await waitFor(
      () => {
        rerender();
        const { chatStore: finalChatStore, projectStore: _finalProjectStore } =
          result.current;
        const finalTaskId = finalChatStore.activeTaskId;
        const finalTask = finalChatStore.tasks[finalTaskId];
        expect(finalTask.status).toBe('finished');
      },
      { timeout: 2000 }
    );

    // Step 7: Verify final state
    const { chatStore: finalChatStore, projectStore: finalProjectStore } =
      result.current;
    const finalProject = finalProjectStore.getProjectById(projectId);

    // Queue should have 1 remaining message (the second one)
    expect(finalProject?.queuedMessages).toHaveLength(1);
    expect(finalProject?.queuedMessages?.[0].content).toBe(
      'Create a weather app'
    );

    // Verify task completed successfully
    const finalTaskId = finalChatStore.activeTaskId;
    const finalTask = finalChatStore.tasks[finalTaskId];
    expect(finalTask.status).toBe('finished');
    //Not to be because its a new chatStore
    expect(finalTask.summaryTask).not.toBe(
      'Calculator App|Build a simple calculator'
    );
    expect(finalTask.summaryTask).toBe(
      'Calculator App|Build a simple calculator 2'
    );

    console.log(
      'Test completed - queue management verified: one task processed, one remains'
    );
  });

  it('should handle multiple queue additions and removals correctly', async () => {
    const { result, rerender: _rerender } = renderHook(() =>
      useChatStoreAdapter()
    );
    const { projectStore } = result.current;
    const projectId = projectStore.activeProjectId as string;

    // Verify initial state
    expect(projectStore.getProjectById(projectId)?.queuedMessages).toEqual([]);

    await act(async () => {
      // Add multiple messages to queue
      const messages = [
        'Build a calculator',
        'Create a todo app',
        'Develop a weather app',
        'Make a chat application',
      ];

      const taskIds: string[] = [];

      messages.forEach((message, _index) => {
        const taskId = projectStore.addQueuedMessage(projectId, message, []);
        taskIds.push(taskId);
        expect(taskId).toBeDefined();
      });

      // Verify all messages are queued
      const project = projectStore.getProjectById(projectId);
      expect(project?.queuedMessages).toHaveLength(4);

      messages.forEach((message, index) => {
        expect(project?.queuedMessages?.[index].content).toBe(message);
        expect(project?.queuedMessages?.[index].task_id).toBe(taskIds[index]);
      });

      // Remove middle message
      projectStore.removeQueuedMessage(projectId, taskIds[1]);

      // Verify removal
      const updatedProject = projectStore.getProjectById(projectId);
      expect(updatedProject?.queuedMessages).toHaveLength(3);
      expect(
        updatedProject?.queuedMessages?.map((m: any) => m.content)
      ).toEqual([
        'Build a calculator',
        'Develop a weather app',
        'Make a chat application',
      ]);

      // Remove first message
      projectStore.removeQueuedMessage(projectId, taskIds[0]);

      // Verify second removal
      const finalProject = projectStore.getProjectById(projectId);
      expect(finalProject?.queuedMessages).toHaveLength(2);
      expect(finalProject?.queuedMessages?.map((m: any) => m.content)).toEqual([
        'Develop a weather app',
        'Make a chat application',
      ]);
    });
  });

  it('should restore queued message when removal fails', async () => {
    const { result, rerender: _rerender } = renderHook(() =>
      useChatStoreAdapter()
    );
    const { projectStore } = result.current;
    const projectId = projectStore.activeProjectId as string;

    await act(async () => {
      // Add a message to queue
      const messageContent = 'Test message for restoration';
      const attachments: any[] = [
        { fileName: 'test.txt', filePath: '/test/path' },
      ];

      const taskId = projectStore.addQueuedMessage(
        projectId,
        messageContent,
        attachments
      );

      // Verify message is queued
      let project = projectStore.getProjectById(projectId);
      expect(project?.queuedMessages).toHaveLength(1);
      expect(project?.queuedMessages?.[0].content).toBe(messageContent);
      expect(project?.queuedMessages?.[0].attaches).toEqual(attachments);

      // Store original message for comparison
      const originalMessage = project?.queuedMessages?.[0];

      // Remove the message (this would normally trigger an API call)
      projectStore.removeQueuedMessage(projectId, taskId);

      // Verify optimistic removal
      project = projectStore.getProjectById(projectId);
      expect(project?.queuedMessages).toHaveLength(0);

      // Simulate restoration (as would happen on API failure)
      if (originalMessage) {
        projectStore.restoreQueuedMessage(projectId, {
          task_id: originalMessage.task_id,
          content: originalMessage.content,
          timestamp: originalMessage.timestamp,
          attaches: originalMessage.attaches,
        });
      }

      // Verify message is restored
      project = projectStore.getProjectById(projectId);
      expect(project?.queuedMessages).toHaveLength(1);
      expect(project?.queuedMessages?.[0].content).toBe(messageContent);
      expect(project?.queuedMessages?.[0].attaches).toEqual(attachments);
      expect(project?.queuedMessages?.[0].task_id).toBe(taskId);
    });
  });

  it('should maintain queue order and timestamps correctly', async () => {
    const { result, rerender: _rerender } = renderHook(() =>
      useChatStoreAdapter()
    );
    const { projectStore } = result.current;
    const projectId = projectStore.activeProjectId as string;

    await act(async () => {
      const messages = ['First message', 'Second message', 'Third message'];
      const taskIds: string[] = [];
      const timestamps: number[] = [];

      // Add messages with small delays to ensure different timestamps
      for (let i = 0; i < messages.length; i++) {
        await new Promise((resolve) => setTimeout(resolve, 10));

        const taskId = projectStore.addQueuedMessage(
          projectId,
          messages[i],
          []
        );
        taskIds.push(taskId);

        const project = projectStore.getProjectById(projectId);
        const addedMessage = project?.queuedMessages?.find(
          (m: any) => m.task_id === taskId
        );
        if (addedMessage) {
          timestamps.push(addedMessage.timestamp);
        }
      }

      // Verify order and timestamps
      const project = projectStore.getProjectById(projectId);
      expect(project?.queuedMessages).toHaveLength(3);

      project?.queuedMessages?.forEach((message: any, index: number) => {
        expect(message.content).toBe(messages[index]);
        expect(message.task_id).toBe(taskIds[index]);
        expect(message.timestamp).toBe(timestamps[index]);

        // Verify timestamps are in ascending order
        if (index > 0) {
          expect(message.timestamp).toBeGreaterThanOrEqual(
            timestamps[index - 1]
          );
        }
      });
    });
  });

  it('should handle confirmed -> subtasks -> end -> new_task_state -> remove_task sequence with queue processing', async () => {
    const { result, rerender } = renderHook(() => useChatStoreAdapter());

    let comprehensiveQueuedTaskIds: string[] = [];

    // Get initial state
    const { chatStore: initialChatStore, projectStore } = result.current;
    const projectId = projectStore.activeProjectId as string;
    const initiatorTaskId = initialChatStore.activeTaskId;

    // Verify initial queue is empty
    expect(projectStore.getProjectById(projectId)?.queuedMessages).toEqual([]);

    // Mock SSE stream with controlled events - delay queue-related events until task IDs are available
    mockFetchEventSource.mockImplementation(
      async (url: string, options: any) => {
        if (options.onmessage) {
          // First send the immediate events (confirmed, to_sub_tasks, end)
          const immediateSequence = createSSESequence([
            {
              event: {
                step: 'confirmed',
                data: { question: 'Build a calculator app' },
              },
              delay: 100,
            },
            {
              event: {
                step: 'to_sub_tasks',
                data: {
                  summary_task:
                    'Calculator App|Build a comprehensive calculator',
                  sub_tasks: [
                    {
                      id: 'calc-ui',
                      content: 'Create calculator UI',
                      status: '',
                    },
                    {
                      id: 'calc-logic',
                      content: 'Implement calculation logic',
                      status: '',
                    },
                    {
                      id: 'calc-tests',
                      content: 'Write unit tests',
                      status: '',
                    },
                  ],
                },
              },
              delay: 200,
            },
            {
              event: {
                step: 'end',
                data: '--- Task Completed Successfully ---\nCalculator app development finished!',
              },
              delay: 300,
            },
          ]);
          await immediateSequence(options.onmessage);

          // Wait for comprehensiveQueuedTaskIds to be populated, then send queue-related events
          const checkForTaskIds = () => {
            return new Promise<void>((resolve, reject) => {
              const startTime = Date.now();
              const timeout = 5000; // 5 second timeout
              const pollForIds = () => {
                if (comprehensiveQueuedTaskIds.length > 0) {
                  console.log(
                    `Found comprehensive queued task IDs: ${comprehensiveQueuedTaskIds}`
                  );
                  resolve();
                } else if (Date.now() - startTime > timeout) {
                  reject(
                    new Error(
                      'Timeout waiting for comprehensive queued task IDs'
                    )
                  );
                } else {
                  setTimeout(pollForIds, 50); // Check every 50ms
                }
              };
              pollForIds();
            });
          };

          await checkForTaskIds();

          // Now send the queue-related events with actual task IDs
          const queueSequence = createSSESequence([
            {
              event: {
                step: 'confirmed',
                data: {
                  task_id: comprehensiveQueuedTaskIds[0], // First queued task ID
                  question: 'Build a todo application',
                },
              },
              delay: 100,
            },
            {
              event: {
                step: 'new_task_state',
                data: {
                  task_id: comprehensiveQueuedTaskIds[0], // First queued task ID
                  content: 'Build a todo application',
                  project_id: projectId,
                },
              },
              delay: 100,
            },
            {
              event: {
                step: 'remove_task',
                data: {
                  task_id: comprehensiveQueuedTaskIds[0], // Remove first task from queue
                  project_id: projectId,
                },
              },
              delay: 200,
            },
            {
              event: {
                step: 'end',
                data: '--- Task Completed Successfully ---\nCalculator app development finished! 2',
              },
              delay: 300,
            },
          ]);
          await queueSequence(options.onmessage);
        }
      }
    );

    // Step 1: Start the main task
    await act(async () => {
      const userMessage = 'Build a calculator app';
      await initialChatStore.startTask(
        initiatorTaskId,
        undefined,
        undefined,
        undefined,
        userMessage
      );
      rerender();
    });
    // Step 2: Wait for confirmed event
    await waitFor(
      () => {
        rerender();
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        // Check for confirmed step
        const hasContent = task.messages.some(
          (m: any) => m.content === 'Build a calculator app'
        );
        expect(hasContent).toBe(true);
        console.log('✓ Confirmed event received');
      },
      { timeout: 1000 }
    );

    // Step 3: Wait for subtasks event
    await waitFor(
      () => {
        rerender();
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        // Task should have subtasks
        expect(task.summaryTask).toBe(
          'Calculator App|Build a comprehensive calculator'
        );
        expect(task.taskInfo).toHaveLength(4); // main task + 3 subtasks
        expect(task.taskRunning).toHaveLength(4);
        console.log('✓ Subtasks created');
      },
      { timeout: 1500 }
    );

    // Step 4: Add messages to queue while task is in subtasks phase
    await act(async () => {
      rerender();
      const { projectStore } = result.current;
      const projectId = projectStore.activeProjectId as string;

      // Add queued messages
      const tempMessageContent1 = 'Build a todo application';
      const currentAttaches1: any[] = [
        { fileName: 'requirements.txt', filePath: '/path/to/req.txt' },
      ];
      const new_task_id_1 = projectStore.addQueuedMessage(
        projectId,
        tempMessageContent1,
        currentAttaches1
      );

      const tempMessageContent2 = 'Create a weather dashboard';
      const currentAttaches2: any[] = [];
      const new_task_id_2 = projectStore.addQueuedMessage(
        projectId,
        tempMessageContent2,
        currentAttaches2
      );

      expect(new_task_id_1).toBeDefined();
      expect(new_task_id_2).toBeDefined();

      // Store task IDs for SSE events
      comprehensiveQueuedTaskIds = [new_task_id_1!, new_task_id_2!];

      console.log('✓ Messages added to queue during subtasks phase');
    });

    // Step 5: Verify messages are properly queued
    await waitFor(() => {
      rerender();
      const { projectStore } = result.current;
      const project = projectStore.getProjectById(projectId);

      expect(project?.queuedMessages).toHaveLength(2);
      expect(project?.queuedMessages?.[0].content).toBe(
        'Build a todo application'
      );
      expect(project?.queuedMessages?.[1].content).toBe(
        'Create a weather dashboard'
      );
      expect(project?.queuedMessages?.[0].attaches).toHaveLength(1);
      expect(project?.queuedMessages?.[1].attaches).toHaveLength(0);
      console.log('✓ Queue contains expected messages with attachments');
    });

    // Step 6: Wait for task completion
    await waitFor(
      () => {
        rerender();
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        expect(task.status).toBe('finished');
        console.log('✓ Main task completed');
      },
      { timeout: 2000 }
    );

    // Step 7: Wait for new_task_state event (new chat creation)
    await waitFor(
      () => {
        rerender();
        const { chatStore } = result.current;
        const taskId = chatStore.activeTaskId;
        const task = chatStore.tasks[taskId];

        // Look for new_task_state event
        const hasNewTaskState = task.messages.some(
          (m: any) => m.content === 'Build a todo application'
        );
        expect(hasNewTaskState).toBe(true);
        console.log('✓ new_task_state event received - new chat created');
      },
      { timeout: 3000 }
    );

    // Step 8: Wait for remove_task event to process queue
    await waitFor(
      () => {
        rerender();
        const { projectStore } = result.current;
        const project = projectStore.getProjectById(projectId);

        // After remove_task event, first queued message should be removed, leaving 1 message
        expect(project?.queuedMessages).toHaveLength(1);
        expect(project?.queuedMessages?.[0].content).toBe(
          'Create a weather dashboard'
        );

        console.log('✓ Queue processed - first message removed');
      },
      { timeout: 4000 }
    );

    //Waitfor end sse
    await waitFor(
      () => {
        rerender();
        const { chatStore: finalChatStore, projectStore: _finalProjectStore } =
          result.current;
        const finalTaskId = finalChatStore.activeTaskId;
        const finalTask = finalChatStore.tasks[finalTaskId];
        expect(finalTask.status).toBe('finished');
      },
      { timeout: 2000 }
    );

    // Step 9: Final verification
    const { chatStore: finalChatStore, projectStore: finalProjectStore } =
      result.current;
    const finalProject = finalProjectStore.getProjectById(projectId);
    const finalTaskId = finalChatStore.activeTaskId;
    const finalTask = finalChatStore.tasks[finalTaskId];

    // Queue should have 1 remaining message (the second one)
    expect(finalProject?.queuedMessages).toHaveLength(1);
    expect(finalProject?.queuedMessages?.[0].content).toBe(
      'Create a weather dashboard'
    );

    expect(finalTask.status).toBe('finished');
    //This time lets not add sub_task sse
    expect(finalTask.summaryTask).not.toBe(
      'Calculator App|Build a comprehensive calculator'
    );

    //Get previous chatStore
    const allChatStores = finalProjectStore.getAllChatStores(
      finalProjectStore.activeProjectId
    );
    // Should have initial + first task + second task = 3 chat stores
    expect(allChatStores).toHaveLength(3);
    const [_initial, first, _second] = allChatStores;
    const originalTaskId = first.chatStore.getState().activeTaskId;
    const originalFinalTask = first.chatStore.getState().tasks[originalTaskId];
    expect(originalFinalTask.summaryTask).toBe(
      'Calculator App|Build a comprehensive calculator'
    );
    expect(originalFinalTask.taskInfo).toHaveLength(4);

    // Verify all subtasks are properly marked as skipped after completion
    originalFinalTask.taskRunning.forEach((task: any) => {
      expect(task.status).toBe('skipped');
    });
    originalFinalTask.taskInfo.forEach((task: any) => {
      expect(task.status).toBe('skipped');
    });

    console.log(
      '✓ Complete test sequence verified: confirmed → subtasks → end → new_task_state → remove_task → one task processed, one remains'
    );
  });
});
