import { v } from "convex/values";

import { mutation, query } from "./_generated/server";

export const connect = mutation({
  args: {
    daemonId: v.string(),
    sessionId: v.string(),
    hostname: v.string(),
    platform: v.string(),
    architecture: v.string(),
    version: v.string(),
  },
  handler: async (ctx, args) => {
    const existing = await ctx.db
      .query("daemonPresence")
      .withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
      .unique();
    const timestamp = Date.now();
    if (existing) {
      await ctx.db.patch("daemonPresence", existing._id, {
        status: "online",
        lastHeartbeatAt: timestamp,
      });
      return existing._id;
    }
    return await ctx.db.insert("daemonPresence", {
      ...args,
      status: "online",
      startedAt: timestamp,
      lastHeartbeatAt: timestamp,
    });
  },
});

export const heartbeat = mutation({
  args: {
    daemonId: v.string(),
    sessionId: v.string(),
  },
  handler: async (ctx, args) => {
    const presence = await ctx.db
      .query("daemonPresence")
      .withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
      .unique();
    if (!presence || presence.daemonId !== args.daemonId) {
      return false;
    }
    await ctx.db.patch("daemonPresence", presence._id, {
      status: "online",
      lastHeartbeatAt: Date.now(),
    });
    return true;
  },
});

export const disconnect = mutation({
  args: {
    daemonId: v.string(),
    sessionId: v.string(),
  },
  handler: async (ctx, args) => {
    const presence = await ctx.db
      .query("daemonPresence")
      .withIndex("by_sessionId", (q) => q.eq("sessionId", args.sessionId))
      .unique();
    if (!presence || presence.daemonId !== args.daemonId) {
      return false;
    }
    await ctx.db.patch("daemonPresence", presence._id, {
      status: "offline",
      lastHeartbeatAt: Date.now(),
    });
    return true;
  },
});

export const recordEvent = mutation({
  args: {
    daemonId: v.string(),
    commandId: v.optional(v.id("daemonCommands")),
    kind: v.string(),
    data: v.any(),
  },
  handler: async (ctx, args) => {
    return await ctx.db.insert("daemonCommandEvents", {
      ...args,
      createdAt: Date.now(),
    });
  },
});

export const listEvents = query({
  args: {
    daemonId: v.string(),
    limit: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("daemonCommandEvents")
      .withIndex("by_daemonId_and_createdAt", (q) =>
        q.eq("daemonId", args.daemonId)
      )
      .order("desc")
      .take(Math.min(args.limit ?? 100, 500));
  },
});
