import { usePrisma } from "../utils/prisma";
import { randomBytes } from "crypto";

// ─── Rooms ────────────────────────────────────────────────────────────────────

export async function listRooms(userId: string) {
  const db = usePrisma();
  // Public rooms + private rooms user is member of
  return db.chatRoom.findMany({
    where: {
      OR: [
        { isPublic: true },
        { members: { some: { userId, status: "active" } } },
      ],
    },
    orderBy: { updatedAt: "desc" },
    include: {
      // Only include current user's membership to correctly determine isMember/myRole
      members: {
        where: { userId, status: "active" },
        select: { userId: true, role: true },
      },
      messages: {
        orderBy: { createdAt: "desc" },
        take: 1,
        select: { content: true, createdAt: true, userId: true },
      },
    },
  });
}

export async function getRoom(roomId: string) {
  const db = usePrisma();
  return db.chatRoom.findUnique({
    where: { id: roomId },
    include: {
      members: {
        where: { status: "active" },
        select: { userId: true, role: true, joinedAt: true },
      },
    },
  });
}

export async function createRoom(data: {
  name: string;
  description?: string;
  isPublic: boolean;
  joinMode: string;
  createdBy: string;
  avatarUrl?: string;
}) {
  const db = usePrisma();
  const inviteCode = randomBytes(4).toString("hex");
  return db.chatRoom.create({
    data: {
      name: data.name,
      description: data.description,
      isPublic: data.isPublic,
      joinMode: data.joinMode,
      inviteCode,
      createdBy: data.createdBy,
      avatarUrl: data.avatarUrl,
      memberCount: 1,
      members: {
        create: { userId: data.createdBy, role: "owner", status: "active" },
      },
    },
  });
}

export async function updateRoom(
  roomId: string,
  data: {
    name?: string;
    description?: string;
    joinMode?: string;
    avatarUrl?: string | null;
  },
) {
  const db = usePrisma();
  return db.chatRoom.update({ where: { id: roomId }, data });
}

export async function deleteRoom(roomId: string) {
  const db = usePrisma();
  return db.chatRoom.delete({ where: { id: roomId } });
}

// ─── Membership ───────────────────────────────────────────────────────────────

export async function getMember(roomId: string, userId: string) {
  const db = usePrisma();
  return db.chatRoomMember.findUnique({
    where: { roomId_userId: { roomId, userId } },
  });
}

export async function getRoomMembers(roomId: string) {
  const db = usePrisma();
  return db.chatRoomMember.findMany({
    where: { roomId, status: "active" },
    orderBy: { joinedAt: "asc" },
    select: { userId: true, role: true, joinedAt: true },
  });
}

export async function joinRoom(
  roomId: string,
  userId: string,
  status: "active" | "pending" = "active",
) {
  const db = usePrisma();
  const member = await db.chatRoomMember.upsert({
    where: { roomId_userId: { roomId, userId } },
    create: { roomId, userId, role: "member", status },
    update: { status },
  });
  if (status === "active") {
    await db.chatRoom.update({
      where: { id: roomId },
      data: { memberCount: { increment: 1 } },
    });
  }
  return member;
}

export async function leaveRoom(roomId: string, userId: string) {
  const db = usePrisma();
  await db.chatRoomMember.delete({
    where: { roomId_userId: { roomId, userId } },
  });
  await db.chatRoom.update({
    where: { id: roomId },
    data: { memberCount: { decrement: 1 } },
  });
}

export async function approveRequest(roomId: string, userId: string) {
  const db = usePrisma();
  await db.chatRoomMember.update({
    where: { roomId_userId: { roomId, userId } },
    data: { status: "active" },
  });
  await db.chatRoom.update({
    where: { id: roomId },
    data: { memberCount: { increment: 1 } },
  });
}

export async function rejectRequest(roomId: string, userId: string) {
  const db = usePrisma();
  await db.chatRoomMember.delete({
    where: { roomId_userId: { roomId, userId } },
  });
}

export async function getPendingRequests(roomId: string) {
  const db = usePrisma();
  return db.chatRoomMember.findMany({
    where: { roomId, status: "pending" },
    orderBy: { joinedAt: "asc" },
    select: { userId: true, joinedAt: true },
  });
}

export async function findRoomByInviteCode(code: string) {
  const db = usePrisma();
  return db.chatRoom.findUnique({ where: { inviteCode: code } });
}

export async function banMember(roomId: string, userId: string) {
  const db = usePrisma();
  const member = await db.chatRoomMember.findUnique({
    where: { roomId_userId: { roomId, userId } },
  });
  if (!member) return;
  await db.chatRoomMember.update({
    where: { roomId_userId: { roomId, userId } },
    data: { status: "banned" },
  });
  if (member.status === "active") {
    await db.chatRoom.update({
      where: { id: roomId },
      data: { memberCount: { decrement: 1 } },
    });
  }
}

export async function setMemberRole(
  roomId: string,
  userId: string,
  role: "admin" | "member",
) {
  const db = usePrisma();
  return db.chatRoomMember.update({
    where: { roomId_userId: { roomId, userId } },
    data: { role },
  });
}

// ─── Room Messages ────────────────────────────────────────────────────────────

export async function getRoomMessages(
  roomId: string,
  cursor?: string,
  limit = 50,
) {
  const db = usePrisma();
  return db.chatMessage.findMany({
    where: { roomId },
    orderBy: { createdAt: "desc" },
    take: limit,
    ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
    select: {
      id: true,
      userId: true,
      content: true,
      replyToId: true,
      attachmentUrl: true,
      attachmentType: true,
      attachmentName: true,
      likesCount: true,
      createdAt: true,
      replyTo: {
        select: { id: true, userId: true, content: true },
      },
    },
  });
}

export async function createRoomMessage(data: {
  userId: string;
  roomId: string;
  content: string;
  replyToId?: string;
  attachmentUrl?: string;
  attachmentType?: string;
  attachmentName?: string;
}) {
  const db = usePrisma();
  const msg = await db.chatMessage.create({
    data: {
      userId: data.userId,
      content: data.content,
      roomId: data.roomId,
      replyToId: data.replyToId || null,
      attachmentUrl: data.attachmentUrl || null,
      attachmentType: data.attachmentType || null,
      attachmentName: data.attachmentName || null,
    },
    select: {
      id: true,
      userId: true,
      content: true,
      replyToId: true,
      attachmentUrl: true,
      attachmentType: true,
      attachmentName: true,
      likesCount: true,
      createdAt: true,
      replyTo: {
        select: { id: true, userId: true, content: true },
      },
    },
  });
  // Bump room updatedAt
  await db.chatRoom.update({
    where: { id: data.roomId },
    data: { updatedAt: new Date() },
  });
  return msg;
}

// ─── Likes ────────────────────────────────────────────────────────────────────

export async function toggleChatMessageLike(userId: string, messageId: string) {
  const db = usePrisma();
  const existing = await db.chatMessageLike.findUnique({
    where: { userId_messageId: { userId, messageId } },
  });
  if (existing) {
    await db.chatMessageLike.delete({
      where: { userId_messageId: { userId, messageId } },
    });
    await db.chatMessage.update({
      where: { id: messageId },
      data: { likesCount: { decrement: 1 } },
    });
    return false;
  }
  await db.chatMessageLike.create({ data: { userId, messageId } });
  await db.chatMessage.update({
    where: { id: messageId },
    data: { likesCount: { increment: 1 } },
  });
  return true;
}

export async function toggleDmLike(userId: string, messageId: string) {
  const db = usePrisma();
  const existing = await db.directMessageLike.findUnique({
    where: { userId_messageId: { userId, messageId } },
  });
  if (existing) {
    await db.directMessageLike.delete({
      where: { userId_messageId: { userId, messageId } },
    });
    await db.directMessage.update({
      where: { id: messageId },
      data: { likesCount: { decrement: 1 } },
    });
    return false;
  }
  await db.directMessageLike.create({ data: { userId, messageId } });
  await db.directMessage.update({
    where: { id: messageId },
    data: { likesCount: { increment: 1 } },
  });
  return true;
}

// ─── Seed Default Groups ──────────────────────────────────────────────────────

const SYSTEM_USER = "00000000-0000-0000-0000-000000000000";

const DEFAULT_ROOMS = [
  {
    name: "Erfolge & Meilensteine",
    description: "Teile deine Fortschritte und feiere mit der Community.",
    isPublic: true,
  },
  {
    name: "Gemeinsam stark",
    description: "Der offene Raum – Austausch, Motivation und Zusammenhalt.",
    isPublic: true,
  },
];

export async function seedDefaultRooms() {
  const db = usePrisma();
  const existing = await db.chatRoom.findMany({
    where: { isDefault: true },
    select: { id: true },
  });
  if (existing.length >= DEFAULT_ROOMS.length) return;

  for (const room of DEFAULT_ROOMS) {
    const exists = await db.chatRoom.findFirst({
      where: { name: room.name, isDefault: true },
    });
    if (exists) continue;
    await db.chatRoom.create({
      data: {
        name: room.name,
        description: room.description,
        isPublic: true,
        isDefault: true,
        joinMode: "open",
        createdBy: SYSTEM_USER,
        inviteCode: randomBytes(4).toString("hex"),
        memberCount: 0,
      },
    });
  }
}
