import Image from "next/image";
import Link from "next/link";
import { DataTable } from "@/components/admin/DataTable";
import { AdminPageHeader } from "@/components/admin/AdminPresentation";
import { deleteProduct, markPriceUpdated } from "@/lib/admin-actions";
import { prisma } from "@/lib/prisma";
import { getBestRecommendation, getRecommendationLeaderboard } from "@/lib/recommendations";
import { currency, displayPrice, priceFreshness, productImages } from "@/lib/utils";

function priceStatusLabel(status: string) {
  if (status === "overdue") return "Price update overdue";
  if (status === "recommended") return "Price update recommended";
  return "Fresh";
}

function normalizeSearch(value: string) {
  return value.toLowerCase().trim();
}

function normalizeDigits(value: string) {
  return value.replace(/[^\d]/g, "");
}

function matchesProductSearch(product: Awaited<ReturnType<typeof prisma.product.findMany>>[number], query: string) {
  if (!query) return true;

  const textFields = [
    product.name,
    product.slug,
    product.brandMint,
    product.mintBrand,
    product.metalType,
    product.weight,
    product.purity,
    product.karat || "",
    product.productType,
    product.stockStatus,
    product.inventoryStatus,
    product.itemKind,
    String(displayPrice(product)),
    currency(displayPrice(product))
  ];

  const textMatch = textFields.some((field) => normalizeSearch(String(field || "")).includes(query));
  if (textMatch) return true;

  const queryDigits = normalizeDigits(query);
  if (!queryDigits) return false;

  const numericFields = [
    String(displayPrice(product)),
    currency(displayPrice(product)),
    String(product.customerPrice ?? ""),
    String(product.totalSalePrice ?? "")
  ];

  return numericFields.some((field) => normalizeDigits(field).includes(queryDigits));
}

function isEligibleForBullionRecommendation(product: Awaited<ReturnType<typeof prisma.product.findMany>>[number]) {
  return product.itemKind === "PHYSICAL_BULLION" && product.isPublicProduct;
}

export default async function AdminProductsPage({ searchParams }: { searchParams: Record<string, string | undefined> }) {
  const allProducts = await prisma.product.findMany({
    include: { supplier: true },
    orderBy: { createdAt: "desc" }
  });

  const eligibleBullionProducts = allProducts.filter(isEligibleForBullionRecommendation);
  const recommendationLeaderboard = getRecommendationLeaderboard(eligibleBullionProducts);
  const bestRecommendation = getBestRecommendation(eligibleBullionProducts);
  const scoreByProductId = new Map(
    recommendationLeaderboard.map((entry) => [
      entry.product.id,
      { score: entry.score, reasons: entry.reasons }
    ])
  );

  const searchQuery = normalizeSearch(searchParams.q || "");
  const metalFilter = searchParams.metal || "";
  const staleFilter = searchParams.stale || "";
  const sort = searchParams.sort || "newest";

  const filtered = allProducts.filter((product) => {
    if (metalFilter && product.metalType !== metalFilter) return false;
    if (staleFilter === "true" && priceFreshness(product.priceLastUpdatedAt) === "fresh") return false;
    return matchesProductSearch(product, searchQuery);
  });

  const sorted = [...filtered].sort((a, b) => {
    if (sort === "name-asc") return a.name.localeCompare(b.name);
    if (sort === "price-high-low") return displayPrice(b) - displayPrice(a);
    if (sort === "price-low-high") return displayPrice(a) - displayPrice(b);
    if (sort === "recommendation-high-low") {
      const aScore = scoreByProductId.get(a.id)?.score ?? -1;
      const bScore = scoreByProductId.get(b.id)?.score ?? -1;
      return bScore - aScore || a.name.localeCompare(b.name);
    }
    return b.createdAt.getTime() - a.createdAt.getTime();
  });

  const rowClassNames = sorted.map((product) =>
    bestRecommendation?.product.id === product.id
      ? "bg-[#fff8ea] shadow-[inset_4px_0_0_#d4af37]"
      : ""
  );

  return (
    <section className="min-w-0 max-w-full">
      <AdminPageHeader
        title="Products"
        subtitle="Search across bullion product details, compare recommendation scores, and quickly jump to the product currently powering the storefront recommendation."
        action={<Link href="/admin/products/new" className="btn btn-primary">Create Product</Link>}
      />

      <form className="panel mt-5 grid gap-3 p-4 md:grid-cols-5" method="get">
        <input name="q" placeholder="Search name, mint, slug, weight, purity, stock, price" defaultValue={searchParams.q} />
        <select name="metal" defaultValue={metalFilter}><option value="">All Metals</option><option value="GOLD">Gold</option><option value="SILVER">Silver</option></select>
        <select name="stale" defaultValue={staleFilter}><option value="">All Price States</option><option value="true">Price update required</option></select>
        <select name="sort" defaultValue={sort}>
          <option value="newest">Newest</option>
          <option value="name-asc">Name A-Z</option>
          <option value="price-high-low">Price high-low</option>
          <option value="price-low-high">Price low-high</option>
          <option value="recommendation-high-low">Recommendation score high-low</option>
        </select>
        <button className="btn btn-primary">Apply</button>
      </form>

      {bestRecommendation ? (
        <div className="panel mt-5 grid gap-4 p-5 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-center">
          <div className="min-w-0">
            <p className="text-xs font-black uppercase tracking-[0.14em] text-[#7a5310]">Current Today&apos;s Best Bullion Product</p>
            <h2 className="mt-2 text-2xl font-black text-[#171717]">{bestRecommendation.product.name}</h2>
            <p className="mt-2 text-sm font-bold text-[#666]">
              {(bestRecommendation.product.brandMint || bestRecommendation.product.mintBrand || "Bullion")} · {bestRecommendation.product.metalType} · {bestRecommendation.product.weight} · {bestRecommendation.product.karat || bestRecommendation.product.purity}
            </p>
            <div className="mt-3 flex flex-wrap items-center gap-2">
              <span className="badge badge-gold">{bestRecommendation.score}/100</span>
              <span className="text-lg font-black text-[#171717]">{currency(displayPrice(bestRecommendation.product))}</span>
            </div>
            <div className="mt-3 flex flex-wrap gap-2">
              {bestRecommendation.reasons.map((reason) => (
                <span key={reason} className="rounded-full border border-[#e2d8c5] bg-white px-3 py-1 text-xs font-bold text-[#5f5a52]">{reason}</span>
              ))}
            </div>
          </div>
          <Link href={`/admin/products/${bestRecommendation.product.id}/edit`} className="btn btn-primary w-fit">Edit Product</Link>
        </div>
      ) : (
        <div className="panel mt-5 p-5 text-[#666]">
          <p className="text-sm font-black uppercase tracking-[0.14em] text-[#7a5310]">Current Today&apos;s Best Bullion Product</p>
          <p className="mt-2">No eligible public bullion product is currently available for the storefront recommendation.</p>
        </div>
      )}

      <div className="mt-5">
        <DataTable
          headers={["Product", "Specs", "Pricing", "Recommendation", "Stock", "Actions"]}
          rowClassNames={rowClassNames}
          rows={sorted.map((product) => {
            const freshness = priceFreshness(product.priceLastUpdatedAt);
            const brand = product.brandMint || product.mintBrand;
            const recommendation = scoreByProductId.get(product.id);
            const eligible = isEligibleForBullionRecommendation(product);
            const recommendationTitle = recommendation?.reasons.join(" • ") || "";

            return [
              <div key="product" className="flex min-w-0 items-center gap-3">
                <Image
                  src={productImages(product)[0]}
                  alt={`${product.name} product thumbnail`}
                  width={48}
                  height={48}
                  unoptimized
                  className="h-12 w-12 shrink-0 rounded border border-[#E5E1D8] bg-[#F7F5EF] object-contain p-1"
                />
                <div className="min-w-0">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="block max-w-[230px] truncate font-black text-[#171717]" title={product.name}>{product.name}</span>
                    {bestRecommendation?.product.id === product.id ? <span className="badge badge-gold">Today&apos;s Best</span> : null}
                  </div>
                  <span className="mt-0.5 block max-w-[220px] truncate text-xs font-bold text-[#666]" title={brand}>{brand}</span>
                  <span className="mt-1 block max-w-[260px] truncate text-[11px] font-bold text-[#7a5310]" title={eligible ? "Eligible for bullion recommendation" : "Not eligible for Today's Best Bullion Product"}>
                    {eligible ? "Eligible for bullion recommendation" : "Not eligible for Today's Best Bullion Product"}
                  </span>
                </div>
              </div>,
              <div key="specs" className="min-w-[140px]">
                <div className="text-xs font-black uppercase text-[#7A5310]">{product.metalType}</div>
                <div className="mt-1 text-sm font-bold text-[#333]">{product.weight} · {product.karat || product.purity}</div>
                <div className="mt-1 text-xs font-bold text-[#666]">{product.productType}</div>
              </div>,
              <div key="pricing" className="min-w-[135px]">
                <div className="font-black text-[#171717]">{currency(displayPrice(product))}</div>
                <div className="mt-1 text-xs font-bold text-[#666]">Supplier {currency(String(product.supplierPrice))} · {String(product.markupPercent)}%</div>
                <div className="mt-1 text-xs font-bold text-[#666]">{priceStatusLabel(freshness)}</div>
              </div>,
              <div key="recommendation" className="min-w-[150px]" title={recommendationTitle}>
                {recommendation ? (
                  <>
                    <div className="font-black text-[#171717]">{recommendation.score}/100</div>
                    <div className="mt-1 text-xs font-bold text-[#666]">
                      {recommendation.reasons.slice(0, 2).join(" · ") || "Eligible for storefront recommendation"}
                    </div>
                  </>
                ) : (
                  <div className="text-xs font-bold text-[#666]">Not eligible</div>
                )}
              </div>,
              <div key="stock" className="min-w-[115px]">
                <div className="font-black">{product.stockQuantity} units</div>
                <span className={product.stockStatus === "OUT_OF_STOCK" || product.inventoryStatus === "OUT_OF_STOCK" ? "badge badge-warning mt-1" : "badge badge-stock mt-1"}>{product.stockStatus || product.inventoryStatus}</span>
              </div>,
              <div key="actions" className="admin-action-group flex w-max flex-wrap gap-1.5">
                <Link className="btn btn-secondary" href={`/admin/products/${product.id}/edit`}>Edit</Link>
                <form action={markPriceUpdated.bind(null, product.id)}><button className="btn btn-secondary">Mark Updated</button></form>
                <form action={deleteProduct.bind(null, product.id)}><button className="btn btn-secondary">Delete</button></form>
              </div>
            ];
          })}
        />
      </div>
    </section>
  );
}
