import { Injectable } from '@nestjs/common';
import type { AgentToolContext, ToolDef, ToolInputResult } from '../agent-tools/agent-tool.types';
import { rejectUnknownKeys, optionalString } from '../agent-tools/tools/tool-input';
import { BusinessContextService } from './business-context.service';

interface GetBusinessContextInput {
  workflowKey?: string;
}

/**
 * 让 Agent 获取当前角色可见的业务流程、实体字典与依赖规则。
 */
@Injectable()
export class GetBusinessContextTool implements ToolDef<GetBusinessContextInput> {
  readonly name = 'get_business_context';
  readonly skillKey = 'assistant';
  readonly requiredPermission = 'ai:chat:use';
  readonly description =
    '获取当前账号可见的业务流程（学生教学/住宿计费/教室租赁）、实体字典、阶段依赖与下一步建议。写入或导入前先调用本工具确认前置数据要求。';
  readonly inputSchema = {
    type: 'object',
    properties: {
      workflowKey: {
        type: 'string',
        description: '可选：聚焦某个闭环（student_teaching / dormitory_billing / classroom_rental）',
        maxLength: 50,
      },
    },
    additionalProperties: false,
  };

  constructor(private readonly service: BusinessContextService) {}

  validate(input: Record<string, unknown>): ToolInputResult<GetBusinessContextInput> {
    const invalid = rejectUnknownKeys(input, ['workflowKey']);
    if (invalid) return invalid;
    const workflowKey = optionalString(input.workflowKey, 'workflowKey', 50);
    if (!workflowKey.ok) return workflowKey;
    return { ok: true, value: { workflowKey: workflowKey.value } };
  }

  async execute(input: GetBusinessContextInput, context: AgentToolContext): Promise<unknown> {
    return this.service.getBusinessContext(
      { permissions: context.permissions, isSuperAdmin: context.isSuperAdmin },
      input.workflowKey,
    );
  }
}

/**
 * 让 Agent 获取指定业务实体的字段字典与关系，用于生成准确表单。
 */
@Injectable()
export class GetEntitySchemaTool implements ToolDef<{ entityKey: string }> {
  readonly name = 'get_entity_schema';
  readonly skillKey = 'assistant';
  readonly requiredPermission = 'ai:chat:use';
  readonly description =
    '获取指定业务实体（student/class/room/occupancy/expense/bill/deposit/classroom/organization/rental 等）的字段字典、枚举来源与关系，render_form 前可按需调用以生成正确字段。';
  readonly inputSchema = {
    type: 'object',
    properties: {
      entityKey: { type: 'string', minLength: 1, maxLength: 50 },
    },
    required: ['entityKey'],
    additionalProperties: false,
  };

  constructor(private readonly service: BusinessContextService) {}

  validate(input: Record<string, unknown>): ToolInputResult<{ entityKey: string }> {
    const invalid = rejectUnknownKeys(input, ['entityKey']);
    if (invalid) return invalid;
    if (typeof input.entityKey !== 'string' || !input.entityKey.trim()) {
      return { ok: false, error: 'entityKey 必须是字符串' };
    }
    const entityKey = input.entityKey.trim();
    if (entityKey.length > 50) {
      return { ok: false, error: 'entityKey 长度不能超过 50' };
    }
    return { ok: true, value: { entityKey } };
  }

  async execute(input: { entityKey: string }, context: AgentToolContext): Promise<unknown> {
    return this.service.getEntitySchema(
      { permissions: context.permissions, isSuperAdmin: context.isSuperAdmin },
      input.entityKey,
    );
  }
}
