import { Type } from "@sinclair/typebox";
import { forcedToolCall } from "../../../src/agents/llm-tools/forced-tool-call.js";
import type { ComplaintResult, ComplaintHistoryEntry } from "./types.js";

const ComplaintSchema = Type.Object({
  is_complaint: Type.Boolean(),
  severity: Type.Union([Type.Literal("low"), Type.Literal("med"), Type.Literal("high")]),
  category: Type.Union([
    Type.Literal("product_defect"),
    Type.Literal("billing"),
    Type.Literal("delivery"),
    Type.Literal("service"),
    Type.Literal("other"),
  ]),
  summary: Type.String(),
});

const SYSTEM_PROMPT_BASE = `You are a customer-complaint classifier.
The conversation history below is the most recent context from this customer (oldest first).
Classify whether the LATEST message (the final entry in the history) indicates a genuine new or escalated complaint.

Hard rules:
- The LATEST message is what you classify. Use prior history only to disambiguate that message.
- If the LATEST message is short, vague, a single character, a typo, a greeting, a question, or general chit-chat, it is NOT a complaint — even if earlier messages in the history were complaints.
- Do NOT re-classify an older complaint just because it appears in the context window.
- For an existing complaint thread, only flag a NEW classification if the LATEST message escalates the issue (e.g. "it exploded", "I'm calling my lawyer") or introduces a new grievance.
- Call the result tool exactly once.`;

const LANGUAGE_HINT: Record<"es" | "en", string> = {
  es: 'Write the "summary" field in Spanish (one short sentence summarizing the complaint).',
  en: 'Write the "summary" field in English (one short sentence summarizing the complaint).',
};

function renderHistory(history: ComplaintHistoryEntry[]): string {
  return history
    .map((h) => `[${h.role}] ${h.content}`)
    .join("\n");
}

export async function classifyMessage(
  history: ComplaintHistoryEntry[],
  apiKey: string,
  model: string,
  signal?: AbortSignal,
  language: "es" | "en" = "es",
): Promise<ComplaintResult> {
  const prompt = `${SYSTEM_PROMPT_BASE}\n${LANGUAGE_HINT[language]}\n\nConversation history:\n${renderHistory(history)}`;
  const raw = await forcedToolCall(prompt, ComplaintSchema, {
    apiKey,
    model,
    toolName: "result",
    toolChoice: { type: "tool", name: "result" },
    maxTokens: 256,
    signal,
  });
  return {
    is_complaint: Boolean(raw.is_complaint),
    severity: raw.severity as ComplaintResult["severity"],
    category: raw.category as ComplaintResult["category"],
    summary: String(raw.summary),
  };
}
