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

/**
 * List all nurture sequences, optionally filtered by status (active/inactive)
 */
export const getSequences = query({
  args: {
    isActive: v.optional(v.boolean()),
    sequenceType: v.optional(nurtureSequenceTypeValidator),
    limit: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const limit = args.limit ?? 50;

    if (args.isActive !== undefined) {
      const results = await ctx.db
        .query("email_nurture_sequences")
        .withIndex("by_isActive", (q) => q.eq("isActive", args.isActive!))
        .order("desc")
        .take(limit);

      if (args.sequenceType) {
        return results.filter((s) => s.sequenceType === args.sequenceType);
      }
      return results;
    }

    if (args.sequenceType) {
      return await ctx.db
        .query("email_nurture_sequences")
        .withIndex("by_sequenceType", (q) =>
          q.eq("sequenceType", args.sequenceType!),
        )
        .order("desc")
        .take(limit);
    }

    return await ctx.db
      .query("email_nurture_sequences")
      .order("desc")
      .take(limit);
  },
});

/**
 * Get a single nurture sequence by ID
 */
export const getSequenceById = query({
  args: { id: v.id("email_nurture_sequences") },
  handler: async (ctx, args) => {
    return await ctx.db.get(args.id);
  },
});

/**
 * Get steps for a sequence, ordered by stepNumber
 */
export const getSequenceSteps = query({
  args: {
    sequenceId: v.string(),
    activeOnly: v.optional(v.boolean()),
  },
  handler: async (ctx, args) => {
    const steps = await ctx.db
      .query("email_nurture_sequence_steps")
      .withIndex("by_sequenceId", (q) => q.eq("sequenceId", args.sequenceId))
      .collect();

    const filtered = args.activeOnly ? steps.filter((s) => s.isActive) : steps;

    return filtered.sort((a, b) => a.stepNumber - b.stepNumber);
  },
});

/**
 * Get enrollment states for a user across all sequences
 */
export const getUserStates = query({
  args: {
    userId: v.string(),
    status: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const states = await ctx.db
      .query("user_nurture_sequence_states")
      .withIndex("by_userId", (q) => q.eq("userId", args.userId))
      .collect();

    if (args.status) {
      return states.filter((s) => s.status === args.status);
    }
    return states;
  },
});

/**
 * Get a single user nurture state for a specific user+sequence combo
 */
export const getUserStateBySequence = query({
  args: {
    userId: v.string(),
    sequenceId: v.string(),
  },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("user_nurture_sequence_states")
      .withIndex("by_userId_sequenceId", (q) =>
        q.eq("userId", args.userId).eq("sequenceId", args.sequenceId),
      )
      .first();
  },
});

/**
 * Get emails for a user nurture state
 */
export const getEmailsByState = query({
  args: {
    stateId: v.string(),
    status: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const emails = await ctx.db
      .query("user_nurture_sequence_emails")
      .withIndex("by_stateId", (q) => q.eq("stateId", args.stateId))
      .collect();

    if (args.status) {
      return emails.filter((e) => e.status === args.status);
    }
    return emails;
  },
});

/**
 * Get aggregate email stats (sent/opened/clicked/failed counts)
 * Optionally scoped to a specific sequence or user
 */
export const getEmailStats = query({
  args: {
    userId: v.optional(v.string()),
    stateId: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    let emails;

    if (args.stateId) {
      emails = await ctx.db
        .query("user_nurture_sequence_emails")
        .withIndex("by_stateId", (q) => q.eq("stateId", args.stateId!))
        .collect();
    } else if (args.userId) {
      emails = await ctx.db
        .query("user_nurture_sequence_emails")
        .withIndex("by_userId", (q) => q.eq("userId", args.userId!))
        .collect();
    } else {
      emails = await ctx.db.query("user_nurture_sequence_emails").collect();
    }

    const stats = {
      total: emails.length,
      pending: 0,
      scheduled: 0,
      sent: 0,
      opened: 0,
      clicked: 0,
      failed: 0,
      skipped: 0,
    };

    for (const email of emails) {
      const key = email.status.toLowerCase() as keyof typeof stats;
      if (key in stats && key !== "total") {
        (stats as Record<string, number>)[key]++;
      }
    }

    return stats;
  },
});
