import type { ConvexHttpClient } from "convex/browser";
import type { Id } from "../../../convex/_generated/dataModel";
import { api } from "@/lib/convex/api";
import {
  buildDocumentBridgeMutationRequest,
  executeDocumentBridgeMutationRequest,
  type CommandEnvelope,
  type BridgeContext,
} from "@/lib/documents/bridge";
import {
  recordBridgeCommandArtifacts,
  recordBridgeCommandFailureArtifacts,
} from "@/lib/documents/bridge-log";

export type MediaAssetReplaceStoragePayload = {
  assetId: string;
  documentId: string;
  workspaceId: string | null;
  storageId: string;
  userId: string;
};

export type MediaAssetWritebackExecutionResult = {
  requestId: string;
  traceId: string;
  commandId: string;
  commandName: string;
};

export async function executeMediaAssetWritebackBridgeCommand(input: {
  client: ConvexHttpClient;
  context: BridgeContext;
  envelope: CommandEnvelope<MediaAssetReplaceStoragePayload>;
}): Promise<MediaAssetWritebackExecutionResult> {
  const mutationRequest = buildDocumentBridgeMutationRequest({
    context: input.context,
    envelope: input.envelope,
    mapConvexArgs: (payload) => ({
      userId: payload.userId,
      id: payload.assetId,
      storageId: payload.storageId as Id<"_storage">,
    }),
  });

  try {
    await executeDocumentBridgeMutationRequest({
      client: input.client,
      mutation: api.mediaAssets.replaceStorageFromUpload,
      request: mutationRequest,
    });
  } catch (error) {
    await recordBridgeCommandFailureArtifacts({
      client: input.client,
      context: input.context,
      envelope: input.envelope,
      error,
    });
    throw error;
  }

  try {
    await recordBridgeCommandArtifacts({
      client: input.client,
      context: input.context,
      envelope: input.envelope,
    });
  } catch (error) {
    // 说明：OnlyOffice callback 写回的主事实是附件存储替换；日志落账失败不应反向导致保存失败。
    console.warn("[onlyoffice/callback] bridge log write skipped:", error);
  }

  return {
    requestId: input.context.requestId,
    traceId: input.context.traceId,
    commandId: input.envelope.commandId,
    commandName: input.envelope.name,
  };
}
