// src/tools/chat/summarize.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved

import type { ToolDefinition } from "../../lib/ai-client.js";
import type { IUser } from "../../models/user.js";

import {
  DtpTool,
  type ToolArguments,
  type ToolContext,
} from "../../lib/tool.js";
import { ChatHistory } from "../../models/chat-history.js";
import { ChatSession, ChatSessionMode } from "../../models/chat-session.js";
import AiService from "../../services/ai.js";

export class ChatSummarizeTool extends DtpTool {
  get name(): string {
    return "ChatSummarizeTool";
  }
  get slug(): string {
    return "chat-summarize";
  }
  get metadata() {
    return {
      name: this.definition.function.name || "chat_summarize",
      category: "chat",
      tags: ["summarize", "session", "overview", "recap"],
      modes: [
        ChatSessionMode.Plan,
        ChatSessionMode.Build,
        ChatSessionMode.Test,
        ChatSessionMode.Ship,
        ChatSessionMode.Develop,
      ],
    };
  }

  public definition: ToolDefinition = {
    type: "function",
    function: {
      name: "chat_summarize",
      description:
        "Summarize the conversation in the current or specified session. Returns a concise summary of the key topics, decisions, and outcomes discussed.",
      parameters: {
        type: "object",
        properties: {
          session_id: {
            type: "string",
            description:
              "Optional: Session ID to summarize. If omitted, summarizes the current session.",
          },
          max_length: {
            type: "number",
            description:
              "Optional: Maximum length of summary in words (default: 100).",
          },
        },
        required: [],
      },
    },
  };

  public async execute(
    context: ToolContext,
    args: ToolArguments,
  ): Promise<string> {
    const { session_id, max_length = 100 } = args;
    const user = context.session.user as IUser;
    const userId = user._id.toHexString();
    const currentSessionId = context.session._id.toHexString();

    const targetSessionId =
      (session_id as string | undefined) || currentSessionId;
    if (!targetSessionId) {
      return this.error(
        "MISSING_SESSION",
        "No session ID provided and no current session context.",
      );
    }

    try {
      const session = await ChatSession.findOne({
        _id: targetSessionId,
        user: userId,
      });

      if (!session) {
        return this.error(
          "NOT_FOUND",
          `Session not found: ${targetSessionId}`,
          {
            recoveryHint:
              "Verify the session ID exists and belongs to the current user.",
          },
        );
      }

      const history = await ChatHistory.find({
        session: targetSessionId,
        status: "success",
      })
        .sort({ createdAt: 1 })
        .lean();

      if (history.length === 0) {
        return this.success(
          { summary: "", turnCount: 0 },
          "No conversation history found in this session.",
        );
      }

      const conversationText = history
        .map((turn) => {
          let text = `User: ${turn.prompt}\n`;
          if (turn.response?.message) {
            text += `Assistant: ${turn.response.message}`;
          }
          return text;
        })
        .join("\n\n---\n\n");

      const summaryPrompt = `Summarize the following conversation in approximately ${max_length} words or less. Focus on the main topics discussed, any decisions made, and key outcomes. Be concise and factual.

Conversation:
${conversationText}`;

      this.log.debug("Generating summary", {
        sessionId: targetSessionId,
        turnCount: history.length,
        maxLength: max_length,
      });

      const utilityClient = await AiService.getUtilityClient(userId);
      const utilityModel = await AiService.getUtilityModel(userId);

      const response = await utilityClient.chat(
        [{ role: "user", content: summaryPrompt }],
        [],
        utilityModel,
      );

      const summary = response.content.trim();
      return this.success({ summary }, summary);
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : String(error);

      this.log.error("Failed to summarize session", {
        sessionId: targetSessionId,
        error: errorMessage,
      });

      return this.error(
        "OPERATION_FAILED",
        `Failed to generate summary: ${errorMessage}`,
        {
          recoveryHint:
            "Try again with a smaller max_length, or proceed without a summary.",
        },
      );
    }
  }
}

export default new ChatSummarizeTool();
