import { Injectable } from "@nestjs/common";
import type { Prisma } from "@prisma/client";
import { KillswitchService } from "../../killswitch/killswitch.service";
import { PrismaService } from "../../prisma/prisma.service";

@Injectable()
export class AgentControlService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly killswitchService: KillswitchService
  ) {}

  private toJsonValue(value: Record<string, unknown>): Prisma.InputJsonValue {
    return value as Prisma.InputJsonValue;
  }

  private async createOperatorAuditLog(
    agentId: string,
    operatorId: string,
    action: "inject" | "pause" | "resume" | "kill",
    payload: Record<string, unknown>
  ): Promise<void> {
    await this.prisma.operatorAuditLog.create({
      data: {
        sessionId: agentId,
        userId: operatorId,
        provider: "internal",
        action,
        metadata: this.toJsonValue({ payload }),
      },
    });
  }

  async injectMessage(agentId: string, operatorId: string, message: string): Promise<void> {
    const treeEntry = await this.prisma.agentSessionTree.findUnique({
      where: { sessionId: agentId },
      select: { id: true },
    });

    if (treeEntry) {
      await this.prisma.agentConversationMessage.create({
        data: {
          sessionId: agentId,
          role: "operator",
          content: message,
          provider: "internal",
          metadata: this.toJsonValue({}),
        },
      });
    }

    await this.createOperatorAuditLog(agentId, operatorId, "inject", { message });
  }

  async pauseAgent(agentId: string, operatorId: string): Promise<void> {
    await this.prisma.agentSessionTree.updateMany({
      where: { sessionId: agentId },
      data: { status: "paused" },
    });

    await this.createOperatorAuditLog(agentId, operatorId, "pause", {});
  }

  async resumeAgent(agentId: string, operatorId: string): Promise<void> {
    await this.prisma.agentSessionTree.updateMany({
      where: { sessionId: agentId },
      data: { status: "running" },
    });

    await this.createOperatorAuditLog(agentId, operatorId, "resume", {});
  }

  async killAgent(agentId: string, operatorId: string, force = true): Promise<void> {
    await this.killswitchService.killAgent(agentId);
    await this.createOperatorAuditLog(agentId, operatorId, "kill", { force });
  }
}
