// src/models/chat-history.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved

import { Types, Schema, Document, model } from "mongoose";

import { IChatSession, ChatSessionMode } from "./chat-session.js";
import { IUser } from "./user.js";

export enum ChatHistoryStatus {
  Processing = "processing",
  Success = "success",
  Failed = "failed",
}
export interface IChatToolCallParameter {
  name: string;
  value: string;
}
export const ChatToolCallParameterSchema = new Schema<IChatToolCallParameter>(
  {
    name: { type: String, required: true },
    value: { type: String, required: true },
  },
  { _id: false },
);

export interface IChatFileOperation {
  type: "read" | "write" | "edit" | "shell";
  path?: string;
  diff?: string;
  linesAdded?: number;
  linesRemoved?: number;
  isBinary?: boolean;
}

export interface IChatToolCall {
  tool: {
    name: string;
    callId: string;
    parameters: IChatToolCallParameter[];
  };
  response: string;
  fileOperation?: IChatFileOperation;
  subagentStats?: {
    inputTokens: number;
    outputTokens: number;
    toolCallCount: number;
  };
}
const ChatFileOperationSchema = new Schema<IChatFileOperation>(
  {
    type: {
      type: String,
      required: true,
      enum: ["read", "write", "edit", "shell"],
    },
    path: { type: String },
    diff: { type: String },
    linesAdded: { type: Number },
    linesRemoved: { type: Number },
    isBinary: { type: Boolean },
  },
  { _id: false },
);

const SubagentStatsSchema = new Schema(
  {
    inputTokens: { type: Number },
    outputTokens: { type: Number },
    toolCallCount: { type: Number },
  },
  { _id: false },
);

export const ChatToolCallSchema = new Schema<IChatToolCall>({
  tool: {
    name: { type: String, required: true },
    callId: { type: String, required: true },
    parameters: {
      type: [ChatToolCallParameterSchema],
      default: [],
      required: true,
    },
  },
  response: { type: String },
  fileOperation: { type: ChatFileOperationSchema },
  subagentStats: { type: SubagentStatsSchema },
});

export interface IChatHistoryError {
  message: string;
  stack?: string;
  timestamp: Date;
}

export interface IChatHistory extends Document {
  createdAt: Date;
  user: IUser | Types.ObjectId;
  session: IChatSession | Types.ObjectId;
  prompt: string;
  mode: ChatSessionMode;
  status: ChatHistoryStatus;
  toolCalls: IChatToolCall[];
  fileOperations: IChatFileOperation[];
  response: {
    thinking?: string;
    message?: string;
  };
  qdrantId?: string;
  isSubagent?: boolean;
  error?: IChatHistoryError;
  subagentHistory?: IChatHistory[]; // For sub-agents, reference to their own history entries
  inputTokens: number;
  outputTokens: number;
}

export const ChatHistorySchema = new Schema<IChatHistory>({
  createdAt: { type: Date, default: Date.now, required: true },
  user: { type: Types.ObjectId, required: true, ref: "User" },
  session: { type: Types.ObjectId, required: true, ref: "ChatSession" },
  prompt: { type: String, required: true },
  mode: { type: String, enum: ChatSessionMode, required: true },
  toolCalls: { type: [ChatToolCallSchema], default: [], required: true },
  fileOperations: {
    type: [ChatFileOperationSchema],
    default: [],
    required: true,
  },
  response: {
    thinking: { type: String },
    message: { type: String },
  },
  qdrantId: { type: String },
  status: {
    type: String,
    enum: ChatHistoryStatus,
    default: ChatHistoryStatus.Processing,
  },
  isSubagent: { type: Boolean, default: false },
  error: {
    message: { type: String },
    stack: { type: String },
    timestamp: { type: Date },
  },
  subagentHistory: [{ type: Schema.Types.ObjectId, ref: "ChatHistory" }],
  inputTokens: { type: Number, default: 0 },
  outputTokens: { type: Number, default: 0 },
});

export const ChatHistory = model<IChatHistory>(
  "ChatHistory",
  ChatHistorySchema,
);
export default ChatHistory;

// Note: Index synchronization is now handled during application startup
// to ensure the database connection is established first.
// See src/lib/db.ts for the syncDatabaseIndexes function.
