import { api } from "@code/backend/convex/_generated/api";
import type { Id } from "@code/backend/convex/_generated/dataModel";
import { ARTIFACT_PATHS } from "@code/backend/convex/artifactModel";
import { parseAgentEnv } from "@code/env/agent";
import { defineTool } from "@flue/runtime";
import { ConvexHttpClient } from "convex/browser";
import * as v from "valibot";

export const createProjectTools = (
  issueAgentId: string,
  runtimeEnv: Record<string, string | undefined>
) => {
  const env = parseAgentEnv(runtimeEnv);
  const client = new ConvexHttpClient(env.CONVEX_URL);
  // Flue receives this controlled id from the issue card that starts the run.
  const issueId = issueAgentId as Id<"projectIssues">;

  return [
    defineTool({
      description:
        "Read the repository, issue, and canonical project artifacts bound to this agent.",
      name: "lookup_issue_context",
      async run() {
        return await client.query(api.agentWorkspace.get, {
          issueId,
          token: env.FLUE_DB_TOKEN,
        });
      },
    }),
    defineTool({
      description:
        "Publish the complete current content of one canonical project markdown artifact after changing it in AgentOS.",
      input: v.object({
        content: v.pipe(v.string(), v.maxLength(200_000)),
        path: v.picklist(ARTIFACT_PATHS),
      }),
      name: "publish_project_artifact",
      async run({ input }) {
        const revision = await client.mutation(
          api.agentWorkspace.updateArtifact,
          {
            content: input.content,
            issueId,
            path: input.path,
            token: env.FLUE_DB_TOKEN,
          }
        );
        return { path: input.path, revision };
      },
    }),
    defineTool({
      description:
        "Report the durable issue state. Use needs-input before asking a blocking question and completed only after verification.",
      input: v.object({
        status: v.picklist(["working", "needs-input", "completed", "failed"]),
        summary: v.pipe(v.string(), v.maxLength(4000)),
      }),
      name: "report_work_status",
      async run({ input }) {
        await client.mutation(api.agentWorkspace.setStatus, {
          issueId,
          status: input.status,
          summary: input.summary,
          token: env.FLUE_DB_TOKEN,
        });
        return { recorded: true, status: input.status };
      },
    }),
  ];
};
