import { Type } from '@sinclair/typebox';
import { AgentToolWithMeta, imagesResult, textResult, type ImageItem } from '../common.js';
import { SkillExecutorService } from '../../service/skill_executor.js';
import { registerSchema } from '../catalog.js';

const ExecuteSkillParams = Type.Object({
  name: Type.String({ description: 'compute-entry skill 名称' }),
  input: Type.Record(Type.String(), Type.Unknown(), { description: '输入参数 JSON' }),
});

export function createExecuteSkillTool(executor: SkillExecutorService): AgentToolWithMeta<typeof ExecuteSkillParams, unknown> {
  return {
    name: 'execute_skill',
    label: '执行 Skill',
    description: '执行 compute-entry 类型的 skill。传入 skill 名称和输入参数，返回执行结果。',
    parameters: ExecuteSkillParams,
    async execute(id, params, onUpdate) {
      const result = await executor.execute({
        skillName: params.name,
        input: params.input as Record<string, unknown>,
        toolCallId: id,
        onProcessEvent: event => {
          try {
            onUpdate?.({
              ...event,
              source: 'skill',
              targetType: 'skill',
              payload: {
                ...(event.payload || {}),
                skillName: params.name,
              },
            });
          } catch {
            // Process updates are observational only.
          }
        },
      });
      if (result.success) {
        const text = buildSkillResultText(params.name, result.output);
        const images = extractSkillImages(result.output);
        if (images.length > 0) {
          return imagesResult(images, text);
        }
        return textResult(text);
      } else {
        return textResult(`执行失败: ${result.error}`);
      }
    },
  };
}

function buildSkillResultText(skillName: string, output: Record<string, unknown> | undefined): string {
  if (!output || typeof output !== 'object') {
    return JSON.stringify(output, null, 2);
  }
  if (skillName !== 'vehicle-damage-inspection') {
    return JSON.stringify(output, null, 2);
  }

  const finalResult = {
    summary: output.summary,
    vehicleInfo: output.vehicleInfo,
    damages: output.damages,
    uncertainDamages: output.uncertainDamages,
    bestFrameImages: output.bestFrameImages,
    reviewImages: output.reviewImages,
  };
  const payload = {
    success: output.success,
    taskId: output.taskId,
    finalResult,
    artifacts: output.artifacts,
  };

  return [
    `Skill ${skillName} 执行完成。`,
    '请只依据 finalResult.damages、finalResult.uncertainDamages、finalResult.bestFrameImages、finalResult.reviewImages 和 finalResult.summary 回答用户。',
    'damages 是已确认旧伤；uncertainDamages 是放大后仍无法明确确认的疑似旧伤，需要提示人工复核，不能说成已确认旧伤。',
    'reviewImages 是模型不清楚时生成的放大复核图；如存在，请说明“模型不清楚，已放大后判断”，并把图片返回给前端展示。',
    'candidates 是已复核前的中间候选，不代表最终旧伤，不要把 candidates 当成检测结论。',
    JSON.stringify(payload, null, 2),
  ].join('\n');
}

function extractSkillImages(output: Record<string, unknown> | undefined): ImageItem[] {
  const values = [
    ...(Array.isArray(output?.bestFrameImages) ? output.bestFrameImages : []),
    ...(Array.isArray(output?.reviewImages) ? output.reviewImages : []),
  ];
  if (!Array.isArray(values)) return [];

  return values
    .map((item): ImageItem | null => {
      if (!item || typeof item !== 'object') return null;
      const source = item as Record<string, unknown>;
      if (typeof source.url !== 'string' || source.url.length === 0) return null;
      return {
        url: source.url,
        ...(typeof source.mimeType === 'string' ? { mimeType: source.mimeType } : {}),
        ...(typeof source.label === 'string' ? { label: source.label } : {}),
        ...(typeof source.purpose === 'string' ? { purpose: source.purpose } : {}),
        ...(typeof source.reason === 'string' ? { reason: source.reason } : {}),
        ...(typeof source.damageId === 'string' ? { damageId: source.damageId } : {}),
        ...(typeof source.timestamp === 'number' ? { timestamp: source.timestamp } : {}),
        ...(typeof source.width === 'number' ? { width: source.width } : {}),
        ...(typeof source.height === 'number' ? { height: source.height } : {}),
      };
    })
    .filter((item): item is ImageItem => item !== null);
}

registerSchema({
  name: 'execute_skill',
  toolset: 'skill',
  description: '执行 compute-entry 类型的技能',
  capability: 'text',
  visibility: 'skill',
});
