import Link from "next/link";
import { eq } from "drizzle-orm";
import { cn } from "@/lib/utils";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { getRegistry } from "@/modules/_core/registry";
import { householdMembers, households, users } from "@/modules/_core/schema";
import { BrandMark } from "@/components/brand-mark";
import { NavIcon } from "@/components/nav-icon";
import { NavLink } from "@/components/nav-link";
import { AvatarFallbackWithName } from "@/components/avatar-fallback";

type Variant = "side" | "top";

const PRIMARY_NAV: Array<{ href: string; label: string; icon: string }> = [
  { href: "/", label: "Dashboard", icon: "home" },
];

const SECONDARY_NAV: Array<{ href: string; label: string; icon: string }> = [
  { href: "/settings#sharing", label: "Share links", icon: "link" },
];

async function getHouseholdInfo(userId: string) {
  const [row] = await db
    .select({ household: households })
    .from(householdMembers)
    .innerJoin(households, eq(householdMembers.householdId, households.id))
    .where(eq(householdMembers.userId, userId))
    .limit(1);
  if (!row) return null;
  const members = await db
    .select({ id: users.id, name: users.name, image: users.image, email: users.email })
    .from(householdMembers)
    .innerJoin(users, eq(householdMembers.userId, users.id))
    .where(eq(householdMembers.householdId, row.household.id))
    .limit(6);
  return { household: row.household, members };
}

export async function Sidebar({ variant = "side" }: { variant?: Variant }) {
  const { modules } = getRegistry();
  const moduleNav = modules.flatMap((m) => (m.nav ? [m.nav] : []));

  const navItems = [
    ...PRIMARY_NAV,
    ...moduleNav.map((n) => ({ href: n.href, label: n.label, icon: n.icon ?? "circle" })),
    { href: "/settings", label: "Settings", icon: "settings" },
  ];

  const session = await auth();
  const householdInfo = session?.user?.id ? await getHouseholdInfo(session.user.id) : null;

  if (variant === "top") {
    return (
      <header className="sidebar sidebar-top">
        <Link href="/" className="brand">
          <BrandMark />
          <span className="brand-name">famapp</span>
        </Link>
        {navItems.map((n) => (
          <NavLink
            key={n.href}
            href={n.href}
            label={n.label}
            icon={n.icon}
            className="!w-auto !h-9"
          />
        ))}
        <div className="ml-auto" />
        {householdInfo && (
          <span className="badge">
            <NavIcon name="people" className="size-3" />
            {householdInfo.household.name}
          </span>
        )}
      </header>
    );
  }

  return (
    <aside className="sidebar">
      <Link href="/" className="brand">
        <BrandMark />
        <span className="brand-name">famapp</span>
      </Link>
      {navItems.map((n) => (
        <NavLink key={n.href} href={n.href} label={n.label} icon={n.icon} />
      ))}
      <div className="nav-divider" />
      {SECONDARY_NAV.map((n) => (
        <NavLink key={n.href} href={n.href} label={n.label} icon={n.icon} />
      ))}
      {householdInfo && <HouseholdPill info={householdInfo} />}
    </aside>
  );
}

function HouseholdPill({
  info,
}: {
  info: NonNullable<Awaited<ReturnType<typeof getHouseholdInfo>>>;
}) {
  const visible = info.members.slice(0, 3);
  return (
    <div className="household-pill" title={info.household.name}>
      <div style={{ display: "flex" }}>
        {visible.map((m, i) => (
          <AvatarFallbackWithName
            key={m.id}
            name={m.name ?? m.email ?? undefined}
            image={m.image}
            className={cn(i > 0 && "-ml-1.5", "shadow-[0_0_0_1.5px_var(--card)]")}
            fallbackStyle={{ background: avatarColor(m.id) }}
            title={m.name ?? m.email ?? undefined}
          />
        ))}
      </div>
      <div className="household-text" style={{ minWidth: 0 }}>
        <div
          style={{
            fontWeight: 500,
            color: "var(--ink)",
            whiteSpace: "nowrap",
            overflow: "hidden",
            textOverflow: "ellipsis",
          }}
        >
          {info.household.name}
        </div>
        <div className="muted" style={{ fontSize: 11 }}>
          {info.members.length} {info.members.length === 1 ? "member" : "members"}
        </div>
      </div>
    </div>
  );
}

// Stable color from id — uses the 5 functional accents in rotation.
const ACCENT_HUES = [
  "var(--c-household)",
  "var(--c-private)",
  "var(--c-kids)",
  "var(--c-work)",
  "var(--c-bills)",
];
function avatarColor(id: string): string {
  let hash = 0;
  for (let i = 0; i < id.length; i++) hash = (hash * 31 + id.charCodeAt(i)) & 0xffff;
  return ACCENT_HUES[hash % ACCENT_HUES.length] ?? "var(--c-household)";
}
