/**
 * Workflows Domain Adapter
 *
 * Routes user_workflows, UserAPIKey, and user_links CRUD to Prisma or Convex
 * based on data-source config. Maintains Prisma-compatible method signatures
 * so service layer changes are minimal.
 *
 * n8n API calls remain untouched — this adapter only handles DB persistence.
 */

import { prisma } from "@/lib/db";
import { convexQuery, convexMutation } from "@/lib/convex-client";
import { getDataSource } from "@/lib/data-source";
import {
  convexToPrismaShape,
  convexToPrismaShapeMany,
  dateToConvexTimestamp,
  applyPagination,
  type ConvexDoc,
  type BatchResult,
} from "./base";

const DOMAIN = "workflows" as const;
const WORKFLOW_TS_FIELDS = [
  "createdAt",
  "updatedAt",
  "lastRunAt",
  "completedAt",
  "scheduledAt",
  "lastErrorAt",
];
const API_CREDENTIAL_TS_FIELDS = [
  "createdAt",
  "updatedAt",
  "expiresAt",
  "lastUsedAt",
];
const LINK_TS_FIELDS = ["createdAt", "updatedAt"];

function isConvex(): boolean {
  return getDataSource(DOMAIN) === "convex";
}

// =============================================================================
// User Workflows (prisma.userWorkflow <-> Convex user_workflows)
// =============================================================================

const userWorkflows = {
  // ── findMany ────────────────────────────────────────────────────────────
  async findMany(args: {
    where?: Record<string, unknown>;
    orderBy?: Record<string, string> | Record<string, string>[];
    take?: number;
    skip?: number;
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userWorkflow.findMany(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const status = where.status as string | undefined;
    const limit = (args.take || 100) + (args.skip || 0);

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getWorkflows", {
        ...(userId ? { userId } : { userId: "" }),
        ...(status ? { status } : {}),
        limit,
      })) || [];

    // Apply additional where filters not handled by Convex query
    let filtered = docs;
    if (where.workflowType) {
      const wt = where.workflowType;
      if (typeof wt === "object" && wt !== null && "in" in (wt as object)) {
        const inValues = (wt as { in: string[] }).in;
        filtered = filtered.filter((d) =>
          inValues.includes(d.workflowType as string),
        );
      } else {
        filtered = filtered.filter((d) => d.workflowType === wt);
      }
    }
    if (where.healthStatus) {
      filtered = filtered.filter((d) => d.healthStatus === where.healthStatus);
    }
    if (where.n8nWorkflowId) {
      filtered = filtered.filter(
        (d) => d.n8nWorkflowId === where.n8nWorkflowId,
      );
    }

    const paginated = applyPagination(filtered, args.skip, args.take);
    return convexToPrismaShapeMany(paginated, WORKFLOW_TS_FIELDS);
  },

  // ── findFirst ───────────────────────────────────────────────────────────
  async findFirst(args: {
    where?: Record<string, unknown>;
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userWorkflow.findFirst(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;

    // Try by-id lookup first
    const id = where.id as string | undefined;
    if (id) {
      const doc = await convexQuery<ConvexDoc | null>(
        "workflows/queries:getWorkflowById",
        { id },
      );
      return doc ? convexToPrismaShape(doc, WORKFLOW_TS_FIELDS) : null;
    }

    // Fallback: fetch by userId and filter
    const userId = where.userId as string | undefined;
    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getWorkflows", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 1000,
      })) || [];

    const match = docs.find((doc) => {
      for (const [field, value] of Object.entries(where)) {
        if (field === "id") {
          if ((doc.prismaId || doc._id) !== value) return false;
        } else if (
          typeof value === "object" &&
          value !== null &&
          "in" in (value as object)
        ) {
          const inValues = (value as { in: unknown[] }).in;
          if (!inValues.includes(doc[field])) return false;
        } else if (doc[field] !== value) {
          return false;
        }
      }
      return true;
    });

    return match ? convexToPrismaShape(match, WORKFLOW_TS_FIELDS) : null;
  },

  // ── findUnique ──────────────────────────────────────────────────────────
  async findUnique(args: {
    where: { id: string };
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userWorkflow.findUnique(args as any);
    }

    const doc = await convexQuery<ConvexDoc | null>(
      "workflows/queries:getWorkflowById",
      { id: args.where.id },
    );
    return doc ? convexToPrismaShape(doc, WORKFLOW_TS_FIELDS) : null;
  },

  // ── count ───────────────────────────────────────────────────────────────
  async count(args?: { where?: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userWorkflow.count(args as any);
    }

    const where = (args?.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const status = where.status as string | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getWorkflows", {
        ...(userId ? { userId } : { userId: "" }),
        ...(status ? { status } : {}),
        limit: 10000,
      })) || [];

    let filtered = docs;
    if (where.workflowType) {
      filtered = filtered.filter((d) => d.workflowType === where.workflowType);
    }
    if (where.healthStatus) {
      filtered = filtered.filter((d) => d.healthStatus === where.healthStatus);
    }

    return filtered.length;
  },

  // ── create ──────────────────────────────────────────────────────────────
  async create(args: { data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userWorkflow.create(args as any);
    }

    const d = args.data;
    const now = Date.now();
    const convexId = await convexMutation<string>(
      "workflows/mutations:createWorkflow",
      {
        userId: d.userId as string,
        workflowType: d.workflowType as string,
        status: (d.status as string) || "inactive",
        config: d.config ?? {},
        errorCount: (d.errorCount as number) || 0,
        healthStatus: (d.healthStatus as string) || "healthy",
        createdAt: now,
        updatedAt: now,
        ...(d.n8nWorkflowId
          ? { n8nWorkflowId: d.n8nWorkflowId as string }
          : {}),
        ...(d.lastRunAt
          ? { lastRunAt: dateToConvexTimestamp(d.lastRunAt as Date) }
          : {}),
        ...(d.lastRunStatus
          ? { lastRunStatus: d.lastRunStatus as string }
          : {}),
        ...(d.lastErrorAt
          ? { lastErrorAt: dateToConvexTimestamp(d.lastErrorAt as Date) }
          : {}),
        ...(d.id ? { prismaId: d.id as string } : {}),
      },
    );

    return {
      id: (d.id as string) || convexId || "",
      userId: d.userId,
      workflowType: d.workflowType,
      n8nWorkflowId: d.n8nWorkflowId ?? null,
      status: d.status || "inactive",
      config: d.config ?? {},
      lastRunAt: d.lastRunAt ?? null,
      lastRunStatus: d.lastRunStatus ?? null,
      errorCount: d.errorCount || 0,
      healthStatus: d.healthStatus || "healthy",
      lastErrorAt: d.lastErrorAt ?? null,
      createdAt: new Date(),
      updatedAt: new Date(),
    };
  },

  // ── update ──────────────────────────────────────────────────────────────
  async update(args: { where: { id: string }; data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userWorkflow.update(args as any);
    }

    const d = args.data;
    const updatePayload: Record<string, unknown> = {
      id: args.where.id,
      updatedAt: Date.now(),
    };

    // Map each field if present
    if (d.status !== undefined) updatePayload.status = d.status;
    if (d.config !== undefined) updatePayload.config = d.config;
    if (d.n8nWorkflowId !== undefined)
      updatePayload.n8nWorkflowId = d.n8nWorkflowId;
    if (d.lastRunAt !== undefined)
      updatePayload.lastRunAt = dateToConvexTimestamp(d.lastRunAt as Date);
    if (d.lastRunStatus !== undefined)
      updatePayload.lastRunStatus = d.lastRunStatus;
    if (d.errorCount !== undefined) updatePayload.errorCount = d.errorCount;
    if (d.healthStatus !== undefined)
      updatePayload.healthStatus = d.healthStatus;
    if (d.lastErrorAt !== undefined)
      updatePayload.lastErrorAt = dateToConvexTimestamp(d.lastErrorAt as Date);
    if (d.updatedAt !== undefined)
      updatePayload.updatedAt =
        dateToConvexTimestamp(d.updatedAt as Date) ?? Date.now();

    await convexMutation("workflows/mutations:updateWorkflow", updatePayload);

    // Return best-effort shape
    const existing = await userWorkflows.findUnique({
      where: { id: args.where.id },
    });
    return existing ? { ...existing, ...d } : null;
  },

  // ── updateMany ──────────────────────────────────────────────────────────
  async updateMany(args: {
    where: Record<string, unknown>;
    data: Record<string, unknown>;
  }): Promise<BatchResult> {
    if (!isConvex()) {
      return prisma.userWorkflow.updateMany(args as any);
    }

    const where = args.where;
    const userId = where.userId as string | undefined;

    // Fetch matching docs
    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getWorkflows", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 10000,
      })) || [];

    // Filter by where conditions
    let matching = docs;
    if (where.n8nWorkflowId) {
      matching = matching.filter(
        (d) => d.n8nWorkflowId === where.n8nWorkflowId,
      );
    }
    if (where.status) {
      matching = matching.filter((d) => d.status === where.status);
    }
    if (where.workflowType) {
      matching = matching.filter((d) => d.workflowType === where.workflowType);
    }
    if (where.healthStatus) {
      matching = matching.filter((d) => d.healthStatus === where.healthStatus);
    }

    // Update each matching doc
    let updatedCount = 0;
    for (const doc of matching) {
      const updatePayload: Record<string, unknown> = {
        id: doc._id,
        updatedAt: Date.now(),
      };

      const d = args.data;
      if (d.status !== undefined) updatePayload.status = d.status;
      if (d.config !== undefined) updatePayload.config = d.config;
      if (d.healthStatus !== undefined)
        updatePayload.healthStatus = d.healthStatus;
      if (d.errorCount !== undefined) updatePayload.errorCount = d.errorCount;
      if (d.lastRunAt !== undefined)
        updatePayload.lastRunAt = dateToConvexTimestamp(d.lastRunAt as Date);
      if (d.lastRunStatus !== undefined)
        updatePayload.lastRunStatus = d.lastRunStatus;
      if (d.lastErrorAt !== undefined)
        updatePayload.lastErrorAt = dateToConvexTimestamp(
          d.lastErrorAt as Date,
        );

      await convexMutation("workflows/mutations:updateWorkflow", updatePayload);
      updatedCount++;
    }

    return { count: updatedCount };
  },

  // ── delete ──────────────────────────────────────────────────────────────
  async deleteOne(args: { where: { id: string } }) {
    if (!isConvex()) {
      return prisma.userWorkflow.delete(args as any);
    }

    await convexMutation("workflows/mutations:deleteWorkflow", {
      id: args.where.id,
    });

    return { id: args.where.id };
  },

  // ── deleteMany ──────────────────────────────────────────────────────────
  async deleteMany(args: {
    where: Record<string, unknown>;
  }): Promise<BatchResult> {
    if (!isConvex()) {
      return prisma.userWorkflow.deleteMany(args as any);
    }

    const where = args.where;
    const userId = where.userId as string | undefined;

    // Fetch matching docs
    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getWorkflows", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 10000,
      })) || [];

    // Filter
    let matching = docs;
    if (where.workflowType) {
      matching = matching.filter((d) => d.workflowType === where.workflowType);
    }
    if (where.status) {
      matching = matching.filter((d) => d.status === where.status);
    }
    if (where.n8nWorkflowId) {
      matching = matching.filter(
        (d) => d.n8nWorkflowId === where.n8nWorkflowId,
      );
    }

    // Delete each
    for (const doc of matching) {
      await convexMutation("workflows/mutations:deleteWorkflow", {
        id: doc._id,
      });
    }

    return { count: matching.length };
  },
};

// =============================================================================
// User API Credentials (prisma.userAPIKey <-> Convex user_api_keys)
// =============================================================================

const userApiCredentials = {
  // ── findMany ────────────────────────────────────────────────────────────
  async findMany(args: {
    where?: Record<string, unknown>;
    orderBy?: Record<string, string> | Record<string, string>[];
    take?: number;
    skip?: number;
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userAPIKey.findMany(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const isActive = where.isActive as boolean | undefined;
    const limit = (args.take || 100) + (args.skip || 0);

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getApiCredentials", {
        ...(userId ? { userId } : { userId: "" }),
        ...(isActive !== undefined ? { isActive } : {}),
        limit,
      })) || [];

    // Additional where filters
    let filtered = docs;
    if (where.service) {
      filtered = filtered.filter((d) => d.service === where.service);
    }
    if (where.keyName) {
      filtered = filtered.filter((d) => d.keyName === where.keyName);
    }

    const paginated = applyPagination(filtered, args.skip, args.take);
    return convexToPrismaShapeMany(paginated, API_CREDENTIAL_TS_FIELDS);
  },

  // ── findFirst ───────────────────────────────────────────────────────────
  async findFirst(args: {
    where?: Record<string, unknown>;
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userAPIKey.findFirst(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getApiCredentials", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 1000,
      })) || [];

    const match = docs.find((doc) => {
      for (const [field, value] of Object.entries(where)) {
        if (field === "id") {
          if ((doc.prismaId || doc._id) !== value) return false;
        } else if (doc[field] !== value) {
          return false;
        }
      }
      return true;
    });

    return match ? convexToPrismaShape(match, API_CREDENTIAL_TS_FIELDS) : null;
  },

  // ── findUnique ──────────────────────────────────────────────────────────
  async findUnique(args: {
    where:
      | { id: string }
      | {
          userId_service_keyName: {
            userId: string;
            service: string;
            keyName: string;
          };
        };
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.userAPIKey.findUnique(args as any);
    }

    const where = args.where as Record<string, unknown>;
    if ("id" in where) {
      return userApiCredentials.findFirst({
        where: { id: where.id as string },
      });
    }

    // Composite unique: userId + service + keyName
    const composite = where.userId_service_keyName as {
      userId: string;
      service: string;
      keyName: string;
    };
    if (composite) {
      const doc = await convexQuery<ConvexDoc | null>(
        "workflows/queries:getApiCredentialByServiceName",
        {
          userId: composite.userId,
          service: composite.service,
          keyName: composite.keyName,
        },
      );
      return doc ? convexToPrismaShape(doc, API_CREDENTIAL_TS_FIELDS) : null;
    }

    return null;
  },

  // ── count ───────────────────────────────────────────────────────────────
  async count(args?: { where?: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userAPIKey.count(args as any);
    }

    const where = (args?.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const isActive = where.isActive as boolean | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getApiCredentials", {
        ...(userId ? { userId } : { userId: "" }),
        ...(isActive !== undefined ? { isActive } : {}),
        limit: 10000,
      })) || [];

    return docs.length;
  },

  // ── create ──────────────────────────────────────────────────────────────
  async create(args: { data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userAPIKey.create(args as any);
    }

    const d = args.data;
    const now = Date.now();
    const convexId = await convexMutation<string>(
      "workflows/mutations:createApiCredential",
      {
        userId: d.userId as string,
        service: d.service as string,
        keyName: d.keyName as string,
        encryptedValue: d.encryptedKey as string,
        isActive: (d.isActive as boolean) ?? true,
        createdAt: now,
        updatedAt: now,
        ...(d.expiresAt
          ? { expiresAt: dateToConvexTimestamp(d.expiresAt as Date) }
          : {}),
        ...(d.id ? { prismaId: d.id as string } : {}),
      },
    );

    return {
      id: (d.id as string) || convexId || "",
      userId: d.userId,
      service: d.service,
      keyName: d.keyName,
      encryptedKey: d.encryptedKey,
      isActive: d.isActive ?? true,
      expiresAt: d.expiresAt ?? null,
      lastUsedAt: null,
      createdAt: new Date(),
      updatedAt: new Date(),
    };
  },

  // ── update ──────────────────────────────────────────────────────────────
  async update(args: { where: { id: string }; data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.userAPIKey.update(args as any);
    }

    const d = args.data;
    const updatePayload: Record<string, unknown> = {
      id: args.where.id,
      updatedAt: Date.now(),
    };

    if (d.isActive !== undefined) updatePayload.isActive = d.isActive;
    if (d.encryptedKey !== undefined)
      updatePayload.encryptedValue = d.encryptedKey;
    if (d.lastUsedAt !== undefined)
      updatePayload.lastUsedAt = dateToConvexTimestamp(d.lastUsedAt as Date);
    if (d.expiresAt !== undefined)
      updatePayload.expiresAt = dateToConvexTimestamp(d.expiresAt as Date);

    await convexMutation(
      "workflows/mutations:updateApiCredential",
      updatePayload,
    );

    const existing = await userApiCredentials.findFirst({
      where: { id: args.where.id },
    });
    return existing ? { ...existing, ...d } : null;
  },

  // ── delete ──────────────────────────────────────────────────────────────
  async deleteOne(args: { where: { id: string } }) {
    if (!isConvex()) {
      return prisma.userAPIKey.delete(args as any);
    }

    await convexMutation("workflows/mutations:deleteApiCredential", {
      id: args.where.id,
    });

    return { id: args.where.id };
  },

  // ── deleteMany ──────────────────────────────────────────────────────────
  async deleteMany(args: {
    where: Record<string, unknown>;
  }): Promise<BatchResult> {
    if (!isConvex()) {
      return prisma.userAPIKey.deleteMany(args as any);
    }

    const where = args.where;
    const userId = where.userId as string | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getApiCredentials", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 10000,
      })) || [];

    let matching = docs;
    if (where.service) {
      matching = matching.filter((d) => d.service === where.service);
    }
    if (where.isActive !== undefined) {
      matching = matching.filter((d) => d.isActive === where.isActive);
    }

    for (const doc of matching) {
      await convexMutation("workflows/mutations:deleteApiCredential", {
        id: doc._id,
      });
    }

    return { count: matching.length };
  },
};

// =============================================================================
// User Links (prisma.user_links <-> Convex user_links)
// =============================================================================

const userLinks = {
  // ── findMany ────────────────────────────────────────────────────────────
  async findMany(args: {
    where?: Record<string, unknown>;
    orderBy?: Record<string, string> | Record<string, string>[];
    take?: number;
    skip?: number;
    select?: Record<string, boolean>;
  }) {
    if (!isConvex()) {
      return prisma.user_links.findMany(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const isActive = where.isActive as boolean | undefined;
    const limit = (args.take || 100) + (args.skip || 0);

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getUserLinks", {
        ...(userId ? { userId } : { userId: "" }),
        ...(isActive !== undefined ? { isActive } : {}),
        limit,
      })) || [];

    // Additional filters
    let filtered = docs;
    if (where.linkType) {
      filtered = filtered.filter((d) => d.linkType === where.linkType);
    }

    const paginated = applyPagination(filtered, args.skip, args.take);
    return convexToPrismaShapeMany(paginated, LINK_TS_FIELDS);
  },

  // ── findFirst ───────────────────────────────────────────────────────────
  async findFirst(args: { where?: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.user_links.findFirst(args as any);
    }

    const where = (args.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getUserLinks", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 1000,
      })) || [];

    const match = docs.find((doc) => {
      for (const [field, value] of Object.entries(where)) {
        if (field === "id") {
          if ((doc.prismaId || doc._id) !== value) return false;
        } else if (doc[field] !== value) {
          return false;
        }
      }
      return true;
    });

    return match ? convexToPrismaShape(match, LINK_TS_FIELDS) : null;
  },

  // ── findUnique ──────────────────────────────────────────────────────────
  async findUnique(args: { where: { id: string } }) {
    if (!isConvex()) {
      return prisma.user_links.findUnique(args as any);
    }

    return userLinks.findFirst({ where: { id: args.where.id } });
  },

  // ── count ───────────────────────────────────────────────────────────────
  async count(args?: { where?: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.user_links.count(args as any);
    }

    const where = (args?.where || {}) as Record<string, unknown>;
    const userId = where.userId as string | undefined;
    const isActive = where.isActive as boolean | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getUserLinks", {
        ...(userId ? { userId } : { userId: "" }),
        ...(isActive !== undefined ? { isActive } : {}),
        limit: 10000,
      })) || [];

    let filtered = docs;
    if (where.linkType) {
      filtered = filtered.filter((d) => d.linkType === where.linkType);
    }

    return filtered.length;
  },

  // ── create ──────────────────────────────────────────────────────────────
  async create(args: { data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.user_links.create(args as any);
    }

    const d = args.data;
    const now = Date.now();
    const convexId = await convexMutation<string>(
      "workflows/mutations:createUserLink",
      {
        userId: d.userId as string,
        linkType: d.linkType as string,
        title: d.title as string,
        url: d.url as string,
        isActive: (d.isActive as boolean) ?? true,
        sortOrder: (d.sortOrder as number) || 0,
        createdBy: d.createdBy as string,
        createdAt: now,
        updatedAt: now,
        ...(d.description ? { description: d.description as string } : {}),
        ...(d.icon ? { icon: d.icon as string } : {}),
        ...(d.updatedBy ? { updatedBy: d.updatedBy as string } : {}),
        ...(d.id ? { prismaId: d.id as string } : {}),
      },
    );

    return {
      id: (d.id as string) || convexId || "",
      userId: d.userId,
      linkType: d.linkType,
      title: d.title,
      url: d.url,
      description: d.description ?? null,
      icon: d.icon ?? null,
      isActive: d.isActive ?? true,
      sortOrder: d.sortOrder || 0,
      createdBy: d.createdBy,
      updatedBy: d.updatedBy ?? null,
      createdAt: new Date(),
      updatedAt: new Date(),
    };
  },

  // ── update ──────────────────────────────────────────────────────────────
  async update(args: { where: { id: string }; data: Record<string, unknown> }) {
    if (!isConvex()) {
      return prisma.user_links.update(args as any);
    }

    const d = args.data;
    const updatePayload: Record<string, unknown> = {
      id: args.where.id,
      updatedAt: Date.now(),
    };

    if (d.title !== undefined) updatePayload.title = d.title;
    if (d.url !== undefined) updatePayload.url = d.url;
    if (d.description !== undefined) updatePayload.description = d.description;
    if (d.icon !== undefined) updatePayload.icon = d.icon;
    if (d.isActive !== undefined) updatePayload.isActive = d.isActive;
    if (d.sortOrder !== undefined) updatePayload.sortOrder = d.sortOrder;
    if (d.linkType !== undefined) updatePayload.linkType = d.linkType;
    if (d.updatedBy !== undefined) updatePayload.updatedBy = d.updatedBy;

    await convexMutation("workflows/mutations:updateUserLink", updatePayload);

    const existing = await userLinks.findFirst({
      where: { id: args.where.id },
    });
    return existing ? { ...existing, ...d } : null;
  },

  // ── delete ──────────────────────────────────────────────────────────────
  async deleteOne(args: { where: { id: string } }) {
    if (!isConvex()) {
      return prisma.user_links.delete(args as any);
    }

    await convexMutation("workflows/mutations:deleteUserLink", {
      id: args.where.id,
    });

    return { id: args.where.id };
  },

  // ── deleteMany ──────────────────────────────────────────────────────────
  async deleteMany(args: {
    where: Record<string, unknown>;
  }): Promise<BatchResult> {
    if (!isConvex()) {
      return prisma.user_links.deleteMany(args as any);
    }

    const where = args.where;
    const userId = where.userId as string | undefined;

    const docs =
      (await convexQuery<ConvexDoc[]>("workflows/queries:getUserLinks", {
        ...(userId ? { userId } : { userId: "" }),
        limit: 10000,
      })) || [];

    let matching = docs;
    if (where.linkType) {
      matching = matching.filter((d) => d.linkType === where.linkType);
    }
    if (where.isActive !== undefined) {
      matching = matching.filter((d) => d.isActive === where.isActive);
    }

    for (const doc of matching) {
      await convexMutation("workflows/mutations:deleteUserLink", {
        id: doc._id,
      });
    }

    return { count: matching.length };
  },
};

// ── Namespace Exports ─────────────────────────────────────────────────────

export const userWorkflowsAdapter = {
  findMany: userWorkflows.findMany,
  findFirst: userWorkflows.findFirst,
  findUnique: userWorkflows.findUnique,
  count: userWorkflows.count,
  create: userWorkflows.create,
  update: userWorkflows.update,
  updateMany: userWorkflows.updateMany,
  delete: userWorkflows.deleteOne,
  deleteMany: userWorkflows.deleteMany,
};

export const userApiCredentialsAdapter = {
  findMany: userApiCredentials.findMany,
  findFirst: userApiCredentials.findFirst,
  findUnique: userApiCredentials.findUnique,
  count: userApiCredentials.count,
  create: userApiCredentials.create,
  update: userApiCredentials.update,
  delete: userApiCredentials.deleteOne,
  deleteMany: userApiCredentials.deleteMany,
};

export const userLinksAdapter = {
  findMany: userLinks.findMany,
  findFirst: userLinks.findFirst,
  findUnique: userLinks.findUnique,
  count: userLinks.count,
  create: userLinks.create,
  update: userLinks.update,
  delete: userLinks.deleteOne,
  deleteMany: userLinks.deleteMany,
};
