import { buildInstructions, shouldReplyInstructions } from "../instructions"
import {
  Agent,
  type AgentInputItem,
  type InputGuardrail,
  InputGuardrailTripwireTriggered,
  run,
  user,
} from "@openai/agents"
import { currentLocalTime } from "@workshop/shared/utils"
import { createInterface } from "node:readline/promises"

interface UserContext {
  name: string
  currentTime: string
  fetchTodos(): Promise<string[]>
}

const ask = async (prompt: string) => {
  const rl = createInterface({ input: process.stdin, output: process.stdout })
  const message = await rl.question(prompt)
  rl.close()
  return message
}

const guardrailAgent = new Agent({
  name: "'Should Reply' check",
  model: "gpt-4.1-nano",
  instructions: shouldReplyInstructions(),
  modelSettings: { maxTokens: 16 },
})

const responseGuardrail: InputGuardrail = {
  name: "'Should Reply' guardrail",
  execute: async ({ input, context }) => {
    const result = await run(guardrailAgent, input.slice(-10), { context })

    return {
      outputInfo: result.finalOutput,
      tripwireTriggered: result.finalOutput?.match(/0/) ? true : false,
    }
  },
}

const agent = new Agent<UserContext>({
  name: "Spike",
  model: "gpt-4.1",
  instructions: ({ context }) => buildInstructions(context.name, context.currentTime),
  inputGuardrails: [responseGuardrail],
})

let history: AgentInputItem[] = []

const main = async () => {
  while (true) {
    const message = await ask("\n\n> ")
    history.push(user(message))

    try {
      const context: UserContext = {
        name: message.includes("!") ? "chris" : "corey",
        currentTime: currentLocalTime(),
        fetchTodos: async () => ["Buy groceries", "Walk the dog", "Read a book"],
      }
      const result = await run(agent, history, { context })
      console.log(`🌵 ${result.finalOutput}\n\n`)
      history = result.history
    } catch (error) {
      if (error instanceof InputGuardrailTripwireTriggered) {
        console.log(
          `🩻 Spike doesn't think it should respond to that input because ${JSON.stringify(
            error.result.output
          )}`
        )
      } else {
        console.error("An error occurred while running the agent:", error)
      }
    }
  }
}

await main()
