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

// Get read state for a single channel
export const getReadState = query({
  args: {
    userId: v.id("userProfiles"),
    channelId: v.id("channels"),
  },
  returns: v.union(
    v.object({
      lastReadTimestamp: v.number(),
    }),
    v.null()
  ),
  handler: async (ctx, args) => {
    const state = await ctx.db
      .query("channelReadState")
      .withIndex("by_user_and_channel", (q) =>
        q.eq("userId", args.userId).eq("channelId", args.channelId)
      )
      .unique();
    if (!state) return null;
    return { lastReadTimestamp: state.lastReadTimestamp };
  },
});

// Mark a channel as read up to a given timestamp
export const markRead = mutation({
  args: {
    userId: v.id("userProfiles"),
    channelId: v.id("channels"),
    lastReadTimestamp: v.number(),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    const existing = await ctx.db
      .query("channelReadState")
      .withIndex("by_user_and_channel", (q) =>
        q.eq("userId", args.userId).eq("channelId", args.channelId)
      )
      .unique();

    if (existing) {
      // Only update if timestamp is newer
      if (args.lastReadTimestamp > existing.lastReadTimestamp) {
        await ctx.db.patch(existing._id, {
          lastReadTimestamp: args.lastReadTimestamp,
        });
      }
    } else {
      await ctx.db.insert("channelReadState", {
        userId: args.userId,
        channelId: args.channelId,
        lastReadTimestamp: args.lastReadTimestamp,
      });
    }
    return null;
  },
});

// Get all read states for a user (used by Sidebar)
export const getAllReadStates = query({
  args: {
    userId: v.id("userProfiles"),
  },
  returns: v.array(
    v.object({
      channelId: v.id("channels"),
      lastReadTimestamp: v.number(),
    })
  ),
  handler: async (ctx, args) => {
    const states = await ctx.db
      .query("channelReadState")
      .withIndex("by_user", (q) => q.eq("userId", args.userId))
      .collect();
    return states.map((s) => ({
      channelId: s.channelId,
      lastReadTimestamp: s.lastReadTimestamp,
    }));
  },
});

// Get the latest message timestamp per channel (used by Sidebar)
export const getLatestMessageTimestamps = query({
  args: {
    channelIds: v.array(v.id("channels")),
  },
  returns: v.array(
    v.object({
      channelId: v.id("channels"),
      latestTimestamp: v.number(),
    })
  ),
  handler: async (ctx, args) => {
    const results = [];
    for (const channelId of args.channelIds) {
      const latestMsg = await ctx.db
        .query("messages")
        .withIndex("by_channel", (q) => q.eq("channelId", channelId))
        .order("desc")
        .first();
      if (latestMsg) {
        results.push({
          channelId,
          latestTimestamp: Math.floor(latestMsg._creationTime),
        });
      }
    }
    return results;
  },
});
