import {
  getMember,
  updateRoom,
  getPendingRequests,
  approveRequest,
  rejectRequest,
  banMember,
  setMemberRole,
  createRoomMessage,
} from "../../../../db/chat-rooms";
import { getUsersMeta } from "../../../../utils/getUsersMeta";

/** PATCH /api/chat/rooms/[roomId] – Room editieren + Anfragen verwalten */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);
  const roomId = getRouterParam(event, "roomId");
  if (!roomId) throw createError({ statusCode: 400, message: "roomId fehlt" });

  const member = await getMember(roomId, user.id);
  if (!member || (member.role !== "owner" && member.role !== "admin")) {
    throw createError({
      statusCode: 403,
      message: "Nur Admins können den Raum bearbeiten",
    });
  }

  const body = await readBody(event);

  // Handle join request approval/rejection
  if (body?.action === "approve" && body?.targetUserId) {
    await approveRequest(roomId, body.targetUserId);
    return { ok: true, action: "approved" };
  }
  if (body?.action === "reject" && body?.targetUserId) {
    await rejectRequest(roomId, body.targetUserId);
    return { ok: true, action: "rejected" };
  }

  // Handle pending requests list
  if (body?.action === "list_requests") {
    const requests = await getPendingRequests(roomId);
    const userIds = requests.map((r) => r.userId);
    const meta = userIds.length > 0 ? await getUsersMeta(userIds) : {};
    return requests.map((r) => ({
      userId: r.userId,
      nickname: meta[r.userId]?.nickname ?? "Anonym",
      avatar: meta[r.userId]?.avatar ?? null,
      requestedAt: r.joinedAt,
    }));
  }

  // Ban member – owner OR admin can ban regular members (not other admins unless owner)
  if (body?.action === "ban" && body?.targetUserId) {
    const target = await getMember(roomId, body.targetUserId);
    if (!target)
      throw createError({
        statusCode: 404,
        message: "Mitglied nicht gefunden",
      });
    if (target.role === "owner")
      throw createError({
        statusCode: 403,
        message: "Owner kann nicht gebannt werden",
      });
    // Admins dürfen keine anderen Admins bannen – nur Owner darf das
    if (target.role === "admin" && member.role !== "owner") {
      throw createError({
        statusCode: 403,
        message: "Nur der Owner kann Admins bannen",
      });
    }
    const bannedMeta = await getUsersMeta([body.targetUserId]);
    const bannedName =
      bannedMeta[body.targetUserId]?.nickname ?? "Ein Mitglied";
    await banMember(roomId, body.targetUserId);
    // Systemnachricht in Gruppe
    const SYSTEM_ID = "00000000-0000-0000-0000-000000000000";
    await createRoomMessage({
      userId: SYSTEM_ID,
      roomId,
      content: `🚫 ${bannedName} wurde aus der Gruppe entfernt.`,
    }).catch(() => {});
    return { ok: true, action: "banned" };
  }

  // Promote member to admin – only Owner can do this (not sub-admins)
  if (body?.action === "promote_admin" && body?.targetUserId) {
    if (member.role !== "owner") {
      throw createError({
        statusCode: 403,
        message: "Nur der Owner kann Admins ernennen",
      });
    }
    const target = await getMember(roomId, body.targetUserId);
    if (!target || target.status !== "active") {
      throw createError({
        statusCode: 404,
        message: "Mitglied nicht gefunden",
      });
    }
    await setMemberRole(roomId, body.targetUserId, "admin");
    return { ok: true, action: "promoted" };
  }

  // Demote admin back to member – only Owner can do this
  if (body?.action === "demote_admin" && body?.targetUserId) {
    if (member.role !== "owner") {
      throw createError({
        statusCode: 403,
        message: "Nur der Owner kann Admins zurückstufen",
      });
    }
    await setMemberRole(roomId, body.targetUserId, "member");
    return { ok: true, action: "demoted" };
  }

  // Update room settings
  const update: Record<string, any> = {};
  if (body?.name) update.name = String(body.name).trim().slice(0, 60);
  if (body?.description !== undefined)
    update.description = String(body.description).trim().slice(0, 200) || null;
  if (
    body?.joinMode &&
    ["open", "approval", "invite_only"].includes(body.joinMode)
  ) {
    update.joinMode = body.joinMode;
  }
  if (body?.avatarUrl !== undefined) {
    update.avatarUrl = body.avatarUrl ? String(body.avatarUrl).trim() : null;
  }

  if (Object.keys(update).length > 0) {
    await updateRoom(roomId, update);
  }

  return { ok: true };
});
