/**
 * workbenchStore 单元测试
 *
 * 覆盖 useWorkbenchStore 的状态管理逻辑：
 * - 初始状态值
 * - selectTask / setTab：任务选择与标签切换
 * - refreshTasks：加载任务列表（pending / completed）
 * - refreshStats：加载统计信息
 * - completeTask：完成任务并自动选中下一个
 * - 错误处理（API 失败）
 */
import { describe, it, expect, vi, beforeEach } from 'vitest';

// ---------------------------------------------------------------------------
// Mock 外部依赖
// ---------------------------------------------------------------------------

const mockList = vi.fn();
const mockStats = vi.fn();

vi.mock('../api/health/actionInbox', () => ({
  actionInboxApi: {
    list: (...args: unknown[]) => mockList(...args),
    stats: (...args: unknown[]) => mockStats(...args),
  },
}));

import { useWorkbenchStore } from './workbenchStore';
import type { ActionItem, WorkbenchStats } from '../api/health/actionInbox';

// ---------------------------------------------------------------------------
// 测试辅助函数
// ---------------------------------------------------------------------------

function createFakeAction(overrides: Partial<ActionItem> = {}): ActionItem {
  return {
    id: 'action-001',
    action_type: 'alert',
    priority: 'high',
    status: 'pending',
    title: '高血压告警',
    summary: '患者血压异常升高',
    patient_id: 'patient-001',
    patient_name: '张三',
    source_ref: 'ref-001',
    created_at: '2026-05-01T08:00:00Z',
    updated_at: '2026-05-01T08:00:00Z',
    ...overrides,
  };
}

function createFakeStats(overrides: Partial<WorkbenchStats> = {}): WorkbenchStats {
  return {
    total_pending: 5,
    ai_suggestion_pending: 2,
    urgent_alerts: 1,
    followup_due: 3,
    completion_rate: 0.75,
    ...overrides,
  };
}

// ---------------------------------------------------------------------------
// 测试套件
// ---------------------------------------------------------------------------

describe('useWorkbenchStore', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    useWorkbenchStore.setState({
      tasks: [],
      selectedTaskId: null,
      tab: 'pending',
      loading: false,
      stats: null,
    });
  });

  // =========================================================================
  // 初始状态
  // =========================================================================
  describe('初始状态', () => {
    it('应有正确的默认状态字段', () => {
      const state = useWorkbenchStore.getState();
      expect(state).toHaveProperty('tasks');
      expect(state).toHaveProperty('selectedTaskId');
      expect(state).toHaveProperty('tab');
      expect(state).toHaveProperty('loading');
      expect(state).toHaveProperty('stats');
      expect(state).toHaveProperty('selectTask');
      expect(state).toHaveProperty('setTab');
      expect(state).toHaveProperty('refreshTasks');
      expect(state).toHaveProperty('refreshStats');
      expect(state).toHaveProperty('completeTask');
    });

    it('默认值应为空和未选中', () => {
      const state = useWorkbenchStore.getState();
      expect(state.tasks).toEqual([]);
      expect(state.selectedTaskId).toBeNull();
      expect(state.tab).toBe('pending');
      expect(state.loading).toBe(false);
      expect(state.stats).toBeNull();
    });
  });

  // =========================================================================
  // selectTask
  // =========================================================================
  describe('selectTask', () => {
    it('应更新 selectedTaskId', () => {
      useWorkbenchStore.getState().selectTask('action-001');
      expect(useWorkbenchStore.getState().selectedTaskId).toBe('action-001');
    });

    it('应允许设为 null 以取消选择', () => {
      useWorkbenchStore.setState({ selectedTaskId: 'action-001' });
      useWorkbenchStore.getState().selectTask(null);
      expect(useWorkbenchStore.getState().selectedTaskId).toBeNull();
    });

    it('切换选中不应影响其他状态', () => {
      const fakeTask = createFakeAction();
      useWorkbenchStore.setState({ tasks: [fakeTask], tab: 'completed' });
      useWorkbenchStore.getState().selectTask('action-001');
      expect(useWorkbenchStore.getState().tasks).toEqual([fakeTask]);
      expect(useWorkbenchStore.getState().tab).toBe('completed');
    });
  });

  // =========================================================================
  // setTab
  // =========================================================================
  describe('setTab', () => {
    it('应更新 tab 并清空 selectedTaskId', async () => {
      useWorkbenchStore.setState({ selectedTaskId: 'action-001', tab: 'pending' });
      mockList.mockResolvedValueOnce({ data: [] });

      useWorkbenchStore.getState().setTab('completed');

      expect(useWorkbenchStore.getState().tab).toBe('completed');
      expect(useWorkbenchStore.getState().selectedTaskId).toBeNull();
    });

    it('切换 tab 时应自动触发 refreshTasks', async () => {
      const fakeTasks = [createFakeAction({ status: 'completed' })];
      mockList.mockResolvedValueOnce({ data: fakeTasks });

      useWorkbenchStore.getState().setTab('completed');

      // 等待异步操作完成
      await vi.waitFor(() => {
        expect(useWorkbenchStore.getState().loading).toBe(false);
      });

      expect(mockList).toHaveBeenCalledWith({
        status: 'completed',
        page: 1,
        page_size: 50,
      });
      expect(useWorkbenchStore.getState().tasks).toEqual(fakeTasks);
    });

    it('切换到 pending tab 应传递 pending status', async () => {
      mockList.mockResolvedValueOnce({ data: [] });

      useWorkbenchStore.getState().setTab('pending');

      await vi.waitFor(() => {
        expect(useWorkbenchStore.getState().loading).toBe(false);
      });

      expect(mockList).toHaveBeenCalledWith({
        status: 'pending',
        page: 1,
        page_size: 50,
      });
    });
  });

  // =========================================================================
  // refreshTasks
  // =========================================================================
  describe('refreshTasks', () => {
    it('成功时应更新 tasks', async () => {
      const fakeTasks = [
        createFakeAction({ id: 'a1' }),
        createFakeAction({ id: 'a2', title: 'AI 建议' }),
      ];
      mockList.mockResolvedValueOnce({ data: fakeTasks });

      await useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().tasks).toEqual(fakeTasks);
    });

    it('加载中 loading 应为 true，完成后恢复为 false', async () => {
      let resolveList: (value: unknown) => void;
      const listPromise = new Promise((resolve) => {
        resolveList = resolve;
      });
      mockList.mockReturnValue(listPromise);

      const refreshPromise = useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().loading).toBe(true);

      resolveList!({ data: [] });
      await refreshPromise;

      expect(useWorkbenchStore.getState().loading).toBe(false);
    });

    it('应传递当前 tab 的 status 参数', async () => {
      mockList.mockResolvedValueOnce({ data: [] });

      useWorkbenchStore.setState({ tab: 'completed' });
      await useWorkbenchStore.getState().refreshTasks();

      expect(mockList).toHaveBeenCalledWith({
        status: 'completed',
        page: 1,
        page_size: 50,
      });
    });

    it('API 返回非数组数据时 tasks 应为空数组', async () => {
      mockList.mockResolvedValueOnce({ data: null });

      await useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().tasks).toEqual([]);
    });

    it('API 返回 undefined data 时 tasks 应为空数组', async () => {
      mockList.mockResolvedValueOnce(undefined);

      await useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().tasks).toEqual([]);
    });

    it('API 失败时应恢复 loading 为 false', async () => {
      mockList.mockRejectedValueOnce(new Error('network error'));

      await useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().loading).toBe(false);
    });

    it('API 失败时不应清空已有 tasks', async () => {
      const existingTasks = [createFakeAction()];
      useWorkbenchStore.setState({ tasks: existingTasks });
      mockList.mockRejectedValueOnce(new Error('network error'));

      await useWorkbenchStore.getState().refreshTasks();

      // 失败时 set 只重置了 loading，未更新 tasks
      // 但注意：代码中 catch 块只 set({ loading: false })，不修改 tasks
      // 不过 loading: true 已经在前面 set 了，这里 tasks 在成功路径才会被替换
      // 由于代码是 try/catch/finally 模式，catch 中 tasks 不会被覆盖
      expect(useWorkbenchStore.getState().loading).toBe(false);
    });
  });

  // =========================================================================
  // refreshStats
  // =========================================================================
  describe('refreshStats', () => {
    it('成功时应更新 stats', async () => {
      const fakeStats = createFakeStats();
      mockStats.mockResolvedValueOnce(fakeStats);

      await useWorkbenchStore.getState().refreshStats();

      expect(useWorkbenchStore.getState().stats).toEqual(fakeStats);
    });

    it('API 返回 null 时 stats 应为 null', async () => {
      mockStats.mockResolvedValueOnce(null);

      await useWorkbenchStore.getState().refreshStats();

      expect(useWorkbenchStore.getState().stats).toBeNull();
    });

    it('API 失败时 stats 应保持不变', async () => {
      const existingStats = createFakeStats();
      useWorkbenchStore.setState({ stats: existingStats });
      mockStats.mockRejectedValueOnce(new Error('server error'));

      await useWorkbenchStore.getState().refreshStats();

      expect(useWorkbenchStore.getState().stats).toEqual(existingStats);
    });

    it('API 失败时不应抛出异常', async () => {
      mockStats.mockRejectedValueOnce(new Error('timeout'));

      await expect(
        useWorkbenchStore.getState().refreshStats(),
      ).resolves.toBeUndefined();
    });
  });

  // =========================================================================
  // completeTask
  // =========================================================================
  describe('completeTask', () => {
    it('应从 tasks 中移除指定 id', () => {
      const task1 = createFakeAction({ id: 'a1' });
      const task2 = createFakeAction({ id: 'a2' });
      useWorkbenchStore.setState({ tasks: [task1, task2] });

      useWorkbenchStore.getState().completeTask('a1');

      expect(useWorkbenchStore.getState().tasks).toEqual([task2]);
    });

    it('应自动选中下一个任务', () => {
      const task1 = createFakeAction({ id: 'a1' });
      const task2 = createFakeAction({ id: 'a2' });
      const task3 = createFakeAction({ id: 'a3' });
      useWorkbenchStore.setState({ tasks: [task1, task2, task3], selectedTaskId: 'a2' });

      useWorkbenchStore.getState().completeTask('a2');

      // 移除 a2 后剩余 [a1, a3]，下一个选中 a1
      expect(useWorkbenchStore.getState().selectedTaskId).toBe('a1');
    });

    it('无剩余任务时 selectedTaskId 应为 null', () => {
      const task1 = createFakeAction({ id: 'a1' });
      useWorkbenchStore.setState({ tasks: [task1], selectedTaskId: 'a1' });

      useWorkbenchStore.getState().completeTask('a1');

      expect(useWorkbenchStore.getState().tasks).toEqual([]);
      expect(useWorkbenchStore.getState().selectedTaskId).toBeNull();
    });

    it('完成后应自动刷新 stats', async () => {
      const fakeStats = createFakeStats({ total_pending: 4 });
      mockStats.mockResolvedValueOnce(fakeStats);

      const task1 = createFakeAction({ id: 'a1' });
      useWorkbenchStore.setState({ tasks: [task1] });
      useWorkbenchStore.getState().completeTask('a1');

      // 等待异步 refreshStats 完成
      await vi.waitFor(() => {
        expect(mockStats).toHaveBeenCalledTimes(1);
      });

      expect(useWorkbenchStore.getState().stats).toEqual(fakeStats);
    });

    it('移除不存在的 id 不应影响 tasks', () => {
      const task1 = createFakeAction({ id: 'a1' });
      useWorkbenchStore.setState({ tasks: [task1] });

      useWorkbenchStore.getState().completeTask('nonexistent');

      expect(useWorkbenchStore.getState().tasks).toEqual([task1]);
    });
  });

  // =========================================================================
  // 边界情况
  // =========================================================================
  describe('边界情况', () => {
    it('快速连续 selectTask 应反映最后设置的值', () => {
      useWorkbenchStore.getState().selectTask('a1');
      useWorkbenchStore.getState().selectTask('a2');
      useWorkbenchStore.getState().selectTask('a3');

      expect(useWorkbenchStore.getState().selectedTaskId).toBe('a3');
    });

    it('stats 含 null completion_rate 时应正确存储', async () => {
      const statsWithNull = createFakeStats({ completion_rate: null });
      mockStats.mockResolvedValueOnce(statsWithNull);

      await useWorkbenchStore.getState().refreshStats();

      expect(useWorkbenchStore.getState().stats!.completion_rate).toBeNull();
    });

    it('completeTask 后再 refreshTasks 应正常加载新列表', async () => {
      const task1 = createFakeAction({ id: 'a1' });
      const task2 = createFakeAction({ id: 'a2' });
      useWorkbenchStore.setState({ tasks: [task1, task2] });

      useWorkbenchStore.getState().completeTask('a1');
      expect(useWorkbenchStore.getState().tasks).toEqual([task2]);

      const newTasks = [createFakeAction({ id: 'a3' }), createFakeAction({ id: 'a4' })];
      mockList.mockResolvedValueOnce({ data: newTasks });
      mockStats.mockResolvedValueOnce(createFakeStats());

      await useWorkbenchStore.getState().refreshTasks();

      expect(useWorkbenchStore.getState().tasks).toEqual(newTasks);
    });
  });
});
