import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";
import { db } from "@/lib/admin/db";
import { requireAuth, getClientMetadata } from "@/lib/admin/auth";
import { validateProfilePatch } from "@/lib/admin/profile-validation";
import { resolveAuthorFromUser } from "@/lib/admin/authors";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

/** GET — the caller's own editable profile (identity + author data only). */
export async function GET(req: NextRequest) {
  try {
    const { user } = await requireAuth(req);
    return NextResponse.json({ profile: profileView(user) });
  } catch (error) {
    const status = (error as { status?: number }).status || 500;
    return NextResponse.json({ error: (error as Error).message }, { status });
  }
}

/**
 * PATCH — update the caller's OWN profile. Never touches security credentials,
 * role, level or status (those have their own secure workflows). Every write is
 * audited and the affected public author surfaces are revalidated.
 */
export async function PATCH(req: NextRequest) {
  try {
    const { user } = await requireAuth(req);
    const { ip } = getClientMetadata(req);

    const body = (await req.json().catch(() => ({}))) as Record<string, unknown>;
    const parsed = validateProfilePatch(body);
    if (!parsed.ok) {
      return NextResponse.json({ error: parsed.error }, { status: 400 });
    }
    const data = { ...parsed.data };

    const previousSlug = user.authorSlug || null;

    // Author slug: auto-generate on first save, enforce uniqueness on change.
    if (data.authorSlug !== undefined) {
      if (!data.authorSlug) {
        data.authorSlug = await db.generateUniqueAuthorSlug(
          data.displayName || user.displayName || user.name,
          user.id
        );
      } else {
        const conflict = await db.getUserByAuthorSlug(data.authorSlug);
        if (conflict && conflict.id !== user.id) {
          return NextResponse.json(
            { error: "That author slug is already in use. Choose another." },
            { status: 409 }
          );
        }
      }
    } else if (!user.authorSlug) {
      // Ensure every author eventually has a slug for their public page.
      data.authorSlug = await db.generateUniqueAuthorSlug(
        data.displayName || user.displayName || user.name,
        user.id
      );
    }

    const updated = await db.updateUser(user.id, data);

    // If the public author slug changed, keep old URLs alive with a redirect.
    if (previousSlug && data.authorSlug && data.authorSlug !== previousSlug) {
      try {
        await db.createRedirect({
          id: crypto.randomUUID(),
          source: `/author/${previousSlug}`,
          destination: `/author/${data.authorSlug}`,
          permanent: true,
          method: 301,
          createdAt: new Date().toISOString(),
          createdBy: user.email,
        });
      } catch {
        /* non-fatal */
      }
    }

    await db.logSecurityEvent({
      actorId: user.id,
      actorName: user.name,
      actorEmail: user.email,
      actorLevel: user.level,
      targetUserId: user.id,
      targetUserEmail: user.email,
      targetUserName: user.name,
      action: "PROFILE_UPDATED",
      details: {
        fields: Object.keys(data),
        slugChanged: previousSlug !== (data.authorSlug ?? previousSlug),
        // Never store the values themselves beyond which fields changed.
      },
      ipAddress: ip,
    });

    // Revalidate the public author surfaces so changes go live without editing posts.
    revalidateAuthor(updated.authorSlug, previousSlug);

    return NextResponse.json({ ok: true, profile: profileView(updated) });
  } catch (error) {
    const status = (error as { status?: number }).status || 500;
    return NextResponse.json(
      { error: (error as Error).message || "Failed to update profile." },
      { status }
    );
  }
}

/** Public-safe projection of a user's profile (no security fields). */
function profileView(user: Parameters<typeof resolveAuthorFromUser>[0]) {
  return {
    id: user.id,
    name: user.name,
    email: user.email,
    level: user.level,
    role: user.role,
    displayName: user.displayName || "",
    jobTitle: user.jobTitle || "",
    shortBio: user.shortBio || "",
    longBio: user.longBio || "",
    location: user.location || "",
    professionalEmail: user.professionalEmail || "",
    authorSlug: user.authorSlug || "",
    avatarUrl: user.avatarUrl || null,
    avatarMediaId: user.avatarMediaId || null,
    socials: {
      linkedin: user.socials?.linkedin || "",
      instagram: user.socials?.instagram || "",
      x: user.socials?.x || "",
      website: user.socials?.website || "",
      github: user.socials?.github || "",
      youtube: user.socials?.youtube || "",
    },
  };
}

function revalidateAuthor(newSlug?: string, oldSlug?: string | null) {
  try {
    revalidatePath("/author");
    if (newSlug) revalidatePath(`/author/${newSlug}`);
    if (oldSlug && oldSlug !== newSlug) revalidatePath(`/author/${oldSlug}`);
    revalidatePath("/blog");
  } catch {
    /* revalidation is best-effort */
  }
}
