type SystemRoleRecord = {
  code: string;
  name: string;
  description: string;
  is_system_role: true;
};

type RoleWriteClient = {
  role: {
    upsert(args: {
      where: { code: string };
      update: Omit<SystemRoleRecord, "code">;
      create: SystemRoleRecord;
    }): Promise<unknown>;
  };
};

export const systemRoles = [
  {
    code: "admin",
    name: "Admin",
    description: "Full tenant administration access",
    is_system_role: true,
  },
  {
    code: "partner",
    name: "Partner",
    description: "Firm leadership with strategic and approval access",
    is_system_role: true,
  },
  {
    code: "attorney",
    name: "Attorney",
    description: "Case owner and legal reviewer",
    is_system_role: true,
  },
  {
    code: "paralegal",
    name: "Paralegal",
    description: "Operational case preparation and document management",
    is_system_role: true,
  },
  {
    code: "intake",
    name: "Intake",
    description: "Lead intake and client onboarding",
    is_system_role: true,
  },
  {
    code: "assistant",
    name: "Assistant",
    description: "Administrative support and coordination",
    is_system_role: true,
  },
  {
    code: "reviewer",
    name: "Reviewer",
    description: "Quality control and legal review",
    is_system_role: true,
  },
] as const satisfies readonly SystemRoleRecord[];

function getSystemRoleRecord(roleCode: string) {
  const role = systemRoles.find((candidate) => candidate.code === roleCode);

  if (!role) {
    throw new Error(`Unknown system role code: ${roleCode}`);
  }

  return role;
}

export async function ensureSystemRole(db: RoleWriteClient, roleCode: string) {
  const role = getSystemRoleRecord(roleCode);

  await db.role.upsert({
    where: { code: role.code },
    update: {
      name: role.name,
      description: role.description,
      is_system_role: role.is_system_role,
    },
    create: { ...role },
  });

  return role;
}

export async function ensureSystemRoles(db: RoleWriteClient) {
  for (const role of systemRoles) {
    await ensureSystemRole(db, role.code);
  }
}
