/**
 * Cascade Delete Helper for Convex
 *
 * Convex has no ON DELETE CASCADE — this utility manually deletes
 * child records before deleting a parent, mirroring every
 * `onDelete: Cascade` relation in the Prisma schema.
 *
 * Usage:
 *   await cascadeDelete(ctx, "users", userId);
 */

import { GenericMutationCtx, GenericDataModel } from "convex/server";

type Ctx = GenericMutationCtx<GenericDataModel>;

/**
 * Complete map of every `onDelete: Cascade` relation from prisma/schema.prisma.
 *
 * Format: parentTable → [ { child, foreignKey } ]
 * The order matters: children are deleted before the parent.
 * Nested cascades (e.g. users → conversation_logs → conversation_log_messages)
 * are handled recursively.
 */
export const CASCADE_MAP: Record<
  string,
  { child: string; foreignKey: string }[]
> = {
  // ── users (root of most cascades) ─────────────────────────────
  users: [
    { child: "conversation_logs", foreignKey: "userId" },
    { child: "knowledge_base_documents", foreignKey: "userId" },
    { child: "knowledge_base_faqs", foreignKey: "userId" },
    { child: "knowledge_base_settings", foreignKey: "userId" },
    { child: "user_api_keys", foreignKey: "userId" },
    { child: "user_workflows", foreignKey: "userId" },
    { child: "workflow_analytics", foreignKey: "userId" },
    { child: "admin_notes", foreignKey: "userId" },
    { child: "billing_history", foreignKey: "userId" },
    { child: "bookings", foreignKey: "userId" },
    { child: "customers", foreignKey: "userId" },
    { child: "integrations", foreignKey: "userId" },
    { child: "leads", foreignKey: "userId" },
    { child: "login_history", foreignKey: "userId" },
    { child: "notifications", foreignKey: "userId" },
    { child: "onboarding_progress", foreignKey: "userId" },
    { child: "organization_invitations", foreignKey: "invitedBy" },
    { child: "organization_members", foreignKey: "userId" },
    { child: "organizations", foreignKey: "ownerId" },
    { child: "subscriptions", foreignKey: "userId" },
    { child: "support_tickets", foreignKey: "userId" },
    { child: "system_message_views", foreignKey: "userId" },
    { child: "system_messages", foreignKey: "createdBy" },
    { child: "user_links", foreignKey: "userId" },
    { child: "user_preferences", foreignKey: "userId" },
    { child: "user_sessions", foreignKey: "userId" },
    { child: "waitlists", foreignKey: "userId" },
    { child: "whatsapp_conversations", foreignKey: "userId" },
    { child: "user_nurture_sequence_states", foreignKey: "userId" },
    { child: "voice_agent_phone_config", foreignKey: "userId" },
    { child: "voice_agent_kb_sync", foreignKey: "userId" },
    { child: "voice_agent_settings", foreignKey: "userId" },
    { child: "social_accounts", foreignKey: "userId" },
    { child: "reviews", foreignKey: "userId" },
    { child: "review_requests", foreignKey: "userId" },
    { child: "review_question_templates", foreignKey: "userId" },
    { child: "review_widget_settings", foreignKey: "userId" },
    { child: "referrals", foreignKey: "userId" },
    { child: "quotations", foreignKey: "userId" },
    { child: "deals", foreignKey: "userId" },
    { child: "quotation_recurring_templates", foreignKey: "userId" },
    { child: "quotation_settings", foreignKey: "userId" },
    { child: "expense_categories", foreignKey: "userId" },
    { child: "expenses", foreignKey: "userId" },
    { child: "property", foreignKey: "userId" },
    { child: "broker", foreignKey: "userId" },
    { child: "property_viewing", foreignKey: "userId" },
    { child: "client_requirements", foreignKey: "userId" },
    { child: "real_estate_transaction", foreignKey: "userId" },
    { child: "lead_pipeline_stages", foreignKey: "userId" },
  ],

  // ── conversation_logs ────────────────────────────────────────
  conversation_logs: [
    { child: "voice_conversation_actions", foreignKey: "conversationId" },
    { child: "conversation_log_messages", foreignKey: "conversationId" },
  ],

  // ── knowledge_base_documents ───────────────────────────────
  knowledge_base_documents: [
    { child: "knowledge_base_chunks", foreignKey: "documentId" },
    { child: "voice_agent_kb_sync", foreignKey: "documentId" },
  ],

  // ── organizations ─────────────────────────────────────────────
  organizations: [
    { child: "organization_invitations", foreignKey: "organizationId" },
    { child: "organization_members", foreignKey: "organizationId" },
    { child: "org_whatsapp_conversations", foreignKey: "organizationId" },
    { child: "user_language_preferences", foreignKey: "organizationId" },
    { child: "company_knowledge_base", foreignKey: "organizationId" },
    { child: "company_availability", foreignKey: "organizationId" },
    { child: "appointment_types", foreignKey: "organizationId" },
  ],

  // ── bookings ──────────────────────────────────────────────────
  bookings: [{ child: "booking_notes", foreignKey: "bookingId" }],

  // ── whatsapp_conversations ────────────────────────────────────
  whatsapp_conversations: [
    { child: "conversation_messages", foreignKey: "conversationId" },
  ],

  // ── org_whatsapp_conversations ────────────────────────────────
  org_whatsapp_conversations: [
    { child: "org_whatsapp_messages", foreignKey: "conversationId" },
  ],

  // ── job_applications ──────────────────────────────────────────
  job_applications: [
    { child: "application_notes", foreignKey: "applicationId" },
    { child: "interview_booking_tokens", foreignKey: "applicationId" },
    { child: "interview_bookings", foreignKey: "applicationId" },
  ],

  // ── jobs ──────────────────────────────────────────────────────
  jobs: [
    { child: "interview_booking_tokens", foreignKey: "jobId" },
    { child: "interview_bookings", foreignKey: "jobId" },
  ],

  // ── support_tickets ───────────────────────────────────────────
  support_tickets: [{ child: "ticket_messages", foreignKey: "ticketId" }],

  // ── system_messages ───────────────────────────────────────────
  system_messages: [{ child: "system_message_views", foreignKey: "messageId" }],

  // ── waitlists ─────────────────────────────────────────────────
  waitlists: [{ child: "waitlist_signups", foreignKey: "waitlistId" }],

  // ── email_nurture_sequences ───────────────────────────────────
  email_nurture_sequences: [
    { child: "email_nurture_sequence_steps", foreignKey: "sequenceId" },
    { child: "user_nurture_sequence_states", foreignKey: "sequenceId" },
  ],

  // ── email_nurture_sequence_steps ──────────────────────────────
  email_nurture_sequence_steps: [
    { child: "user_nurture_sequence_emails", foreignKey: "stepId" },
  ],

  // ── user_nurture_sequence_states ──────────────────────────────
  user_nurture_sequence_states: [
    { child: "user_nurture_sequence_emails", foreignKey: "stateId" },
  ],

  // ── contact_submissions ───────────────────────────────────────
  contact_submissions: [{ child: "contact_messages", foreignKey: "contactId" }],

  // ── social_accounts ───────────────────────────────────────────
  social_accounts: [
    { child: "social_content_queue", foreignKey: "socialAccountId" },
    { child: "social_messages", foreignKey: "socialAccountId" },
  ],

  // ── social_content_queue ──────────────────────────────────────
  social_content_queue: [
    { child: "social_analytics", foreignKey: "queueItemId" },
  ],

  // ── leads ─────────────────────────────────────────────────────
  leads: [
    { child: "lead_activities", foreignKey: "leadId" },
    { child: "lead_scoring_events", foreignKey: "leadId" },
    { child: "lead_nurture_memberships", foreignKey: "leadId" },
  ],

  // ── lead_nurture_sequences ────────────────────────────────────
  lead_nurture_sequences: [
    { child: "lead_nurture_steps", foreignKey: "sequenceId" },
    { child: "lead_nurture_memberships", foreignKey: "sequenceId" },
  ],

  // ── quotations ────────────────────────────────────────────────
  quotations: [
    { child: "quotation_items", foreignKey: "quotationId" },
    { child: "quotation_payments", foreignKey: "quotationId" },
    { child: "quotation_penalties", foreignKey: "quotationId" },
    { child: "quotation_reminders", foreignKey: "quotationId" },
  ],

  // ── quotation_recurring_templates ─────────────────────────────
  quotation_recurring_templates: [
    { child: "quotation_recurring_template_items", foreignKey: "templateId" },
  ],

  // ── property ─────────────────────────────────────────────────
  property: [
    { child: "property_image", foreignKey: "propertyId" },
    { child: "property_viewing", foreignKey: "propertyId" },
    { child: "property_match", foreignKey: "propertyId" },
  ],

  // ── broker ──────────────────────────────────────────────────
  broker: [{ child: "broker_availability", foreignKey: "brokerId" }],

  // ── property_viewing ────────────────────────────────────────
  property_viewing: [{ child: "viewing_feedback", foreignKey: "viewingId" }],

  // ── client_requirements ─────────────────────────────────────
  client_requirements: [
    { child: "property_match", foreignKey: "requirementId" },
  ],
};

/**
 * Recursively delete all cascade-dependent children, then the parent record.
 *
 * @param ctx - Convex mutation context
 * @param table - The parent table name (must be a key in CASCADE_MAP or a leaf table)
 * @param parentId - The Convex document _id of the parent record to delete
 */
export async function cascadeDelete(
  ctx: Ctx,
  table: string,
  parentId: string,
): Promise<number> {
  let deletedCount = 0;
  const children = CASCADE_MAP[table];

  if (children) {
    for (const { child, foreignKey } of children) {
      // Query all child records referencing this parent
      // Dynamic table/field names require type bypass — safe because CASCADE_MAP is static
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const childRecords = await (ctx.db as any)
        .query(child)
        .filter((q: any) => q.eq(q.field(foreignKey), parentId))
        .collect();

      // Recursively cascade-delete each child
      for (const record of childRecords) {
        deletedCount += await cascadeDelete(ctx, child, record._id as string);
      }
    }
  }

  // Delete the parent record itself
  await ctx.db.delete(parentId as never);
  deletedCount += 1;

  return deletedCount;
}
