import { Injectable } from '@nestjs/common';
import type { AiCall } from '../../ai-call.interface';
import type { SafetyRule } from '../../core/safety-gate.service';
import { DraftPersonaSummarySchema } from './schema';
import type { DraftPersonaSummaryInput, DraftPersonaSummaryOutput } from './input.types';
import {
  DRAFT_PERSONA_SUMMARY_PROMPT_VERSION,
  DRAFT_PERSONA_SUMMARY_SYSTEM,
  buildDraftPersonaSummaryPrompt,
} from './prompt';

const FORBIDDEN_PHRASES = ['一定能', '保证', '绝对', '百分百', '100%', '亲爱的'];

const safetyRules: ReadonlyArray<SafetyRule<DraftPersonaSummaryOutput>> = [
  {
    name: 'no_forbidden_phrases',
    severity: 'block',
    check(output) {
      const hit = FORBIDDEN_PHRASES.filter((p) => output.summary.includes(p));
      return { pass: hit.length === 0, message: hit.length > 0 ? `命中禁词: ${hit.join(',')}` : undefined };
    },
  },
];

/** LLM 失败 / safety 拒收时:用标签拼一句最朴素的概述。 */
function fallback(input: DraftPersonaSummaryInput): DraftPersonaSummaryOutput {
  const n = input.items.length;
  if (n === 0) return { summary: '暂无画像标签。' };
  const top = input.items.slice(0, 2).map((it) => it.value.split(/[·,，]/)[0]?.trim()).filter(Boolean);
  return { summary: `${top.join(' · ') || '画像'} 等 ${n} 项画像标签。` };
}

@Injectable()
export class DraftPersonaSummaryCall
  implements AiCall<DraftPersonaSummaryInput, DraftPersonaSummaryOutput>
{
  readonly kind = 'summary' as const;
  readonly callKey = 'draft_persona_summary';
  readonly promptVersion = DRAFT_PERSONA_SUMMARY_PROMPT_VERSION;
  readonly defaultModelId = 'qwen'; // 这类一句话摘要统一走 Qwen(qwen3.7-max)
  readonly outputSchema = DraftPersonaSummarySchema;
  readonly safetyRules = safetyRules;

  buildPrompt(input: DraftPersonaSummaryInput) {
    return {
      system: DRAFT_PERSONA_SUMMARY_SYSTEM,
      prompt: buildDraftPersonaSummaryPrompt(input),
    };
  }

  fallback(input: DraftPersonaSummaryInput): DraftPersonaSummaryOutput {
    return fallback(input);
  }
}
