import type { PrismaClient } from "@capakraken/db";
import { AllocationStatus } from "@capakraken/shared";
import { buildSplitAllocationReadModel } from "../allocation/build-split-allocation-read-model.js";

export const DASHBOARD_PLANNING_ALLOCATION_INCLUDE = {
  project: {
    select: {
      id: true,
      name: true,
      shortCode: true,
      staffingReqs: true,
    },
  },
  resource: {
    select: {
      id: true,
      displayName: true,
      chapter: true,
      eid: true,
      lcrCents: true,
      availability: true,
      countryId: true,
      federalState: true,
      metroCityId: true,
      country: {
        select: {
          code: true,
          name: true,
        },
      },
      metroCity: {
        select: {
          name: true,
        },
      },
    },
  },
} as const;

export const DASHBOARD_PLANNING_DEMAND_INCLUDE = {
  project: DASHBOARD_PLANNING_ALLOCATION_INCLUDE.project,
} as const;

export const DASHBOARD_PLANNING_ASSIGNMENT_INCLUDE = {
  project: DASHBOARD_PLANNING_ALLOCATION_INCLUDE.project,
  resource: DASHBOARD_PLANNING_ALLOCATION_INCLUDE.resource,
} as const;

type DashboardPlanningReadDbClient = Pick<
  PrismaClient,
  "demandRequirement" | "assignment" | "project"
>;

export interface LoadDashboardPlanningReadModelInput {
  startDate: Date;
  endDate: Date;
}

export async function loadDashboardPlanningReadModel(
  db: DashboardPlanningReadDbClient,
  input: LoadDashboardPlanningReadModelInput,
) {
  const activeWindowFilter = {
    status: { not: AllocationStatus.CANCELLED },
    startDate: { lte: input.endDate },
    endDate: { gte: input.startDate },
  } as const;

  const [demandRequirements, assignments, projects] = await Promise.all([
    db.demandRequirement.findMany({
      where: activeWindowFilter,
      include: DASHBOARD_PLANNING_DEMAND_INCLUDE,
    }),
    db.assignment.findMany({
      where: activeWindowFilter,
      include: DASHBOARD_PLANNING_ASSIGNMENT_INCLUDE,
    }),
    db.project.findMany({
      where: activeWindowFilter,
      select: { id: true, shortCode: true, name: true, staffingReqs: true },
    }),
  ]);

  return {
    demandRequirements,
    assignments,
    projects,
    readModel: buildSplitAllocationReadModel({
      demandRequirements,
      assignments,
    }),
  };
}
