import { Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { NetaClawAgentService } from '../service/agent.js';
import { NetaClawModelChannelService } from '../service/model_channel.js';
import { SkillLoaderService } from '../service/skill_loader.js';
import { buildSystemPrompt } from '../runtime/prompt_builder.js';
import { NetaClawToolResolverService } from '../service/tool_resolver.js';

@Provide()
@Controller('/admin/netaclaw/agent')
export class NetaClawAgentAdminController {
  @Inject()
  ctx: Context;

  @Inject()
  agentService: NetaClawAgentService;

  @Inject()
  channelService: NetaClawModelChannelService;

  @Inject()
  skillLoader: SkillLoaderService;

  @Inject()
  toolResolver: NetaClawToolResolverService;

  @Post('/page')
  async page(@Body() body: { page?: number; size?: number; keyWord?: string }) {
    return { code: 1000, data: await this.agentService.page(body) };
  }

  @Post('/options')
  async options() {
    return { code: 1000, data: await this.agentService.publishedOptions() };
  }

  @Post('/add')
  async add(@Body() body: any) {
    return { code: 1000, data: await this.agentService.add(body) };
  }

  @Post('/update')
  async update(@Body() body: any) {
    await this.agentService.update(body);
    return { code: 1000, message: 'success' };
  }

  @Post('/delete')
  async delete(@Body() body: { ids: number[] }) {
    await this.agentService.delete(body.ids);
    return { code: 1000, message: 'success' };
  }

  @Get('/info')
  async info(@Query('id') id: number) {
    return { code: 1000, data: await this.agentService.info(id) };
  }

  @Post('/previewPrompt', { summary: '预览最终系统提示词' })
  async previewPrompt(@Body() body: {
    id?: number;
    name?: string;
    label?: string;
    description?: string;
    systemPrompt: string;
    skills: string[];
    toolsets?: string[];
    tools?: {
      inheritCoreTools?: boolean;
      enabled?: string[];
      disabled?: string[];
      perTool?: Record<string, {
        enabled?: boolean;
        promptHint?: string;
        allowInSubagent?: boolean;
        workerRoutingStrategy?: 'auto' | 'force-local' | 'force-main-process-proxy' | 'force-disabled';
      }>;
    };
    config?: Record<string, unknown>;
    modelConfig: { channelId?: number; modelId?: string };
  }) {
    let modelId = body.modelConfig?.modelId || 'unknown';
    let modelCapability: any = 'text';

    if (body.modelConfig?.channelId) {
      try {
        const resolved = await this.channelService.resolveForAgent(
          body.modelConfig.channelId,
          modelId
        );
        modelId = resolved.model;
        modelCapability = resolved.capability;
      } catch {
        // fall back to the raw model id
      }
    }

    const resolvedTools = await this.toolResolver.resolve({
      agent: {
        ...(body as any),
        skills: body.skills || [],
        toolsets: Array.isArray(body.toolsets) ? body.toolsets : null,
        tools: body.tools || {},
        config: body.config || {},
        modelConfig: body.modelConfig || {},
      } as any,
      modelCapability,
      memoryEnabled: !!(body.config as any)?.memory?.enabled,
      hasSkills: !!body.skills?.length,
    });

    const result = buildSystemPrompt({
      agentSystemPrompt: body.systemPrompt || '',
      modelId,
      availableToolNames: resolvedTools.toolNames,
      skills: body.skills || [],
      skillLoader: this.skillLoader,
      memoryEnabled: !!(body.config as any)?.memory?.enabled,
      toolPromptHints: resolvedTools.toolPromptHints,
    });

    return {
      code: 1000,
      data: {
        ...result,
        toolNames: resolvedTools.toolNames,
        disabledReasons: resolvedTools.disabledReasons,
      },
    };
  }
}

@Provide()
@Controller('/open/netaclaw/agent')
export class NetaClawAgentOpenController {
  @Inject()
  agentService: NetaClawAgentService;

  @Inject()
  channelService: NetaClawModelChannelService;

  @Post('/list')
  async list() {
    return { code: 1000, data: await this.agentService.publishedList() };
  }

  @Post('/thinkingCapability')
  async thinkingCapability(@Body() body: { agentId: number }) {
    if (!body.agentId) {
      return { code: 1000, data: { supported: false, adaptive: false, levels: ['off'], defaultLevel: 'off' } };
    }
    const agentInfo = await this.agentService.info(body.agentId);
    if (!agentInfo) {
      return { code: 1000, data: { supported: false, adaptive: false, levels: ['off'], defaultLevel: 'off' } };
    }
    const mc = (agentInfo.modelConfig || {}) as any;
    if (!mc.channelId || mc.channelId <= 0) {
      return { code: 1000, data: { supported: false, adaptive: false, levels: ['off'], defaultLevel: 'off' } };
    }
    try {
      const resolved = await this.channelService.resolveForAgent(mc.channelId, mc.modelId || '');
      let capability: any;
      if (!resolved.supportThinking) {
        capability = { supported: false, adaptive: false, levels: ['off'], defaultLevel: 'off' };
      } else if (!resolved.supportThinkingLevel) {
        capability = { supported: true, adaptive: false, levels: ['medium'], defaultLevel: 'medium' };
      } else {
        capability = { supported: true, adaptive: false, levels: ['off', 'low', 'medium', 'high'], defaultLevel: 'medium' };
      }
      return { code: 1000, data: capability };
    } catch {
      return { code: 1000, data: { supported: false, adaptive: false, levels: ['off'], defaultLevel: 'off' } };
    }
  }
}
