import Link from "next/link";
import { notFound } from "next/navigation";
import { createClient } from "@/lib/supabase/server";
import { requireUser } from "@/lib/auth/session";
import { requireCompleteStudentProfile } from "@/lib/auth/student-onboarding";
import { MessagesClient, type ThreadMessage } from "./messages-client";

type RawMessage = {
  id: string;
  body: string;
  created_at: string;
  sender: string;
  sender_user_id: string | null;
  sender_user?: { full_name: string } | { full_name: string }[] | null;
};

function embeddedName(
  rel: RawMessage["sender_user"],
): string {
  if (!rel) return "";
  const r = Array.isArray(rel) ? rel[0] : rel;
  return r?.full_name ?? "";
}

export default async function PortalMessagesPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const user = await requireUser();
  if (user.role?.slug === "student") {
    await requireCompleteStudentProfile(user.id);
  }
  const supabase = await createClient();

  // Verify the application is visible to the student (RLS-scoped).
  const { data: app } = await supabase
    .from("student_applications")
    .select("applicant_name")
    .eq("id", id)
    .single();
  if (!app) notFound();

  // Fetch the thread. Attempt the embedded sender name; fall back to a
  // separate name lookup if the relationship does not resolve.
  let raw: RawMessage[] = [];
  const withEmbed = await supabase
    .from("student_messages")
    .select("id, body, created_at, sender, sender_user_id, sender_user:users(full_name)")
    .eq("student_application_id", id)
    .order("created_at");

  let nameById = new Map<string, string>();

  if (withEmbed.error) {
    const plain = await supabase
      .from("student_messages")
      .select("id, body, created_at, sender, sender_user_id")
      .eq("student_application_id", id)
      .order("created_at");
    raw = (plain.data as RawMessage[]) ?? [];

    const ids = [
      ...new Set(raw.map((m) => m.sender_user_id).filter(Boolean) as string[]),
    ];
    if (ids.length > 0) {
      const { data: users } = await supabase
        .from("users")
        .select("id, full_name")
        .in("id", ids);
      nameById = new Map(
        (users ?? []).map((u) => [u.id, u.full_name as string]),
      );
    }
  } else {
    raw = (withEmbed.data as RawMessage[]) ?? [];
  }

  const messages: ThreadMessage[] = raw.map((m) => ({
    id: m.id,
    body: m.body,
    created_at: m.created_at,
    sender: m.sender,
    senderName:
      embeddedName(m.sender_user) ||
      (m.sender_user_id ? nameById.get(m.sender_user_id) ?? "" : ""),
    mine: m.sender_user_id === user.id || m.sender === "student",
  }));

  return (
    <div className="mx-auto max-w-2xl space-y-4 p-4">
      <div>
        <Link
          href={`/portal/applications/${id}`}
          className="text-sm text-brand-blue underline"
        >
          ← Back to application
        </Link>
        <h1 className="mt-2 text-xl font-bold tracking-tight">
          Message my counsellor
        </h1>
        <p className="text-sm text-muted-foreground">{app.applicant_name}</p>
      </div>

      <MessagesClient applicationId={id} messages={messages} />
    </div>
  );
}
