import { getAuthedConvexClient } from "@/lib/convex/route";
import {
  type CommandEnvelope,
  type BridgeContext,
} from "@/lib/documents/bridge";
import {
  recordBridgeCommandFailureArtifacts,
  recordRustBridgeCommandArtifacts,
} from "@/lib/documents/bridge-log";
import {
  executeRustBridgeMutationTransport,
  resolveRustBridgeCommandPlan,
} from "@/lib/documents/rust-runtime";
import type { PageOptionsState } from "@/types/page-options";

export type DocumentTitleUpdatePayload = {
  documentId: string;
  workspaceId: string | null;
  title: string;
};

export type DocumentStatsUpdatePayload = {
  documentId: string;
  workspaceId: string | null;
  stats: {
    wordCount: number;
    characterCount: number;
    blockCount: number;
    todoTotal: number;
    todoDone: number;
  };
};

export type DocumentOptionsUpdatePayload = {
  documentId: string;
  workspaceId: string | null;
  options: Partial<PageOptionsState>;
};

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

export async function executeMetadataBridgeCommand<TPayload>(input: {
  context: BridgeContext;
  envelope: CommandEnvelope<TPayload>;
}): Promise<MetadataCommandExecutionResult> {
  const { client } = await getAuthedConvexClient();
  try {
    const plan = await resolveRustBridgeCommandPlan({
      context: input.context,
      envelope: input.envelope,
    });
    const transportResult = await executeRustBridgeMutationTransport({
      client,
      plan,
    });
    await recordRustBridgeCommandArtifacts({
      client,
      context: input.context,
      envelope: input.envelope,
      plan,
      result: transportResult,
    });
  } catch (error) {
    await recordBridgeCommandFailureArtifacts({
      context: input.context,
      envelope: input.envelope,
      client,
      error,
    });
    throw error;
  }

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