/**
 * WhatsApp Workflows — CRUD for sector-specific conversation workflows.
 *
 * A workflow extends the AI agent's behaviour for specific triggers
 * (e.g. clinic intake form, restaurant reservation flow). Defaults are
 * auto-seeded during org provisioning by `lib/services/workflow-seeder.service.ts`
 * and can be edited from the dashboard.
 */

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

const collectFieldValidator = v.object({
  key: v.string(),
  labelEn: v.string(),
  labelAr: v.string(),
  type: v.string(),
  required: v.boolean(),
  options: v.optional(v.array(v.string())),
});

export const createWorkflow = mutation({
  args: {
    organizationId: v.string(),
    name: v.string(),
    description: v.optional(v.string()),
    sector: v.optional(v.string()),
    triggerKeywords: v.array(v.string()),
    triggerIntent: v.optional(v.string()),
    systemPromptAddition: v.string(),
    collectFields: v.array(collectFieldValidator),
    confirmationMessageEn: v.optional(v.string()),
    confirmationMessageAr: v.optional(v.string()),
    isActive: v.boolean(),
    priority: v.number(),
    language: v.string(),
    createdAt: v.optional(v.number()),
    updatedAt: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    return await ctx.db.insert("whatsapp_workflows", {
      organizationId: args.organizationId,
      name: args.name,
      description: args.description,
      sector: args.sector,
      triggerKeywords: args.triggerKeywords,
      triggerIntent: args.triggerIntent,
      systemPromptAddition: args.systemPromptAddition,
      collectFields: args.collectFields,
      confirmationMessageEn: args.confirmationMessageEn,
      confirmationMessageAr: args.confirmationMessageAr,
      isActive: args.isActive,
      priority: args.priority,
      language: args.language,
      createdAt: args.createdAt ?? now,
      updatedAt: args.updatedAt ?? now,
    });
  },
});

export const updateWorkflow = mutation({
  args: {
    id: v.string(),
    name: v.optional(v.string()),
    description: v.optional(v.string()),
    triggerKeywords: v.optional(v.array(v.string())),
    triggerIntent: v.optional(v.string()),
    systemPromptAddition: v.optional(v.string()),
    collectFields: v.optional(v.array(collectFieldValidator)),
    confirmationMessageEn: v.optional(v.string()),
    confirmationMessageAr: v.optional(v.string()),
    isActive: v.optional(v.boolean()),
    priority: v.optional(v.number()),
    language: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const { id, ...fields } = args;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let docId: any;
    try {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const doc = await ctx.db.get(id as any);
      if (doc) docId = doc._id;
    } catch {
      return null;
    }
    if (!docId) return null;

    const updates: Record<string, unknown> = { updatedAt: Date.now() };
    for (const [key, value] of Object.entries(fields)) {
      if (value !== undefined) updates[key] = value;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    await ctx.db.patch(docId, updates as any);
    return docId;
  },
});

export const deleteWorkflow = mutation({
  args: { id: v.string() },
  handler: async (ctx, args) => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let docId: any;
    try {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const doc = await ctx.db.get(args.id as any);
      if (doc) docId = doc._id;
    } catch {
      return null;
    }
    if (!docId) return null;
    // Soft delete: set isActive false so the workflow is no longer matched
    // by the AI engine but the row is preserved for analytics / undo.
    await ctx.db.patch(docId, { isActive: false, updatedAt: Date.now() });
    return docId;
  },
});

export const listWorkflows = query({
  args: {
    organizationId: v.string(),
    activeOnly: v.optional(v.boolean()),
  },
  handler: async (ctx, args) => {
    if (args.activeOnly) {
      return await ctx.db
        .query("whatsapp_workflows")
        .withIndex("by_organizationId_isActive", (q) =>
          q.eq("organizationId", args.organizationId).eq("isActive", true),
        )
        .collect();
    }
    return await ctx.db
      .query("whatsapp_workflows")
      .withIndex("by_organizationId", (q) =>
        q.eq("organizationId", args.organizationId),
      )
      .collect();
  },
});

export const getWorkflow = query({
  args: { id: v.string() },
  handler: async (ctx, args) => {
    try {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      return await ctx.db.get(args.id as any);
    } catch {
      return null;
    }
  },
});

/**
 * Hard-delete every workflow for an organization.
 *
 * Used by the sector-switcher script when flipping a test org from one
 * sector to another, so we don't accumulate stale workflows from previous
 * sectors. Returns the number of rows deleted.
 */
export const hardDeleteAllForOrg = mutation({
  args: { organizationId: v.string() },
  handler: async (ctx, args) => {
    const rows = await ctx.db
      .query("whatsapp_workflows")
      .withIndex("by_organizationId", (q) =>
        q.eq("organizationId", args.organizationId),
      )
      .collect();

    for (const row of rows) {
      await ctx.db.delete(row._id);
    }

    return { deleted: rows.length };
  },
});
