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

/**
 * Get referrals for a user, optionally filtered by status
 */
export const getReferrals = query({
  args: {
    userId: v.string(),
    status: v.optional(v.string()),
    limit: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const limit = args.limit ?? 50;

    if (args.status) {
      return await ctx.db
        .query("referrals")
        .withIndex("by_userId_status", (q) =>
          q.eq("userId", args.userId).eq("status", args.status!),
        )
        .order("desc")
        .take(limit);
    }

    return await ctx.db
      .query("referrals")
      .withIndex("by_userId", (q) => q.eq("userId", args.userId))
      .order("desc")
      .take(limit);
  },
});

/**
 * Get a single referral by its code
 */
export const getReferralByCode = query({
  args: {
    code: v.string(),
    status: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const doc = await ctx.db
      .query("referrals")
      .withIndex("by_code", (q) => q.eq("code", args.code))
      .first();

    if (!doc) return null;
    if (args.status && doc.status !== args.status) return null;
    return doc;
  },
});

/**
 * Get a single referral by its Convex _id (or prismaId)
 */
export const getReferralById = query({
  args: { id: v.string() },
  handler: async (ctx, args) => {
    // Try direct lookup first
    try {
      const doc = await ctx.db.get(args.id as never);
      if (doc) return doc;
    } catch {
      // Not a valid Convex ID, try prismaId fallback
    }

    // Fallback: search by prismaId
    const byPrismaId = await ctx.db
      .query("referrals")
      .filter((q) => q.eq(q.field("prismaId"), args.id))
      .first();
    return byPrismaId;
  },
});

/**
 * Get referral stats for a user
 */
export const getReferralStats = query({
  args: { userId: v.string() },
  handler: async (ctx, args) => {
    const referrals = await ctx.db
      .query("referrals")
      .withIndex("by_userId", (q) => q.eq("userId", args.userId))
      .collect();

    const total = referrals.length;
    let totalUses = 0;
    let totalConversions = 0;
    let totalRewards = 0;
    const byStatus: Record<string, number> = {};

    for (const r of referrals) {
      totalUses += r.uses;
      totalConversions += r.conversions;
      totalRewards += r.rewardsIssued;
      byStatus[r.status] = (byStatus[r.status] ?? 0) + 1;
    }

    return {
      totalCodes: total,
      totalUses,
      totalConversions,
      totalRewards,
      conversionRate:
        totalUses > 0 ? Math.round((totalConversions / totalUses) * 100) : 0,
      byStatus,
    };
  },
});
