import { ok, type ReadonlyDB } from "@tailor-platform/erp-kit/core";
import type { DB } from "../generated/kysely-tailordb";
import { buildTree } from "../lib/buildTree";

export interface GetProfitCenterHierarchyInput {
  id: string;
}

async function loadNodesWithProfitCenters(db: ReadonlyDB<DB>, hierarchyId: string) {
  const nodes = await db
    .selectFrom("ProfitCenterHierarchyNode")
    .selectAll()
    .where("hierarchyId", "=", hierarchyId)
    .orderBy("level", "asc")
    .orderBy("sortOrder", "asc")
    .execute();

  return Promise.all(
    nodes.map(async (node) => {
      const profitCenters = await db
        .selectFrom("ProfitCenterHierarchyAssignment")
        .innerJoin(
          "ProfitCenter",
          "ProfitCenter.id",
          "ProfitCenterHierarchyAssignment.profitCenterId",
        )
        .selectAll("ProfitCenter")
        .where("ProfitCenterHierarchyAssignment.hierarchyNodeId", "=", node.id)
        .execute();
      return { ...node, profitCenters };
    }),
  );
}

/**
 * Function: getProfitCenterHierarchy
 *
 * Retrieves a single profit center hierarchy by id, along with its hierarchy nodes
 * and the profit centers assigned to each node.
 */
export async function run(db: ReadonlyDB<DB>, input: GetProfitCenterHierarchyInput) {
  const hierarchy = await db
    .selectFrom("ProfitCenterHierarchy")
    .selectAll()
    .where("id", "=", input.id)
    .executeTakeFirst();

  if (!hierarchy) {
    return ok({ profitCenterHierarchy: null, nodes: [] });
  }

  const nodesWithProfitCenters = await loadNodesWithProfitCenters(db, input.id);
  const nodes = buildTree(nodesWithProfitCenters);

  return ok({ profitCenterHierarchy: hierarchy, nodes });
}
