/**
 * GET  /api/me/profile — current user's profile (DB-side fields)
 * PATCH /api/me/profile — update timezone / emailPrefs (+ future)
 *
 * Clerk owns identity (name / email / avatar / password); this route
 * only persists fields that belong in our own DB:
 *   - timezone (IANA): scheduled reports + cron timing
 *   - emailPrefs (JSON): per-channel opt-in/out for outbound email
 *     (signal alerts, weekly digest, audit completion, report ready,
 *      team activity)
 *
 * EmailPrefs shape + mergePrefs helper live in
 * src/lib/notification-prefs.ts so other callers (alert sender,
 * report generator) can reach them without importing this route —
 * Next.js route files only allow HTTP method handlers + route config
 * exports, so non-handler exports here trigger a build error.
 */

import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { Prisma } from "@prisma/client";
import { mergePrefs, type EmailPrefs } from "@/lib/notification-prefs";

export const dynamic = "force-dynamic";

export async function GET() {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  // Re-read the user with the Json column selected — getCurrentUser
  // already includes what we need, but emailPrefs isn't part of its
  // default select so a dedicated read here keeps the helper tight.
  const db = await prisma.user.findUnique({
    where: { id: user.id },
    select: { emailPrefs: true, timezone: true, name: true, email: true, image: true, id: true },
  });
  return NextResponse.json({
    id: db?.id ?? user.id,
    email: db?.email ?? user.email,
    name: db?.name ?? user.name,
    image: db?.image ?? user.image,
    timezone: db?.timezone ?? null,
    emailPrefs: mergePrefs(db?.emailPrefs ?? null),
  });
}

export async function PATCH(req: Request) {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const body = (await req.json().catch(() => null)) as {
    timezone?: string | null;
    emailPrefs?: Partial<EmailPrefs>;
  } | null;
  if (!body) return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });

  const data: Prisma.UserUpdateInput = {};

  // Timezone — cap length; strings only; null clears.
  if (body.timezone === null) data.timezone = null;
  else if (typeof body.timezone === "string" && body.timezone.length <= 64) {
    data.timezone = body.timezone.trim() || null;
  }

  // Email preferences — merge into existing rather than replace so a
  // partial PATCH (e.g. toggle one switch) doesn't reset the others
  // to the defaults.
  if (body.emailPrefs && typeof body.emailPrefs === "object") {
    const existing = await prisma.user.findUnique({
      where: { id: user.id },
      select: { emailPrefs: true },
    });
    const merged = mergePrefs({ ...(existing?.emailPrefs as object | null), ...body.emailPrefs });
    data.emailPrefs = merged as unknown as Prisma.InputJsonValue;
  }

  const updated = await prisma.user.update({
    where: { id: user.id },
    data,
    select: { id: true, email: true, name: true, image: true, timezone: true, emailPrefs: true },
  });
  return NextResponse.json({
    ...updated,
    emailPrefs: mergePrefs(updated.emailPrefs),
  });
}
