import "server-only";
import { redirect } from "next/navigation";
import { db } from "./db";
import { requireUser } from "./auth";
import { VOLUNTEER_AREAS, type ConfRole } from "./constants";

// Conference-scoped permission actions
export type Action =
  | "conference.manage"     // settings, publish, delete
  | "conference.view"       // see the workspace at all
  | "registrations.manage"
  | "registrations.export"   // CSV/data export — staff only, never volunteers
  | "agenda.manage"
  | "speakers.manage"
  | "checkin.perform"
  | "finance.view"
  | "submissions.manage"    // CFP pipeline, assign reviewers, decide
  | "submissions.review"    // write reviews
  | "sponsors.manage"
  | "content.manage"        // announcements, pages
  | "certificates.manage"
  | "volunteers.manage";

const ROLE_ACTIONS: Record<ConfRole, Action[]> = {
  ORGANIZER: [
    "conference.manage", "conference.view", "registrations.manage", "registrations.export", "agenda.manage",
    "speakers.manage", "checkin.perform", "finance.view", "submissions.manage",
    "submissions.review", "sponsors.manage", "content.manage", "certificates.manage",
    "volunteers.manage",
  ],
  CO_ORGANIZER: [
    "conference.manage", "conference.view", "registrations.manage", "registrations.export", "agenda.manage",
    "speakers.manage", "checkin.perform", "finance.view", "submissions.manage",
    "sponsors.manage", "content.manage", "certificates.manage", "volunteers.manage",
  ],
  EVENT_MANAGER: [
    "conference.view", "registrations.manage", "registrations.export", "agenda.manage", "speakers.manage",
    "checkin.perform", "content.manage", "certificates.manage", "volunteers.manage",
  ],
  MODERATOR: ["conference.view", "agenda.manage"],
  VOLUNTEER: ["conference.view"],
  REVIEWER: ["conference.view", "submissions.review"],
  FINANCE_MANAGER: ["conference.view", "finance.view", "registrations.manage", "registrations.export"],
  CONTENT_MANAGER: ["conference.view", "content.manage"],
};

export type Membership = { roles: ConfRole[]; isSuperAdmin: boolean; volunteerAreas: string[] };

export async function getMembership(userId: string, conferenceId: string): Promise<Membership> {
  const [user, members, volunteer] = await Promise.all([
    db.user.findUnique({ where: { id: userId }, select: { platformRole: true } }),
    db.confMember.findMany({ where: { conferenceId, userId }, select: { role: true } }),
    db.volunteer.findFirst({ where: { conferenceId, userId }, select: { areas: true } }),
  ]);
  let volunteerAreas: string[] = [];
  try { volunteerAreas = volunteer ? JSON.parse(volunteer.areas) : []; } catch { /* malformed areas */ }
  return {
    roles: members.map((m) => m.role as ConfRole),
    isSuperAdmin: user?.platformRole === "SUPER_ADMIN",
    volunteerAreas,
  };
}

export function can(membership: Membership, action: Action): boolean {
  if (membership.isSuperAdmin) return true;
  if (membership.roles.some((r) => ROLE_ACTIONS[r]?.includes(action))) return true;
  // volunteer area assignments grant exactly one action each
  return membership.volunteerAreas.some(
    (key) => VOLUNTEER_AREAS.find((a) => a.key === key)?.action === action
  );
}

/** Auth + membership gate for workspace pages and server actions. Redirects if not permitted. */
export async function requireConfAccess(conferenceId: string, action: Action = "conference.view") {
  const user = await requireUser();
  const membership = await getMembership(user.id, conferenceId);
  if (!can(membership, action)) redirect("/dashboard");
  return { user, membership };
}
