// src/models/chat-turn.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

import { Schema, model } from "mongoose";

import {
  ChatSessionMode,
  ChatTurnStatus,
  IChatTurnPrompts,
  IChatSubagentProcess,
  IChatToolCall,
  IChatTurn,
  IChatTurnStats,
  IChatTurnBlock,
} from "@gadget/api";
import { nanoid } from "nanoid";

export const ChatTurnPromptsSchema = new Schema<IChatTurnPrompts>({
  user: { type: String, required: true },
  system: { type: String, required: false },
});

export const ChatTurnStatsSchema = new Schema<IChatTurnStats>({
  toolCallCount: { type: Number, default: 0, required: true },
  inputTokens: { type: Number, default: 0, required: true },
  thinkingTokenCount: { type: Number, default: 0, required: true },
  responseTokens: { type: Number, default: 0, required: true },
  durationMs: { type: Number, default: 0, required: true },
  durationLabel: { type: String, default: "pending", required: true },
});

const ChatTurnBlockSchema = new Schema<IChatTurnBlock>({
  mode: { 
    type: String, 
    enum: ['thinking', 'responding', 'tool'], 
    required: true 
  },
  createdAt: { type: Date, default: Date.now, required: true },
  content: { type: Schema.Types.Mixed, required: true },
}, { _id: false });

export const ChatToolCallSchema = new Schema<IChatToolCall>({
  callId: { type: String, required: true },
  name: { type: String, required: true },
  parameters: { type: String, required: false },
  response: { type: String, required: false },
  subagent: { type: Schema.Types.Mixed, required: false } as any,
});

export const ChatSubagentProcessSchema = new Schema<IChatSubagentProcess>({
  prompt: { type: String, required: true },
  thinking: { type: String, required: false },
  response: { type: String, required: false },
  toolCalls: { type: [ChatToolCallSchema], default: [], required: true },
  stats: { type: ChatTurnStatsSchema, default: {}, required: true },
});

export const ChatTurnSchema = new Schema<IChatTurn>({
  _id: { type: String, default: () => nanoid() },
  createdAt: { type: Date, default: Date.now, required: true },
  user: { type: String, required: true, ref: "User" },
  project: { type: String, required: false, ref: "Project" },
  session: { type: String, required: true, ref: "ChatSession" },
  provider: { type: String, required: true, ref: "AiProvider" },
  llm: { type: String, required: true }, // id/name of the model used to process the prompt
  reasoningEffort: {
    type: String,
    enum: ["off", "low", "medium", "high"],
    default: "off",
  },
  numCtx: { type: Number },
  mode: {
    type: String,
    enum: ChatSessionMode,
    default: ChatSessionMode.Build,
    required: true,
  },
  status: {
    type: String,
    enum: ChatTurnStatus,
    default: ChatTurnStatus.Processing,
    required: true,
  },
  prompts: { type: ChatTurnPromptsSchema, required: true },
  blocks: { type: [ChatTurnBlockSchema], default: [], required: true },
  errorMessage: { type: String, required: false },
  toolCalls: { type: [ChatToolCallSchema], default: [], required: true },
  subagents: { type: [ChatSubagentProcessSchema], default: [], required: true },
  stats: {
    toolCallCount: { type: Number, default: 0, required: true },
    inputTokens: { type: Number, default: 0, required: true },
    thinkingTokenCount: { type: Number, default: 0, required: true },
    responseTokens: { type: Number, default: 0, required: true },
    durationMs: { type: Number, default: 0, required: true },
    durationLabel: { type: String, default: "pending", required: true },
  },
});

ChatTurnSchema.index(
  {
    user: 1,
    project: 1,
    session: 1,
  },
  {
    name: "chat-turn-user-project-session-index",
  },
);

ChatTurnSchema.index(
  {
    user: 1,
    "prompts.user": "text",
    "prompts.system": "text",
  },
  {
    weights: {
      "prompts.user": 10,
      "prompts.system": 5,
    },
    name: "chat-turn-user-text-index",
  },
);

export const ChatTurn = model<IChatTurn>("ChatTurn", ChatTurnSchema);
export default ChatTurn;
