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

const ScenarioChangeSchema = z.object({
  /** Existing assignment to modify — omit to add a new allocation */
  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),
  /** Set to true to mark an existing assignment for removal */
  remove: z.boolean().optional(),
});

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

export const scenarioRouter = createTRPCRouter({
  /**
   * Returns current allocations/costs for a project — the baseline for comparison.
   */
  getProjectBaseline: planningReadProcedure
    .input(z.object({ projectId: z.string() }))
    .query(async ({ ctx, input }) => {
      requirePermission(ctx, PermissionKey.VIEW_COSTS);
      return readProjectScenarioBaseline(ctx.db, input.projectId);
    }),

  /**
   * Pure simulation: computes cost/hours/utilization impact of scenario changes
   * without persisting anything.
   */
  simulate: controllerProcedure
    .input(SimulateInputSchema)
    .mutation(async ({ ctx, input }) => simulateProjectScenario(ctx.db, input)),

  /**
   * Applies a scenario: creates real assignments from scenario changes.
   * Manager+ access required.
   */
  applyScenario: controllerProcedure
    .input(SimulateInputSchema)
    .mutation(async ({ ctx, input }) => applyProjectScenario(ctx.db, {
      ...input,
      userId: ctx.dbUser?.id,
    })),
});
