import type { Metadata } from "next";
import Link from "next/link";
import Image from "next/image";
import { eq, inArray, desc, sql } from "drizzle-orm";
import {
  Mail,
  ShieldCheck,
  Globe2,
  Building2,
  Calendar,
  ArrowRight,
  BookOpen,
  BookOpenCheck,
  ClipboardList,
  FlaskConical,
  GraduationCap,
  ShoppingBag,
  Send,
  Lightbulb,
  Sparkles,
  Users,
  UserCircle,
} from "lucide-react";
import { requireUser } from "@/lib/auth/admin-guard";
import { SignOutButton } from "./SignOutButton";
import { db } from "@/lib/db/client";
import {
  users,
  enrollments,
  courses,
  lessons,
  courseModules,
  lessonProgress,
  researchApplications,
  researchProposals,
  researchStudiesTable,
} from "@/lib/db/schema";

export const metadata: Metadata = { title: "Account" };
export const dynamic = "force-dynamic";

function formatMemberSince(d: Date | null | undefined): string {
  if (!d) return "—";
  return new Intl.DateTimeFormat("en-GB", {
    month: "long",
    year: "numeric",
  }).format(d);
}

function formatRelativeDate(d: Date | null | undefined): string {
  if (!d) return "—";
  const diff = Date.now() - d.getTime();
  const days = Math.floor(diff / 86_400_000);
  if (days < 1) return "Today";
  if (days < 2) return "Yesterday";
  if (days < 7) return `${days} days ago`;
  if (days < 30) return `${Math.floor(days / 7)}w ago`;
  return d.toLocaleDateString("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  });
}

function initials(name: string): string {
  return name
    .trim()
    .split(/\s+/)
    .map((p) => p[0]?.toUpperCase() ?? "")
    .slice(0, 2)
    .join("");
}

const APPLICATION_STATUS_CLASSES: Record<string, string> = {
  pending: "bg-amber-50 text-amber-800 ring-amber-200",
  accepted: "bg-emerald-50 text-emerald-800 ring-emerald-200",
  declined: "bg-slate-100 text-slate-700 ring-slate-200",
  withdrawn: "bg-slate-100 text-slate-700 ring-slate-200",
};

export default async function AccountPage({
  searchParams,
}: {
  searchParams?: Promise<{ gate?: string }>;
}) {
  const params = (await searchParams) ?? {};
  const gate = params.gate;
  const session = await requireUser();
  const sessionUser = session.user as {
    id?: string;
    email?: string | null;
    name?: string | null;
    role?: string;
  };
  const userId = sessionUser.id;

  const [record] = userId
    ? await db
        .select({
          name: users.name,
          email: users.email,
          country: users.country,
          institution: users.institution,
          professionalRole: users.professionalRole,
          role: users.role,
          createdAt: users.createdAt,
          approvedAt: users.approvedAt,
          avatarPath: users.avatarPath,
          specialty: users.specialty,
          bio: users.bio,
        })
        .from(users)
        .where(eq(users.id, userId))
        .limit(1)
    : [];

  const displayName =
    record?.name ?? sessionUser.name ?? sessionUser.email ?? "Member";
  const email = record?.email ?? sessionUser.email ?? "";
  const role = record?.role ?? sessionUser.role ?? "user";
  const isAdmin = role === "admin";
  const memberSince = formatMemberSince(record?.createdAt);

  // ------- Enrolled courses with progress -------
  type EnrolledCourseSummary = {
    id: string;
    slug: string;
    title: string;
    level: string;
    topic: string;
    totalLessons: number;
    completed: number;
  };
  let enrolledCourses: EnrolledCourseSummary[] = [];
  if (userId) {
    const enrolls = await db
      .select({ courseId: enrollments.courseId })
      .from(enrollments)
      .where(eq(enrollments.userId, userId));
    const courseIds = enrolls.map((e) => e.courseId);
    if (courseIds.length > 0) {
      const courseRows = await db
        .select()
        .from(courses)
        .where(inArray(courses.id, courseIds));
      const moduleRows = await db
        .select()
        .from(courseModules)
        .where(inArray(courseModules.courseId, courseIds));
      const moduleIds = moduleRows.map((m) => m.id);
      const lessonRows =
        moduleIds.length === 0
          ? []
          : await db
              .select()
              .from(lessons)
              .where(inArray(lessons.moduleId, moduleIds));
      const progressRows = await db
        .select()
        .from(lessonProgress)
        .where(eq(lessonProgress.userId, userId));
      const completedIds = new Set(progressRows.map((p) => p.lessonId));
      enrolledCourses = courseRows.map((c) => {
        const cMods = moduleRows
          .filter((m) => m.courseId === c.id)
          .map((m) => m.id);
        const cLessons = lessonRows.filter((l) => cMods.includes(l.moduleId));
        return {
          id: c.id,
          slug: c.slug,
          title: c.title,
          level: c.level,
          topic: c.topic,
          totalLessons: cLessons.length,
          completed: cLessons.filter((l) => completedIds.has(l.id)).length,
        };
      });
    }
  }

  // ------- Research applications + proposals -------
  const myApplications = email
    ? await db
        .select({
          app: researchApplications,
          studyTitle: researchStudiesTable.title,
          studySlug: researchStudiesTable.slug,
        })
        .from(researchApplications)
        .leftJoin(
          researchStudiesTable,
          eq(researchStudiesTable.id, researchApplications.studyId),
        )
        .where(eq(researchApplications.email, email.toLowerCase()))
        .orderBy(desc(researchApplications.createdAt))
        .limit(5)
    : [];

  const myProposals = email
    ? await db
        .select()
        .from(researchProposals)
        .where(eq(researchProposals.email, email.toLowerCase()))
        .orderBy(desc(researchProposals.createdAt))
        .limit(5)
    : [];

  // ------- Community snapshot -------
  const [{ memberCount }] = await db
    .select({ memberCount: sql<number>`count(*)`.mapWith(Number) })
    .from(users)
    .where(eq(users.status, "active"));
  const [{ countryCount }] = await db
    .select({
      countryCount: sql<number>`count(distinct country)`.mapWith(Number),
    })
    .from(users)
    .where(eq(users.status, "active"));

  const lessonsCompleted = enrolledCourses.reduce(
    (a, c) => a + c.completed,
    0,
  );

  const quickLinks: Array<{
    href: string;
    label: string;
    description: string;
    Icon: typeof BookOpen;
  }> = [
    {
      href: "/products/atlas",
      label: "Orthopaedic Atlas",
      description: "35 conditions · 7 anatomical regions.",
      Icon: BookOpen,
    },
    {
      href: "/products/consentiq",
      label: "ConsentIQ",
      description: "Interactive consent for 15 procedures.",
      Icon: ClipboardList,
    },
    {
      href: "/products/orthoprep",
      label: "OrthoPrep",
      description: "1,575 FRCS-aligned SBAs with answers.",
      Icon: BookOpenCheck,
    },
    {
      href: "/products/academy",
      label: "Academy",
      description: "Courses with video + progress tracking.",
      Icon: GraduationCap,
    },
    {
      href: "/products/research",
      label: "Research Portal",
      description: "Active studies + collaborator roles.",
      Icon: FlaskConical,
    },
    {
      href: "/products/store",
      label: "Store",
      description: "Curated books and merch for members.",
      Icon: ShoppingBag,
    },
  ];

  const gateBanner = (() => {
    if (!gate) return null;
    const styles: Record<string, { tone: string; heading: string; body: string }> = {
      pending: {
        tone: "border-amber-200 bg-amber-50 text-amber-900",
        heading: "Your membership is still being reviewed.",
        body: "OrthoPrep (and other member-only tools) unlock once an admin approves your application. Most decisions are made within 72 hours — you'll be emailed as soon as it's done.",
      },
      denied: {
        tone: "border-slate-200 bg-slate-50 text-slate-800",
        heading: "OrthoPrep access is restricted on your account.",
        body: "Your membership application wasn't approved. Contact info@orthoglobe.org if you think this was a mistake.",
      },
      suspended: {
        tone: "border-red-200 bg-red-50 text-red-900",
        heading: "Your account is currently suspended.",
        body: "Member tools including OrthoPrep are disabled. Please contact info@orthoglobe.org to resolve.",
      },
    };
    const s = styles[gate] ?? styles.pending;
    return (
      <div className={`mb-6 rounded-xl border px-5 py-4 ${s.tone}`} role="status">
        <div className="text-[13px] font-bold uppercase tracking-wider">OrthoPrep access</div>
        <div className="mt-1 font-display text-[18px] font-extrabold leading-tight">
          {s.heading}
        </div>
        <p className="mt-1.5 text-[14px] leading-relaxed">{s.body}</p>
      </div>
    );
  })();

  return (
    <>
      {gateBanner}
      {/* Compact hero */}
      <section className="relative overflow-hidden rounded-2xl border border-[var(--color-line)] bg-gradient-to-br from-[var(--color-mist)] via-white to-white p-6 md:p-8">
        <div
          aria-hidden
          className="pointer-events-none absolute -left-24 -top-8 h-[260px] w-[260px] rounded-full bg-[var(--color-blue)]/10 blur-3xl"
        />
        <div className="relative flex flex-wrap items-start gap-5">
          <div className="relative flex h-16 w-16 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[var(--color-blue)] text-white shadow-[0_8px_24px_rgba(30,64,255,0.2)]">
            {record?.avatarPath ? (
              <Image
                src={record.avatarPath}
                alt=""
                width={80}
                height={80}
                className="h-full w-full object-cover"
              />
            ) : (
              <span className="font-display text-[22px] font-extrabold">
                {initials(displayName)}
              </span>
            )}
            {isAdmin && (
              <span
                className="absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-white shadow-sm ring-1 ring-[var(--color-line)]"
                aria-label="Administrator"
              >
                <ShieldCheck
                  className="h-3.5 w-3.5 text-[var(--color-blue)]"
                  aria-hidden
                />
              </span>
            )}
          </div>
          <div className="min-w-0 flex-1">
            <div className="flex flex-wrap items-center gap-2">
              <span className="inline-flex items-center gap-1.5 rounded-full border border-emerald-200 bg-emerald-50 px-2.5 py-0.5 text-[11px] font-bold uppercase tracking-wider text-emerald-700">
                <span className="h-1.5 w-1.5 rounded-full bg-emerald-500" />
                Active member
              </span>
              {isAdmin && (
                <span className="inline-flex items-center gap-1.5 rounded-full bg-[var(--color-blue)] px-2.5 py-0.5 text-[11px] font-bold uppercase tracking-wider text-white">
                  <ShieldCheck className="h-3 w-3" aria-hidden />
                  Administrator
                </span>
              )}
              {record?.specialty && (
                <span className="rounded-full bg-[var(--color-mist)] px-2.5 py-0.5 text-[11px] font-bold uppercase tracking-wider text-[var(--color-blue)]">
                  {record.specialty}
                </span>
              )}
            </div>
            <h1 className="mt-2 font-display text-[26px] md:text-[32px] font-extrabold leading-[1.05] tracking-[-0.02em] text-[var(--color-ink)]">
              Welcome back, {displayName.split(" ")[0]}.
            </h1>
            <p className="mt-1.5 text-[14px] leading-relaxed text-[var(--color-slate)]">
              Your member hub. Pick up where you left off, apply to studies,
              browse the directory, or jump into a product.
            </p>
          </div>
          <div className="shrink-0">
            <SignOutButton />
          </div>
        </div>

        <dl className="relative mt-6 grid grid-cols-2 gap-3 md:grid-cols-4">
          <StatTile
            Icon={Calendar}
            label="Member since"
            value={memberSince}
            tone="blue"
          />
          <StatTile
            Icon={GraduationCap}
            label="Enrolled"
            value={String(enrolledCourses.length)}
            sub={
              lessonsCompleted > 0
                ? `${lessonsCompleted} lesson${lessonsCompleted === 1 ? "" : "s"} done`
                : undefined
            }
            tone="emerald"
          />
          <StatTile
            Icon={Send}
            label="Applications"
            value={String(myApplications.length)}
            sub={
              myApplications[0]
                ? `Latest: ${myApplications[0].app.status}`
                : undefined
            }
            tone="amber"
          />
          <StatTile
            Icon={Users}
            label="Community"
            value={memberCount.toLocaleString()}
            sub={`${countryCount} ${countryCount === 1 ? "country" : "countries"}`}
            tone="slate"
          />
        </dl>
      </section>

      {/* Continue learning */}
      {enrolledCourses.length > 0 && (
        <section className="mt-8">
          <SectionHeading
            eyebrow="Continue learning"
            title="Your Academy courses"
            action={
              <Link
                href="/products/academy"
                className="text-[13px] font-semibold text-[var(--color-blue)] hover:underline"
              >
                Browse all →
              </Link>
            }
          />
          <ul className="mt-4 grid gap-4 md:grid-cols-2">
            {enrolledCourses.map((c) => {
              const pct =
                c.totalLessons > 0
                  ? Math.round((c.completed / c.totalLessons) * 100)
                  : 0;
              return (
                <li key={c.id}>
                  <Link
                    href={`/account/academy/${c.id}`}
                    className="group flex flex-col rounded-2xl border border-[var(--color-line)] bg-white p-5 transition-[border-color,box-shadow] hover:border-[var(--color-blue)] hover:shadow-[0_12px_32px_rgba(30,64,255,0.08)]"
                  >
                    <div className="text-[11px] font-bold uppercase tracking-[0.15em] text-[var(--color-blue)]">
                      {c.level} · {c.topic}
                    </div>
                    <div className="mt-1.5 font-display text-[17px] font-extrabold tracking-[-0.01em] text-[var(--color-ink)] group-hover:text-[var(--color-blue)]">
                      {c.title}
                    </div>
                    <div className="mt-4 flex items-center justify-between text-[12px] text-[var(--color-slate)]">
                      <span>
                        <strong className="text-[var(--color-ink)]">
                          {c.completed}
                        </strong>{" "}
                        / {c.totalLessons} lessons
                      </span>
                      <span className="font-semibold text-[var(--color-ink)]">
                        {pct}%
                      </span>
                    </div>
                    <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-[var(--color-mist)]">
                      <div
                        className="h-full rounded-full bg-[var(--color-blue)] transition-all"
                        style={{ width: `${pct}%` }}
                      />
                    </div>
                  </Link>
                </li>
              );
            })}
          </ul>
        </section>
      )}

      {/* Quick access grid */}
      <section className="mt-8">
        <SectionHeading
          eyebrow="Jump in"
          title="All your OrthoGlobe tools"
          subtitle="Every product in the umbrella, one click away."
        />
        <div className="mt-4 grid gap-3 md:grid-cols-2 xl:grid-cols-3">
          {quickLinks.map(({ href, label, description, Icon }) => (
            <Link
              key={href}
              href={href}
              className="group flex items-start gap-3 rounded-2xl border border-[var(--color-line)] bg-white p-4 transition-[border-color,box-shadow] hover:border-[var(--color-blue)] hover:shadow-[0_8px_24px_rgba(30,64,255,0.06)]"
            >
              <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-mist)] text-[var(--color-blue)] transition-colors group-hover:bg-[var(--color-blue)] group-hover:text-white">
                <Icon className="h-4 w-4" aria-hidden />
              </span>
              <div className="min-w-0 flex-1">
                <div className="flex items-center justify-between gap-2">
                  <h3 className="font-display text-[15px] font-extrabold tracking-tight text-[var(--color-ink)] group-hover:text-[var(--color-blue)]">
                    {label}
                  </h3>
                  <ArrowRight
                    className="h-4 w-4 text-[var(--color-slate)] transition-transform group-hover:translate-x-0.5 group-hover:text-[var(--color-blue)]"
                    aria-hidden
                  />
                </div>
                <p className="mt-0.5 text-[12.5px] leading-relaxed text-[var(--color-slate)]">
                  {description}
                </p>
              </div>
            </Link>
          ))}
        </div>
      </section>

      {/* Activity */}
      {(myApplications.length > 0 || myProposals.length > 0) && (
        <section className="mt-8">
          <SectionHeading
            eyebrow="My activity"
            title="Research applications & proposals"
            action={
              <Link
                href="/account/research"
                className="text-[13px] font-semibold text-[var(--color-blue)] hover:underline"
              >
                See all →
              </Link>
            }
          />
          <div className="mt-4 grid gap-5 md:grid-cols-2">
            {myApplications.length > 0 && (
              <div>
                <div className="flex items-center gap-2 text-[11px] font-bold uppercase tracking-[0.15em] text-[var(--color-slate)]">
                  <Send className="h-3.5 w-3.5" aria-hidden />
                  Study applications
                </div>
                <ul className="mt-3 space-y-3">
                  {myApplications.map((r) => (
                    <li
                      key={r.app.id}
                      className="rounded-xl border border-[var(--color-line)] bg-white p-4"
                    >
                      <div className="flex flex-wrap items-center justify-between gap-2">
                        <span
                          className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[11px] font-bold uppercase tracking-wider ring-1 ring-inset ${APPLICATION_STATUS_CLASSES[r.app.status] ?? APPLICATION_STATUS_CLASSES.pending}`}
                        >
                          {r.app.status}
                        </span>
                        <span className="text-[11px] font-semibold text-[var(--color-slate)]">
                          {formatRelativeDate(r.app.createdAt)}
                        </span>
                      </div>
                      <div className="mt-2 font-display text-[14px] font-extrabold text-[var(--color-ink)]">
                        {r.studyTitle ? (
                          <Link
                            href={`/products/research/studies/${r.studySlug}`}
                            className="hover:text-[var(--color-blue)] hover:underline"
                          >
                            {r.studyTitle}
                          </Link>
                        ) : (
                          <span className="italic text-[var(--color-slate)]">
                            General interest
                          </span>
                        )}
                      </div>
                    </li>
                  ))}
                </ul>
              </div>
            )}
            {myProposals.length > 0 && (
              <div>
                <div className="flex items-center gap-2 text-[11px] font-bold uppercase tracking-[0.15em] text-[var(--color-slate)]">
                  <Lightbulb className="h-3.5 w-3.5" aria-hidden />
                  Study proposals
                </div>
                <ul className="mt-3 space-y-3">
                  {myProposals.map((p) => (
                    <li
                      key={p.id}
                      className="rounded-xl border border-[var(--color-line)] bg-white p-4"
                    >
                      <div className="flex flex-wrap items-center justify-between gap-2">
                        <span
                          className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[11px] font-bold uppercase tracking-wider ring-1 ring-inset ${APPLICATION_STATUS_CLASSES[p.status] ?? APPLICATION_STATUS_CLASSES.pending}`}
                        >
                          {p.status}
                        </span>
                        <span className="text-[11px] font-semibold text-[var(--color-slate)]">
                          {formatRelativeDate(p.createdAt)}
                        </span>
                      </div>
                      <div className="mt-2 font-display text-[14px] font-extrabold text-[var(--color-ink)]">
                        {p.title}
                      </div>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </section>
      )}

      {/* Profile snapshot */}
      <section className="mt-8">
        <SectionHeading
          eyebrow="Your profile"
          title="Snapshot"
          action={
            <Link
              href="/account/profile"
              className="text-[13px] font-semibold text-[var(--color-blue)] hover:underline"
            >
              Edit profile →
            </Link>
          }
        />
        <div className="mt-4 rounded-2xl border border-[var(--color-line)] bg-white p-6 md:p-8">
          <dl className="grid gap-5 sm:grid-cols-2">
            <InfoRow icon={UserCircle} label="Name" value={displayName} />
            <InfoRow icon={Mail} label="Email" value={email} />
            <InfoRow
              icon={Building2}
              label="Institution"
              value={record?.institution ?? "—"}
            />
            <InfoRow
              icon={Globe2}
              label="Country"
              value={record?.country ?? "—"}
            />
          </dl>
          {record?.bio && (
            <div className="mt-5 border-t border-[var(--color-line)] pt-4">
              <div className="text-[11px] font-bold uppercase tracking-wider text-[var(--color-slate)]">
                Bio
              </div>
              <p className="mt-1.5 whitespace-pre-wrap text-[14px] leading-relaxed text-[var(--color-ink)]/80">
                {record.bio}
              </p>
            </div>
          )}
        </div>
      </section>
    </>
  );
}

function SectionHeading({
  eyebrow,
  title,
  subtitle,
  action,
}: {
  eyebrow: string;
  title: string;
  subtitle?: string;
  action?: React.ReactNode;
}) {
  return (
    <div className="flex flex-wrap items-end justify-between gap-3">
      <div>
        <div className="inline-flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-[0.15em] text-[var(--color-blue)]">
          <Sparkles className="h-3 w-3" aria-hidden />
          {eyebrow}
        </div>
        <h2 className="mt-1.5 font-display text-[22px] md:text-[26px] font-extrabold leading-tight tracking-[-0.02em] text-[var(--color-ink)]">
          {title}
        </h2>
        {subtitle && (
          <p className="mt-1 text-[13px] leading-relaxed text-[var(--color-slate)]">
            {subtitle}
          </p>
        )}
      </div>
      {action}
    </div>
  );
}

function StatTile({
  Icon,
  label,
  value,
  sub,
  tone,
}: {
  Icon: typeof Calendar;
  label: string;
  value: string;
  sub?: string;
  tone: "blue" | "emerald" | "amber" | "slate";
}) {
  const iconBg: Record<string, string> = {
    blue: "bg-[var(--color-mist)] text-[var(--color-blue)]",
    emerald: "bg-emerald-50 text-emerald-600",
    amber: "bg-amber-50 text-amber-700",
    slate: "bg-white text-[var(--color-slate)] ring-1 ring-[var(--color-line)]",
  };
  return (
    <div className="flex flex-col rounded-xl border border-[var(--color-line)] bg-white p-3 shadow-sm">
      <span
        className={`inline-flex h-8 w-8 items-center justify-center rounded-lg ${iconBg[tone]}`}
      >
        <Icon className="h-3.5 w-3.5" aria-hidden />
      </span>
      <dt className="mt-2.5 text-[10px] font-bold uppercase tracking-wider text-[var(--color-slate)]">
        {label}
      </dt>
      <dd className="mt-0.5 font-display text-[17px] font-extrabold leading-tight tracking-tight text-[var(--color-ink)]">
        {value}
      </dd>
      {sub && (
        <span className="mt-0.5 text-[11px] font-semibold text-[var(--color-slate)]">
          {sub}
        </span>
      )}
    </div>
  );
}

function InfoRow({
  icon: Icon,
  label,
  value,
}: {
  icon: React.ComponentType<{ className?: string; "aria-hidden"?: boolean }>;
  label: string;
  value: React.ReactNode;
}) {
  return (
    <div className="flex gap-3">
      <div className="mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[var(--color-mist)]">
        <Icon className="h-4 w-4 text-[var(--color-blue)]" aria-hidden={true} />
      </div>
      <div className="min-w-0">
        <dt className="text-[11px] font-bold uppercase tracking-wider text-[var(--color-slate)]">
          {label}
        </dt>
        <dd className="mt-0.5 truncate text-[15px] font-semibold text-[var(--color-ink)]">
          {value}
        </dd>
      </div>
    </div>
  );
}
