import Link from "next/link";
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { ArrowLeft } from "lucide-react";
import { authOptions } from "@/lib/auth";
import { isAdminEmail } from "@/lib/admin";
import { prisma } from "@/lib/prisma";

const DAY_MS = 24 * 60 * 60 * 1000;

interface WeeklyBucket {
  weekStart: Date;
  label: string;
  count: number;
}

function thirtyDaysAgoDate(): Date {
  return new Date(Date.now() - 30 * DAY_MS);
}

async function getSignupsPerWeek(weeks = 8): Promise<WeeklyBucket[]> {
  const now = new Date();
  const startMs = now.getTime() - weeks * 7 * DAY_MS;
  const startDate = new Date(startMs);

  const users = await prisma.user.findMany({
    where: { createdAt: { gte: startDate } },
    select: { createdAt: true },
  });

  // Bucketize per week (Senin sebagai start, supaya konsisten dengan kalender Indonesia).
  const buckets: WeeklyBucket[] = [];
  for (let i = weeks - 1; i >= 0; i--) {
    const bucketStart = new Date(now.getTime() - (i + 1) * 7 * DAY_MS);
    bucketStart.setUTCHours(0, 0, 0, 0);
    const bucketEnd = new Date(bucketStart.getTime() + 7 * DAY_MS);
    const count = users.filter(
      (u) => u.createdAt >= bucketStart && u.createdAt < bucketEnd
    ).length;
    buckets.push({
      weekStart: bucketStart,
      label: bucketStart.toLocaleDateString("id-ID", {
        day: "2-digit",
        month: "short",
      }),
      count,
    });
  }
  return buckets;
}

export default async function AdminUserStatsPage() {
  const session = await getServerSession(authOptions);
  if (!session?.user) redirect("/login?callbackUrl=/admin/users/stats");
  if (!isAdminEmail(session.user.email)) {
    return (
      <div className="mx-auto max-w-2xl px-4 py-12 text-center">
        <p className="text-sm text-neutral-600">
          Halaman ini hanya untuk admin SeTrip.
        </p>
      </div>
    );
  }

  const thirtyDaysAgo = thirtyDaysAgoDate();

  const [
    totalUsers,
    suspendedUsers,
    verifiedOrganizers,
    activeOrganizers30d,
    paidParticipants30d,
    weekly,
  ] = await Promise.all([
    prisma.user.count(),
    prisma.user.count({ where: { suspended: true } }),
    prisma.organizerVerification.count({ where: { status: "APPROVED" } }),
    prisma.user.count({
      where: {
        trips: { some: { createdAt: { gte: thirtyDaysAgo } } },
      },
    }),
    prisma.user.count({
      where: {
        bookings: {
          some: {
            status: "PAID",
            createdAt: { gte: thirtyDaysAgo },
          },
        },
      },
    }),
    getSignupsPerWeek(8),
  ]);

  const maxWeeklyCount = Math.max(1, ...weekly.map((w) => w.count));

  return (
    <div className="mx-auto max-w-5xl px-4 py-8 sm:py-12">
      <div className="mb-4 text-xs text-neutral-500">
        <Link
          href="/admin/users"
          className="inline-flex items-center gap-1 hover:text-primary-600"
        >
          <ArrowLeft size={14} strokeWidth={2} aria-hidden />
          Kembali ke list users
        </Link>
      </div>

      <header className="mb-6">
        <h1 className="text-2xl font-bold text-neutral-900 sm:text-3xl">
          User Analytics
        </h1>
        <p className="mt-1 text-sm text-neutral-500">
          Snapshot pertumbuhan user. Real-time read langsung dari DB — tidak
          ada cache, refresh halaman untuk angka terbaru.
        </p>
      </header>

      <section className="mb-8 grid gap-3 sm:grid-cols-3">
        <StatCard label="Total Users" value={totalUsers} />
        <StatCard
          label="Suspended"
          value={suspendedUsers}
          accent="red"
        />
        <StatCard
          label="Verified Organizers"
          value={verifiedOrganizers}
          accent="emerald"
        />
        <StatCard
          label="Organizer Aktif (30 hari)"
          value={activeOrganizers30d}
          accent="secondary"
          sub="Bikin trip baru"
        />
        <StatCard
          label="Peserta Aktif (30 hari)"
          value={paidParticipants30d}
          accent="primary"
          sub="Booking PAID"
        />
      </section>

      <section className="rounded-2xl border border-neutral-200 bg-white p-4 shadow-sm sm:p-6">
        <h2 className="mb-1 text-sm font-bold text-neutral-900">
          Signup per Minggu (8 minggu terakhir)
        </h2>
        <p className="mb-4 text-xs text-neutral-500">
          Tiap bar = 1 minggu (mulai hari ini mundur). Angka di atas bar = total
          signup minggu itu.
        </p>
        <div className="flex h-48 items-end gap-2">
          {weekly.map((w) => {
            const heightPct = (w.count / maxWeeklyCount) * 100;
            return (
              <div
                key={w.weekStart.toISOString()}
                className="flex flex-1 flex-col items-center gap-1"
              >
                <span className="text-[10px] font-semibold text-neutral-700">
                  {w.count}
                </span>
                <div
                  className="w-full rounded-t-md bg-primary-500/80"
                  style={{ height: `${Math.max(heightPct, 2)}%` }}
                  title={`${w.count} signup minggu ${w.label}`}
                />
                <span className="text-[10px] text-neutral-500">{w.label}</span>
              </div>
            );
          })}
        </div>
      </section>
    </div>
  );
}

function StatCard({
  label,
  value,
  sub,
  accent = "neutral",
}: {
  label: string;
  value: number;
  sub?: string;
  accent?: "neutral" | "primary" | "secondary" | "emerald" | "red";
}) {
  const map = {
    neutral: "text-neutral-800",
    primary: "text-primary-700",
    secondary: "text-secondary-700",
    emerald: "text-emerald-700",
    red: "text-red-700",
  };
  return (
    <div className="rounded-xl border border-neutral-200 bg-white p-4 shadow-sm">
      <p className="text-[10px] font-semibold uppercase tracking-wide text-neutral-500">
        {label}
      </p>
      <p className={`mt-0.5 text-2xl font-bold ${map[accent]}`}>{value}</p>
      {sub && <p className="text-[11px] text-neutral-500">{sub}</p>}
    </div>
  );
}
