import { randomUUID } from "crypto";
import type { ConvexHttpClient } from "convex/browser";
import type { FunctionReference } from "convex/server";
import type { SidebarInitialData } from "@/components/sidebar/types";
import type { DocumentRecord } from "@/lib/documents";
import { api } from "@/lib/convex/api";
import {
  mapSidebarDatasetListQueryResultToInitialData,
  type SidebarDatasetListQueryResult,
} from "@/lib/sidebar-data";
import type { WorkspaceSummary } from "@/lib/workspaces";
import {
  attachKernelFileTreeProjection,
  resolveKernelFileTreeProjection,
} from "@/lib/server/kernel-file-tree";
import type { AuthContext } from "@/lib/auth/types";

type LoadSidebarDataFromConvexInput = {
  client: ConvexHttpClient;
  auth: AuthContext;
  fallbackName: string;
  requestedWorkspaceId?: string | null;
};

type LoadSidebarDataFromConvexResult = {
  workspaces: WorkspaceSummary[];
  activeWorkspaceId: string;
  targetWorkspaceId: string | null;
  sidebarDataset: SidebarDatasetListQueryResult | null;
  sidebarInitialData: SidebarInitialData | null;
  documents: DocumentRecord[];
};

const sidebarDatasetListQuery = ((api as unknown as Record<string, unknown>).sidebar as
  | Record<string, unknown>
  | undefined)?.datasetList as FunctionReference<
  "query",
  "public",
  { workspaceId: string },
  SidebarDatasetListQueryResult
>;

export async function loadSidebarDataFromConvex(
  input: LoadSidebarDataFromConvexInput,
): Promise<LoadSidebarDataFromConvexResult> {
  const bootstrap = await input.client.mutation(api.workspaces.ensureDefaultWorkspace, {
    fallbackName: input.fallbackName,
    workspaceIdIfCreate: randomUUID(),
  });

  const workspaces = bootstrap.workspaces;
  const activeWorkspaceId = bootstrap.activeWorkspaceId;
  const targetWorkspaceId = input.requestedWorkspaceId?.trim() || activeWorkspaceId || null;

  if (!targetWorkspaceId) {
    return {
      workspaces,
      activeWorkspaceId,
      targetWorkspaceId: null,
      sidebarDataset: null,
      sidebarInitialData: null,
      documents: [],
    };
  }

  // 说明：SSR 首屏阶段必须优先保证“可进入页面”。
  // mnote-web compat sidebar 仍处于渐进接入期，若这里优先走远端/Rust 兼容接口，
  // 一旦 actor/header 权限链不一致，就会把整个 (app) layout 阻塞住，表现为“登录后进不去页面”。
  // 因此服务端首屏一律先走稳定的 Convex 直查；mnote-web 仅允许用于客户端树壳渐进增强。
  const sidebarDataset = (await input.client.query(sidebarDatasetListQuery, {
    workspaceId: targetWorkspaceId,
  })) as SidebarDatasetListQueryResult;
  const syntheticRequest = new Request(`http://127.0.0.1:3000/api/sidebar?workspaceId=${targetWorkspaceId}`);
  const sidebarDatasetWithFileTree = attachKernelFileTreeProjection({
    dataset: sidebarDataset,
    projection: await resolveKernelFileTreeProjection({
      client: input.client,
      request: syntheticRequest,
      workspaceId: targetWorkspaceId,
      actor: {
        actorType: "user",
        actorId: input.auth.userId,
        sessionId: null,
      },
      dataset: sidebarDataset,
    }),
  });
  const normalizedDocuments = (sidebarDatasetWithFileTree.documents ?? []) as DocumentRecord[];

  return {
    workspaces: sidebarDatasetWithFileTree.workspaces ?? workspaces,
    activeWorkspaceId,
    targetWorkspaceId,
    sidebarDataset: sidebarDatasetWithFileTree,
    sidebarInitialData: mapSidebarDatasetListQueryResultToInitialData(sidebarDatasetWithFileTree),
    documents: normalizedDocuments,
  };
}
