import { Injectable } from '@nestjs/common';
import { AgentScratchpadService } from '../scratchpad/scratchpad.service';
import type { AgentTool, ToolDescriptor, ToolInvocation, ToolResult } from './tool.types';

/**
 * PR8b scratchpad_read / scratchpad_write —— 把 AgentScratchpad 暴露给 agent。
 *
 * sub-agent 把中间数据存这里，主 agent 后续 turn 读，不必从外部重拉。
 * 隔离：service 层 organizationId 过滤；ToolInvocation 自带 orgId。
 */

@Injectable()
export class ScratchpadReadTool implements AgentTool {
  constructor(private readonly scratchpad: AgentScratchpadService) {}

  readonly descriptor: ToolDescriptor = {
    name: 'scratchpad_read',
    description: '读 session 草稿本里某个 key 的内容（跨 turn 持久）。返回 value 或 null。',
    inputSchema: {
      key: { type: 'string', required: true, description: '草稿键名（5-100 字符）' },
    },
    availability: { surface: ['web', 'desktop', 'mobile', 'teams', 'cli'] },
  };

  async invoke(inv: ToolInvocation): Promise<ToolResult> {
    const key = String(inv.input.key ?? '').trim();
    if (!key) return { ok: false, errorMessage: 'key 必填' };
    if (!inv.sessionId) return { ok: false, errorMessage: 'sessionId 必填（scratchpad 按 session 隔离）' };
    const value = await this.scratchpad.get({
      organizationId: inv.organizationId,
      sessionId: inv.sessionId,
      key,
    });
    return { ok: true, output: { key, value } };
  }
}

@Injectable()
export class ScratchpadWriteTool implements AgentTool {
  constructor(private readonly scratchpad: AgentScratchpadService) {}

  readonly descriptor: ToolDescriptor = {
    name: 'scratchpad_write',
    description:
      '写 session 草稿本：upsert (key, value)，跨 turn 持久。value 是任意 JSON 序列化字符串。',
    inputSchema: {
      key: { type: 'string', required: true, description: '草稿键名（5-100 字符）' },
      value: {
        type: 'string',
        required: true,
        description: 'JSON 字符串。若不是合法 JSON，按裸字符串落库',
      },
    },
    availability: { surface: ['web', 'desktop', 'mobile', 'teams', 'cli'] },
    writeAction: true,
  };

  async invoke(inv: ToolInvocation): Promise<ToolResult> {
    const key = String(inv.input.key ?? '').trim();
    const raw = String(inv.input.value ?? '');
    if (!key || raw === '') return { ok: false, errorMessage: 'key 和 value 必填' };
    if (!inv.sessionId) return { ok: false, errorMessage: 'sessionId 必填' };
    let parsed: unknown = raw;
    try {
      parsed = JSON.parse(raw);
    } catch {
      // 非合法 JSON 时按字符串落库（agent 写人话也接受）
    }
    const row = await this.scratchpad.upsert({
      organizationId: inv.organizationId,
      sessionId: inv.sessionId,
      key,
      value: parsed,
    });
    return { ok: true, output: { key, updatedAt: row.updatedAt } };
  }
}
