import type { Metadata } from "next";
import { headers } from "next/headers";
import { auth } from "@/lib/auth/server";
import { db, recipes, pantryItems } from "@epicure/db";
import { eq } from "@epicure/db";
import { getPublicUrl } from "@/lib/storage";
import { CanCookContent } from "@/components/recipe/can-cook-content";

export const metadata: Metadata = {};

const EXPIRING_WITHIN_DAYS = 3;

function isExpiringSoon(expiresAt: Date | null): boolean {
  if (!expiresAt) return false;
  const days = Math.ceil((expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
  return days >= 0 && days <= EXPIRING_WITHIN_DAYS;
}

export default async function CanCookPage() {
  const session = await auth.api.getSession({ headers: await headers() });
  if (!session) return null;

  const [userRecipes, pantry] = await Promise.all([
    db.query.recipes.findMany({
      where: eq(recipes.authorId, session.user.id),
      with: {
        ingredients: true,
        photos: true,
      },
    }),
    db.query.pantryItems.findMany({
      where: eq(pantryItems.userId, session.user.id),
    }),
  ]);

  const pantryKeys = new Set(pantry.map((p) => p.rawName.toLowerCase()));

  const expiringSoonKeys = new Set(
    pantry
      .filter((p) => isExpiringSoon(p.expiresAt))
      .map((p) => p.rawName.toLowerCase())
  );

  const scored = userRecipes
    .filter((r) => r.ingredients.length > 0)
    .map((recipe) => {
      const matched = recipe.ingredients.filter((ing) =>
        pantryKeys.has(ing.rawName.toLowerCase())
      ).length;
      const missing = recipe.ingredients
        .filter((ing) => !pantryKeys.has(ing.rawName.toLowerCase()))
        .map((ing) => ing.rawName)
        .slice(0, 5);
      const usesExpiring = recipe.ingredients
        .filter((ing) => expiringSoonKeys.has(ing.rawName.toLowerCase()))
        .map((ing) => ing.rawName);
      const total = recipe.ingredients.length;
      const cover = recipe.photos?.find((p) => p.isCover) ?? recipe.photos?.[0];
      return {
        recipe: {
          id: recipe.id,
          title: recipe.title,
          description: recipe.description,
          photos: cover ? [{ url: getPublicUrl(cover.storageKey) }] : [],
        },
        matched,
        total,
        pct: Math.round((matched / total) * 100),
        missing,
        usesExpiring,
      };
    })
    .sort((a, b) => {
      if (a.usesExpiring.length > 0 !== b.usesExpiring.length > 0) {
        return a.usesExpiring.length > 0 ? -1 : 1;
      }
      return b.pct - a.pct;
    });

  return <CanCookContent pantryCount={pantry.length} scored={scored} />;
}
