import { prisma } from "@capakraken/db";

type PrismaClient = typeof prisma;

export interface TaskActionResult {
  success: boolean;
  message: string;
}

export interface TaskActionHandler {
  /** PermissionKey string value required to execute this action */
  permission: string;
  execute: (entityId: string, db: PrismaClient, executorId: string) => Promise<TaskActionResult>;
}

export const TASK_ACTION_REGISTRY: Record<string, TaskActionHandler> = {
  approve_vacation: {
    permission: "approveVacations",
    execute: async (vacationId, db, _executorId) => {
      const vacation = await db.vacation.findUnique({
        where: { id: vacationId },
        select: { id: true, status: true },
      });
      if (!vacation) return { success: false, message: "Vacation not found" };
      if (vacation.status !== "PENDING") {
        return { success: false, message: `Vacation is ${vacation.status}, not PENDING` };
      }
      await db.vacation.update({
        where: { id: vacationId },
        data: { status: "APPROVED" },
      });
      return { success: true, message: "Vacation approved" };
    },
  },

  reject_vacation: {
    permission: "approveVacations",
    execute: async (vacationId, db, _executorId) => {
      const vacation = await db.vacation.findUnique({
        where: { id: vacationId },
        select: { id: true, status: true },
      });
      if (!vacation) return { success: false, message: "Vacation not found" };
      if (vacation.status !== "PENDING") {
        return { success: false, message: `Vacation is ${vacation.status}, not PENDING` };
      }
      await db.vacation.update({
        where: { id: vacationId },
        data: { status: "REJECTED" },
      });
      return { success: true, message: "Vacation rejected" };
    },
  },

  confirm_assignment: {
    permission: "manageAllocations",
    execute: async (assignmentId, db, _executorId) => {
      const assignment = await db.assignment.findUnique({
        where: { id: assignmentId },
        select: { id: true, status: true },
      });
      if (!assignment) return { success: false, message: "Assignment not found" };
      if (assignment.status === "CONFIRMED") {
        return { success: false, message: "Assignment is already CONFIRMED" };
      }
      await db.assignment.update({
        where: { id: assignmentId },
        data: { status: "CONFIRMED" },
      });
      return { success: true, message: "Assignment confirmed" };
    },
  },
};

export function getTaskAction(actionName: string): TaskActionHandler | undefined {
  return TASK_ACTION_REGISTRY[actionName];
}
