import { describe, expect, it, jest } from '@jest/globals';
import type { AgentToolContext } from '../agent-tools/agent-tool.types';
import { AgentToolContextFactory } from '../agent-tools/agent-tool.types';
import type { AuthenticatedUser } from '../authorization';
import type { BusinessContextService } from './business-context.service';
import { GetBusinessContextTool, GetEntitySchemaTool } from './get-business-context.tool';
import { GetPendingTasksTool } from './get-pending-tasks.tool';

function context(permissions: string[] = []): AgentToolContext {
  const user: AuthenticatedUser = {
    id: 7,
    username: 'ops',
    permissions,
    isSuperAdmin: false,
    roles: [],
  };
  return AgentToolContextFactory.fromAuthenticatedUser(user);
}

describe('agent business context tools', () => {
  it('get_business_context 校验 workflowKey 并透传主体与过滤条件', async () => {
    const service = {
      getBusinessContext: jest.fn().mockReturnValue({ workflows: [], entities: [] }),
    } as unknown as BusinessContextService;
    const tool = new GetBusinessContextTool(service);
    expect(tool.requiredPermission).toBe('ai:chat:use');
    expect(tool.validate({ workflowKey: 123 }).ok).toBe(false);
    expect(tool.validate({ workflowKey: 'x'.repeat(51) }).ok).toBe(false);
    expect(tool.validate({ debug: true }).ok).toBe(false);
    const parsed = tool.validate({ workflowKey: 'dormitory_billing' });
    expect(parsed.ok).toBe(true);
    if (!parsed.ok) return;
    const ctx = context(['occupancy:view']);
    await tool.execute(parsed.value, ctx);
    expect(service.getBusinessContext).toHaveBeenCalledWith(
      { permissions: ['occupancy:view'], isSuperAdmin: false },
      'dormitory_billing',
    );
  });

  it('get_entity_schema 必须提供存在的 entityKey', async () => {
    const service = {
      getEntitySchema: jest.fn().mockReturnValue({ key: 'student', name: '学生档案' }),
    } as unknown as BusinessContextService;
    const tool = new GetEntitySchemaTool(service);
    expect(tool.validate({}).ok).toBe(false);
    expect(tool.validate({ entityKey: '' }).ok).toBe(false);
    expect(tool.validate({ entityKey: 'student', extra: 1 }).ok).toBe(false);
    const parsed = tool.validate({ entityKey: 'student' });
    expect(parsed.ok).toBe(true);
    if (!parsed.ok) return;
    await tool.execute(parsed.value, context());
    expect(service.getEntitySchema).toHaveBeenCalledWith(
      { permissions: [], isSuperAdmin: false },
      'student',
    );
  });

  it('get_pending_tasks 只接受已知工作流 key', async () => {
    const service = {
      getPendingTasks: jest.fn().mockResolvedValue([]),
    };
    const tool = new GetPendingTasksTool(service as never);
    expect(tool.requiredPermission).toBe('ai:chat:use');
    expect(tool.validate({ workflowKey: 'unknown_loop' }).ok).toBe(false);
    expect(tool.validate({ workflowKey: 'dormitory_billing', limit: 1 }).ok).toBe(false);
    const parsed = tool.validate({ workflowKey: 'dormitory_billing' });
    expect(parsed.ok).toBe(true);
    if (!parsed.ok) return;
    await tool.execute(parsed.value, context(['bill:view']));
    expect(service.getPendingTasks).toHaveBeenCalledWith(expect.anything(), 'dormitory_billing');
  });
});
