import { AppShell } from "@/components/app-shell";
import { RoomConsole } from "@/components/room-console";
import { StatusBadge } from "@/components/status-badge";
import { PageHeader, StatusDot } from "@/components/ui";
import { canEnterRoom } from "@/lib/access";
import { normalizeMediaUrl } from "@/lib/media";
import { prisma } from "@/lib/prisma";
import { getShellContext } from "@/lib/shell";
import { requireCurrentUser, userIsAdmin } from "@/lib/session";
import { requireInitialSetup } from "@/lib/setup";
import { redirect } from "next/navigation";
import Link from "next/link";

export const dynamic = "force-dynamic";

export default async function RoomPage({
  params,
  searchParams
}: {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ rail?: string; saved?: string; error?: string }>;
}) {
  await requireInitialSetup();
  const user = await requireCurrentUser();
  const isAdmin = userIsAdmin(user);
  const { slug } = await params;
  const { rail = "Activity", saved, error } = await searchParams;
  const roomSlug = decodeURIComponent(slug);
  const room = await prisma.room.findUnique({
    where: { slug: roomSlug },
    include: {
      owner: true,
      members: { include: { user: true } },
      invites: {
        include: { creator: true },
        orderBy: { createdAt: "desc" },
        take: 12
      },
      mediaSources: { include: { submitter: true }, orderBy: [{ queuePosition: "asc" }, { createdAt: "asc" }], take: 40 }
    }
  });

  if (!room) {
    redirect("/dashboard");
  }

  const isOwner = room.ownerId === user.id;
  const explicitMember = room.members.some((member) => member.userId === user.id);
  const canManageRoom = isOwner || isAdmin || room.members.some((member) => member.userId === user.id && member.canManage);
  const isFriend = room.ownerId
    ? Boolean(
        await prisma.friendship.findFirst({
          where: {
            status: "ACCEPTED",
            OR: [
              { requesterId: user.id, receiverId: room.ownerId },
              { requesterId: room.ownerId, receiverId: user.id }
            ]
          },
          select: { id: true }
        })
      )
    : false;

  if (
    !canEnterRoom({
      visibility: room.visibility,
      isOwner,
      isAdmin,
      isFriend,
      explicitMember,
      hasRoomRole: explicitMember
    })
  ) {
    redirect("/dashboard");
  }

  const shell = await getShellContext(user);

  return (
    <AppShell active="Rooms" {...shell}>
      <PageHeader
        title={room.name}
        description={room.owner ? `Owned by ${room.owner.displayName || room.owner.username}. Stable route /rooms/${room.slug}.` : "Shared watch room"}
        meta={
          <>
            <StatusDot tone="good" label="Socket ready" />
            <StatusDot tone={room.mediaSources.length > 0 ? "good" : "neutral"} label={`${room.mediaSources.length} queued`} />
            <StatusBadge>{room.visibility.toLowerCase().replace("_", " ")}</StatusBadge>
          </>
        }
        actions={
          <>
            <Link className="button animated-button" href={`/rooms/${encodeURIComponent(room.slug)}?rail=Invite`}>Invite</Link>
            <Link className="button animated-button" href={`/rooms/${encodeURIComponent(room.slug)}?rail=Settings`}>Settings</Link>
          </>
        }
      />
      <RoomConsole
        roomId={room.id}
        roomSlug={room.slug}
        roomName={room.name}
        roomVisibility={room.visibility}
        isPersonal={room.isPersonal}
        ownerName={room.owner?.displayName || room.owner?.username || "Unassigned"}
        canManageRoom={canManageRoom}
        initialRail={rail}
        savedState={saved}
        errorState={error}
        currentUser={user.displayName || user.username}
        queue={room.mediaSources.map((item) => {
          const normalized = normalizeMediaUrl(item.originalUrl);
          return {
            id: item.id,
            title: item.title || item.originalUrl,
            provider: item.provider,
            originalUrl: item.originalUrl,
            playbackUrl: item.playbackUrl,
            thumbnailUrl: item.thumbnailUrl || normalized.thumbnailUrl,
            by: item.submitter?.displayName || item.submitter?.username || "Unknown",
            createdAt: formatDate(item.createdAt)
          };
        })}
        participants={[
          ...(room.owner
            ? [
                {
                  id: room.owner.id,
                  name: room.owner.displayName || room.owner.username,
                  avatarUrl: room.owner.avatarUrl,
                  role: "Owner",
                  status: room.owner.id === user.id ? "Online" : "Available"
                }
              ]
            : []),
          ...room.members.map((member) => ({
            id: member.userId,
            name: member.user.displayName || member.user.username,
            avatarUrl: member.user.avatarUrl,
            role: member.canManage ? "Manager" : "Member",
            status: member.userId === user.id ? "Online" : "Allowed"
            }))
        ]}
        invites={room.invites.map((invite) => ({
          id: invite.id,
          code: invite.code,
          status: invite.status,
          expiresAt: invite.expiresAt?.toISOString() || null,
          createdAt: formatDate(invite.createdAt),
          creator: invite.creator?.displayName || invite.creator?.username || "Unknown"
        }))}
      />
    </AppShell>
  );
}

function formatDate(date: Date) {
  return new Intl.DateTimeFormat("en", { month: "short", day: "numeric" }).format(date);
}
