import { getAuthedConvexClient } from "@/lib/convex/route";
import {
  type BridgeContext,
  type CommandEnvelope,
  DocumentBridgeError,
} from "@/lib/documents/bridge";
import {
  recordBridgeCommandFailureArtifacts,
  recordRustBridgeCommandArtifacts,
} from "@/lib/documents/bridge-log";
import type { DocumentOptionsUpdatePayload, DocumentTitleUpdatePayload } from "@/lib/documents/metadata-command-adapter";
import type { DocumentSavePayload } from "@/lib/documents/save-contract";
import {
  executeRustBridgeMutationTransport,
  resolveRustBridgeCommandPlan,
} from "@/lib/documents/rust-runtime";

type PageWritePayload =
  | DocumentTitleUpdatePayload
  | DocumentOptionsUpdatePayload
  | DocumentSavePayload;

export type PageWriteCommandExecutionResult = {
  requestId: string;
  traceId: string;
  commandId: string;
  commandName: string;
  revision: number | null;
  conflictDetectionKey: string | null;
};

function normalizePersistedMeta(result: unknown): Pick<PageWriteCommandExecutionResult, "revision" | "conflictDetectionKey"> {
  const record = result && typeof result === "object" ? (result as Record<string, unknown>) : null;
  return {
    revision:
      typeof record?.revision === "number" && Number.isInteger(record.revision)
        ? record.revision
        : null,
    conflictDetectionKey:
      typeof record?.conflict_detection_key === "string" && record.conflict_detection_key.trim()
        ? record.conflict_detection_key.trim()
        : null,
  };
}

export async function executePageWriteBridgeCommand<TPayload extends PageWritePayload>(input: {
  context: BridgeContext;
  envelope: CommandEnvelope<TPayload>;
}): Promise<PageWriteCommandExecutionResult> {
  const { client } = await getAuthedConvexClient();

  try {
    const plan = await resolveRustBridgeCommandPlan({
      context: input.context,
      envelope: input.envelope,
    });
    const transportResult = await executeRustBridgeMutationTransport({
      client,
      plan,
    });
    const persistedMeta = normalizePersistedMeta(transportResult);

    await recordRustBridgeCommandArtifacts({
      client,
      context: input.context,
      envelope: input.envelope,
      plan,
      result: transportResult,
    });

    return {
      requestId: input.context.requestId,
      traceId: input.context.traceId,
      commandId: input.envelope.commandId,
      commandName: input.envelope.name,
      revision: persistedMeta.revision,
      conflictDetectionKey: persistedMeta.conflictDetectionKey,
    };
  } catch (error) {
    await recordBridgeCommandFailureArtifacts({
      context: input.context,
      envelope: input.envelope,
      client,
      error,
    });
    if (
      input.envelope.name === "page.body.save" &&
      error instanceof Error &&
      /正文(内容已变更|冲突检测失败)/.test(error.message)
    ) {
      throw new DocumentBridgeError(error.message, 409, "REJECTED", {
        reason: "content_conflict",
        revision: (input.envelope.payload as DocumentSavePayload).revision,
        conflictDetectionKey: (input.envelope.payload as DocumentSavePayload).conflictDetectionKey,
      });
    }
    throw error;
  }
}
