import "server-only";
import { prisma } from "@/lib/prisma";
import { PERMISSIONS, MODULES } from "@/lib/rbac/catalog";

export type AdminUser = {
  id: string;
  name: string;
  email: string;
  jobTitle: string | null;
  status: string;
  avatarUrl: string | null;
  lastLoginAt: string | null;
  roleIds: string[];
  roleNames: string[];
  teamNames: string[];
  supervisorId: string | null;
  supervisorName: string | null;
  vacationDaysPerYear: number;
};

export async function getAdminUsers(): Promise<AdminUser[]> {
  const users = await prisma.user.findMany({
    orderBy: { createdAt: "asc" },
    select: {
      id: true,
      name: true,
      email: true,
      jobTitle: true,
      status: true,
      avatarUrl: true,
      lastLoginAt: true,
      supervisorId: true,
      vacationDaysPerYear: true,
      supervisor: { select: { name: true, displayName: true } },
      roles: { select: { roleId: true, role: { select: { name: true } } } },
      teamMemberships: { select: { team: { select: { name: true } } } },
    },
  });
  return users.map((u) => ({
    id: u.id,
    name: u.name,
    email: u.email,
    jobTitle: u.jobTitle,
    status: u.status,
    avatarUrl: u.avatarUrl,
    lastLoginAt: u.lastLoginAt ? u.lastLoginAt.toISOString() : null,
    roleIds: u.roles.map((r) => r.roleId),
    roleNames: u.roles.map((r) => r.role.name),
    teamNames: u.teamMemberships.map((t) => t.team.name),
    supervisorId: u.supervisorId,
    supervisorName: u.supervisor ? u.supervisor.displayName ?? u.supervisor.name : null,
    vacationDaysPerYear: u.vacationDaysPerYear,
  }));
}

export type AdminRole = {
  id: string;
  key: string;
  name: string;
  description: string | null;
  isSystem: boolean;
  rank: number;
  userCount: number;
  permissionKeys: string[];
};

export async function getAdminRoles(): Promise<AdminRole[]> {
  const roles = await prisma.role.findMany({
    orderBy: { rank: "asc" },
    select: {
      id: true,
      key: true,
      name: true,
      description: true,
      isSystem: true,
      rank: true,
      _count: { select: { users: true } },
      permissions: { select: { permission: { select: { key: true } } } },
    },
  });
  return roles.map((r) => ({
    id: r.id,
    key: r.key,
    name: r.name,
    description: r.description,
    isSystem: r.isSystem,
    rank: r.rank,
    userCount: r._count.users,
    permissionKeys: r.permissions.map((p) => p.permission.key),
  }));
}

/** Berechtigungen nach Modul gruppiert (für die Rollen-Matrix). */
export type PermissionGroup = { module: string; moduleLabel: string; items: { key: string; description: string }[] };

export function getPermissionGroups(): PermissionGroup[] {
  const byModule = new Map<string, { key: string; description: string }[]>();
  for (const [key, def] of Object.entries(PERMISSIONS)) {
    const list = byModule.get(def.module) ?? [];
    list.push({ key, description: def.description });
    byModule.set(def.module, list);
  }
  return Array.from(byModule.entries()).map(([module, items]) => ({
    module,
    moduleLabel: (MODULES as Record<string, string>)[module] ?? module,
    items,
  }));
}

export type AdminTeam = {
  id: string;
  key: string;
  name: string;
  description: string | null;
  color: string | null;
  memberIds: string[];
  members: { id: string; name: string; avatarUrl: string | null }[];
  boardIds: string[];
  boards: { id: string; name: string }[];
};

export async function getAdminTeams(): Promise<AdminTeam[]> {
  const teams = await prisma.team.findMany({
    orderBy: { createdAt: "asc" },
    select: {
      id: true,
      key: true,
      name: true,
      description: true,
      color: true,
      members: {
        select: { user: { select: { id: true, name: true, displayName: true, avatarUrl: true } } },
      },
      boardLinks: { select: { board: { select: { id: true, name: true } } } },
    },
  });
  return teams.map((t) => ({
    id: t.id,
    key: t.key,
    name: t.name,
    description: t.description,
    color: t.color,
    memberIds: t.members.map((m) => m.user.id),
    members: t.members.map((m) => ({
      id: m.user.id,
      name: m.user.displayName ?? m.user.name,
      avatarUrl: m.user.avatarUrl,
    })),
    boardIds: t.boardLinks.map((b) => b.board.id),
    boards: t.boardLinks.map((b) => ({ id: b.board.id, name: b.board.name })),
  }));
}

export type PickerUser = { id: string; name: string; avatarUrl: string | null };
export async function getUserPicker(): Promise<PickerUser[]> {
  const users = await prisma.user.findMany({
    orderBy: { name: "asc" },
    select: { id: true, name: true, displayName: true, avatarUrl: true },
  });
  return users.map((u) => ({ id: u.id, name: u.displayName ?? u.name, avatarUrl: u.avatarUrl }));
}

export type PickerBoard = { id: string; name: string; isDefault: boolean };
export async function getBoardPicker(): Promise<PickerBoard[]> {
  return prisma.board.findMany({
    orderBy: [{ isDefault: "desc" }, { createdAt: "asc" }],
    select: { id: true, name: true, isDefault: true },
  });
}

export async function getRolePicker(): Promise<{ id: string; name: string }[]> {
  return prisma.role.findMany({ orderBy: { rank: "asc" }, select: { id: true, name: true } });
}
