import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

export const runtime = "nodejs";
export const revalidate = 300;

const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb";

function client() {
  return createClient(SUPABASE_URL, SUPABASE_ANON, {
    db: { schema: SCHEMA as "public" },
    auth: { persistSession: false },
  });
}

// Title-case a slug as a last-resort display fallback.
function titleizeSlug(slug: string): string {
  return slug
    .split("-")
    .map((w) => (w ? w.charAt(0).toUpperCase() + w.slice(1) : w))
    .join(" ");
}

// Format a date for the "Joined March 2014" line.
function fmtJoined(iso: string | null | undefined): string {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleDateString("en-US", { month: "long", year: "numeric" });
  } catch {
    return "";
  }
}

export async function GET(
  req: Request,
  { params }: { params: Promise<{ slug: string }> },
) {
  const { slug } = await params;
  const { searchParams } = new URL(req.url);
  const limit = Math.min(parseInt(searchParams.get("limit") || "500", 10) || 500, 5000);

  const sb = client();

  // 1) Pull the profile (with live join-date stats) from the new view.
  //    If no row exists for this slug, we synthesize a minimum profile
  //    from author_name = titleized(slug) so the page always renders.
  const { data: profileRow } = await sb
    .from("author_profiles_with_stats")
    .select("*")
    .eq("slug", slug)
    .maybeSingle();

  // 2) Resolve which author_name values count as "this author".
  //    If we have a stored profile, use its author_names array.
  //    Otherwise fall back to the titleized slug guess.
  const names: string[] =
    profileRow?.author_names && profileRow.author_names.length > 0
      ? profileRow.author_names
      : [titleizeSlug(slug)];

  // 3) Count + fetch articles by name match.
  const { count: total } = await sb
    .from("wp_imported_posts")
    .select("wp_id", { count: "exact", head: true })
    .eq("status", "published")
    .in("author_name", names);

  const { data: articleRows } = await sb
    .from("wp_imported_posts")
    .select("wp_id, wp_slug, title, excerpt, category, featured_image, wp_published_at, author_name")
    .eq("status", "published")
    .in("author_name", names)
    .order("wp_published_at", { ascending: false, nullsFirst: false })
    .limit(limit);

  // 4) If no profile row, compute join date directly from posts so the
  //    page still gets an accurate "Joined" line.
  let firstPostDate: string | null = profileRow?.first_post_date ?? null;
  if (!firstPostDate) {
    const { data: firstRow } = await sb
      .from("wp_imported_posts")
      .select("wp_published_at")
      .eq("status", "published")
      .in("author_name", names)
      .order("wp_published_at", { ascending: true, nullsFirst: false })
      .limit(1)
      .maybeSingle();
    firstPostDate = firstRow?.wp_published_at ?? null;
  }

  const articles = (articleRows || []).map((r: any) => ({
    slug: r.wp_slug,
    title: r.title,
    excerpt: r.excerpt || "",
    category: r.category || "News",
    date: r.wp_published_at
      ? new Date(r.wp_published_at).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })
      : "",
    image: r.featured_image,
    alt: r.title,
    readTime: estimateReadTime(r.excerpt || ""),
  }));

  // 5) Build the response. Display name preference order:
  //    profile.display_name > first matched author_name > titleized slug
  const displayName =
    profileRow?.display_name ||
    (articleRows && articleRows.length > 0 ? articleRows[0].author_name : null) ||
    titleizeSlug(slug);

  const profile = {
    slug,
    display_name: displayName,
    role: profileRow?.role || "Contributor",
    kind: profileRow?.kind || "contributor",
    bio: profileRow?.bio || null,
    address_line1: profileRow?.address_line1 || null,
    address_line2: profileRow?.address_line2 || null,
    city: profileRow?.city || null,
    state: profileRow?.state || null,
    postal_code: profileRow?.postal_code || null,
    country: profileRow?.country || null,
    phone: profileRow?.phone || null,
    email: profileRow?.email || null,
    website: profileRow?.website || null,
    twitter: profileRow?.twitter || null,
    linkedin: profileRow?.linkedin || null,
    facebook: profileRow?.facebook || null,
    instagram: profileRow?.instagram || null,
    avatar_url: profileRow?.avatar_url || "/assets/images/logo.png",
    cover_url: profileRow?.cover_url || "/assets/images/og-image.png",
    specialties: profileRow?.specialties || [],
    location_text: profileRow?.location_text || null,
    first_post_date: firstPostDate,
    joined_label: fmtJoined(firstPostDate),
  };

  return NextResponse.json(
    { slug, names, total: total ?? articles.length, profile, articles },
    { headers: { "Cache-Control": "public, s-maxage=300, stale-while-revalidate=600" } },
  );
}

function estimateReadTime(text: string): string {
  const words = (text || "").trim().split(/\s+/).filter(Boolean).length;
  const minutes = Math.max(1, Math.round((words || 200) / 200));
  return `${minutes} min read`;
}
