import { headers } from "next/headers";
import { api } from "@/lib/convex/api";
import { getAuthedConvexClient } from "@/lib/convex/route";
import {
  buildDocumentBridgeContext,
  buildDocumentQueryEnvelope,
  type BridgeContext,
} from "@/lib/documents/bridge";
import type { PageAggregateProjection } from "@/lib/documents/page-aggregate";
import {
  buildPageAggregateFromDocumentPayloads,
  type DocumentContentPayload,
  type DocumentMetaPayload,
} from "@/lib/documents/page-aggregate-builder";
import {
  executeRustBridgeQueryTransport,
  resolveRustBridgeQueryPlan,
} from "@/lib/documents/rust-runtime";

const FORWARDED_REQUEST_HEADERS = [
  "cookie",
  "authorization",
  "x-request-id",
  "x-trace-id",
  "x-session-id",
  "x-source-channel",
  "x-source-client",
  "user-agent",
] as const;

export type LoadedPageAggregate = {
  page: PageAggregateProjection;
  bridge: {
    requestId: string;
    traceId: string;
    queryName: "documents.page.get";
  };
};

function copyForwardHeaderIfPresent(target: Headers, source: Headers, name: string) {
  const value = source.get(name);
  if (value) {
    target.set(name, value);
  }
}

async function buildServerBridgeRequest(pathname: string): Promise<Request> {
  const headerList = await headers();
  const requestHeaders = new Headers();
  FORWARDED_REQUEST_HEADERS.forEach((name) => {
    copyForwardHeaderIfPresent(requestHeaders, headerList, name);
  });

  return new Request(`http://mnote.local${pathname}`, {
    method: "GET",
    headers: requestHeaders,
  });
}

async function fetchDocumentContentPayload(input: {
  context: BridgeContext;
  documentId: string;
  workspaceId: string;
}): Promise<DocumentContentPayload | null> {
  const { client } = await getAuthedConvexClient();
  const envelope = buildDocumentQueryEnvelope({
    name: "documents.content.get",
    payload: {
      documentId: input.documentId,
      workspaceId: input.workspaceId,
    },
  });
  const plan = await resolveRustBridgeQueryPlan({
    context: input.context,
    envelope,
  });

  return executeRustBridgeQueryTransport<DocumentContentPayload | null>({
    client,
    plan,
  });
}

export async function loadPageAggregate(input: {
  request: Request;
  documentId: string;
  workspaceId?: string | null;
}): Promise<LoadedPageAggregate | null> {
  const { client } = await getAuthedConvexClient();
  const meta = await client.query(api.documents.getMeta, {
    id: input.documentId,
  });

  if (!meta) {
    return null;
  }

  const workspaceId = input.workspaceId?.trim() || meta.workspace_id;
  const context = await buildDocumentBridgeContext({
    request: input.request,
    workspaceId,
  });
  const contentPayload = await fetchDocumentContentPayload({
    context,
    documentId: meta.id,
    workspaceId,
  });

  return {
    page: buildPageAggregateFromDocumentPayloads({
      meta,
      contentPayload,
    }),
    bridge: {
      requestId: context.requestId,
      traceId: context.traceId,
      queryName: "documents.page.get",
    },
  };
}

export async function loadPageAggregateFromNextHeaders(input: {
  documentId: string;
  workspaceId?: string | null;
}): Promise<LoadedPageAggregate | null> {
  const request = await buildServerBridgeRequest("/documents/page");
  return loadPageAggregate({
    request,
    documentId: input.documentId,
    workspaceId: input.workspaceId,
  });
}
