import { Injectable, NotFoundException } from '@nestjs/common';
import { StudentsService } from '../../students/students.service';
import { StudentAccessScopeFactory } from '../../students/student-access-scope.factory';
import type { AgentToolContext, ToolDef, ToolInputResult } from '../agent-tool.types';

interface GetStudentBasicInput {
  studentId: number;
}

/** Forbidden input keys — if the model sends these, validation fails. */
const FORBIDDEN_INPUT_KEYS = new Set([
  'userId',
  'isSuperAdmin',
  'permissions',
  'roles',
  'ability',
  'user',
  'password',
  'token',
]);

@Injectable()
export class GetStudentBasicTool implements ToolDef<GetStudentBasicInput> {
  readonly inputSchema = {
    type: 'object',
    properties: {
      studentId: {
        type: 'integer',
        description: '学生ID',
        minimum: 1,
      },
    },
    required: ['studentId'],
    additionalProperties: false,
  };
  readonly name = 'get_student_basic';
  readonly description = '获取单个学生基本信息。仅返回基础公开字段。';
  readonly requiredPermission = 'student:view';

  constructor(
    private readonly studentsService: StudentsService,
    private readonly scopeFactory: StudentAccessScopeFactory,
  ) {}

  validate(input: Record<string, unknown>): ToolInputResult<GetStudentBasicInput> {
    for (const key of Object.keys(input)) {
      if (FORBIDDEN_INPUT_KEYS.has(key)) {
        return { ok: false, error: `不允许的输入字段: ${key}` };
      }
    }

    if (input.studentId === undefined) {
      return { ok: false, error: '缺少必填字段: studentId' };
    }

    const studentId = Number(input.studentId);
    if (!Number.isInteger(studentId) || studentId <= 0) {
      return { ok: false, error: 'studentId 必须是正整数' };
    }

    // Reject unexpected keys
    const allowedKeys = new Set(['studentId']);
    for (const key of Object.keys(input)) {
      if (!allowedKeys.has(key)) {
        return { ok: false, error: `不允许的输入字段: ${key}` };
      }
    }

    return { ok: true, value: { studentId } };
  }

  async execute(input: GetStudentBasicInput, context: AgentToolContext): Promise<unknown> {
    const scope = this.scopeFactory.buildScope(context);
    const result = await this.studentsService.agentGetStudentBasic(scope, input.studentId);

    if (result === null) {
      throw new NotFoundException('记录不存在或无权访问');
    }

    return result;
  }
}
