import { PermissionKey } from "@capakraken/shared";
import { z } from "zod";
import type { TRPCContext } from "../trpc.js";
import { requirePermission } from "../trpc.js";
import { applyProjectScenario } from "./scenario-apply.js";
import { readProjectScenarioBaseline } from "./scenario-baseline.js";
import { simulateProjectScenario } from "./scenario-simulation.js";

export const ScenarioChangeSchema = z.object({
  assignmentId: z.string().optional(),
  resourceId: z.string().optional(),
  roleId: z.string().optional(),
  startDate: z.coerce.date(),
  endDate: z.coerce.date(),
  hoursPerDay: z.number().min(0).max(24),
  remove: z.boolean().optional(),
});

export const ScenarioProjectIdInputSchema = z.object({
  projectId: z.string(),
});

export const ScenarioSimulationInputSchema = z.object({
  projectId: z.string(),
  changes: z.array(ScenarioChangeSchema).min(1),
});

type ScenarioBaselineContext = Pick<TRPCContext, "db" | "dbUser"> & {
  permissions: Set<PermissionKey>;
};

export async function getProjectScenarioBaseline(
  ctx: ScenarioBaselineContext,
  input: z.infer<typeof ScenarioProjectIdInputSchema>,
) {
  requirePermission(ctx, PermissionKey.VIEW_COSTS);
  return readProjectScenarioBaseline(ctx.db, input.projectId);
}

export async function simulateScenario(
  ctx: Pick<TRPCContext, "db">,
  input: z.infer<typeof ScenarioSimulationInputSchema>,
) {
  return simulateProjectScenario(ctx.db, input);
}

export async function applyScenario(
  ctx: Pick<TRPCContext, "db" | "dbUser">,
  input: z.infer<typeof ScenarioSimulationInputSchema>,
) {
  return applyProjectScenario(ctx.db, {
    ...input,
    ...(ctx.dbUser?.id ? { userId: ctx.dbUser.id } : {}),
  });
}
