import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { supabase } from "@/lib/supabase";
import { PublicMenuClient, type MenuCategory, type MenuItem, type RestaurantData } from "@/components/PublicMenuClient";
import { DEMO_RESTAURANT, DEMO_CATEGORIES } from "@/lib/demo-data";
import type { ThemeConfig } from "@menulio/shared";

type PageProps = {
  params: Promise<{ slug: string }>;
  searchParams?: Promise<{ theme?: string }>;
};

interface MenuItemRow {
  id: string;
  name: string;
  description: string | null;
  price: number;
  image_url: string | null;
  is_active: boolean;
}

interface MenuCategoryRow {
  id: string;
  name: string;
  description: string | null;
  is_active: boolean;
  menu_items: MenuItemRow[];
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
  const { slug } = await params;
  let restaurant: any = null;
  const { data: bySlug } = await supabase
    .from("restaurants")
    .select("name, logo_url")
    .eq("slug", slug)
    .maybeSingle();

  if (bySlug) {
    restaurant = bySlug;
  } else if (slug === "demo" || slug === "gusto-brasserie") {
    restaurant = DEMO_RESTAURANT;
  } else {
    const { data: domainRow } = await supabase
      .from("domains")
      .select("restaurants(name, logo_url)")
      .eq("hostname", slug)
      .maybeSingle();
    if (domainRow?.restaurants) {
      restaurant = domainRow.restaurants;
    }
  }

  if (!restaurant) {
    return {
      title: "Menü Bulunamadı | Menulio",
    };
  }

  return {
    title: `${restaurant.name} | QR Menü`,
    description: `${restaurant.name} restoranının güncel dijital QR menüsü ve fiyatları.`,
    openGraph: {
      title: `${restaurant.name} QR Menü`,
      description: `${restaurant.name} dijital menüsünü inceleyin.`,
      images: restaurant.logo_url ? [restaurant.logo_url] : [],
    },
  };
}

async function fetchRestaurantBySlug(slug: string) {
  let { data: bySlug, error } = await supabase
    .from("restaurants")
    .select("id, name, slug, logo_url, cover_url, phone, address")
    .eq("slug", slug)
    .maybeSingle();

  if (error && error.code === "42703") {
    const { data: fallback } = await supabase
      .from("restaurants")
      .select("id, name, slug, logo_url, phone, address")
      .eq("slug", slug)
      .maybeSingle();
    if (fallback) {
      return { ...fallback, cover_url: null };
    }
  }

  if (bySlug) return bySlug;

  let { data: domainRow, error: domErr } = await supabase
    .from("domains")
    .select("restaurant_id, restaurants(id, name, slug, logo_url, cover_url, phone, address)")
    .eq("hostname", slug)
    .maybeSingle();

  if (domErr && domErr.code === "42703") {
    const { data: fallbackDom } = await supabase
      .from("domains")
      .select("restaurant_id, restaurants(id, name, slug, logo_url, phone, address)")
      .eq("hostname", slug)
      .maybeSingle();
    if (fallbackDom?.restaurants) {
      return { ...(fallbackDom.restaurants as any), cover_url: null };
    }
  }

  return (domainRow?.restaurants as any) ?? null;
}

export default async function PublicMenuPage({ params, searchParams }: PageProps) {
  const { slug } = await params;
  const resolvedSearchParams = searchParams ? await searchParams : {};
  const themeParam = resolvedSearchParams.theme;

  const restaurant: any = await fetchRestaurantBySlug(slug);

  if (!restaurant) {
    if (slug === "demo" || slug === "gusto-brasserie") {
      return (
        <PublicMenuClient
          restaurant={DEMO_RESTAURANT}
          categories={DEMO_CATEGORIES}
          initialThemeKey={themeParam || "coastal"}
        />
      );
    }
    notFound();
  }

  // Find menu (published or any available menu)
  let { data: menu } = await supabase
    .from("menus")
    .select("id, name, locations!inner(restaurant_id)")
    .eq("locations.restaurant_id", restaurant.id)
    .eq("is_published", true)
    .maybeSingle();

  if (!menu) {
    const { data: anyMenu } = await supabase
      .from("menus")
      .select("id, name, locations!inner(restaurant_id)")
      .eq("locations.restaurant_id", restaurant.id)
      .maybeSingle();
    menu = anyMenu;
  }

  let categories: MenuCategory[] = [];

  if (menu) {
    const { data: rawCategories } = await supabase
      .from("menu_categories")
      .select("id, name, description, is_active, menu_items(id, name, description, price, image_url, is_active)")
      .eq("menu_id", menu.id)
      .eq("is_active", true)
      .order("sort_order", { ascending: true })
      .returns<MenuCategoryRow[]>();

    categories = (rawCategories ?? []).map((cat) => ({
      id: cat.id,
      name: cat.name,
      description: cat.description,
      is_active: cat.is_active,
      menu_items: (cat.menu_items ?? [])
        .filter((item) => item.is_active)
        .map((item): MenuItem => ({
          id: item.id,
          name: item.name,
          description: item.description,
          price: item.price,
          image_url: item.image_url,
          is_active: item.is_active,
        })),
    }));
  } else if (slug === "demo" || slug === "gusto-brasserie") {
    categories = DEMO_CATEGORIES;
  }

  const { data: themeRow } = await supabase
    .from("restaurant_themes")
    .select("overrides, themes(key, config)")
    .eq("restaurant_id", restaurant.id)
    .maybeSingle();

  const themeRelation = themeRow?.themes as unknown as { key?: string; config?: Partial<ThemeConfig> } | null;
  const themeKey = themeParam || themeRelation?.key || "elegant";
  const customConfig = (themeRow?.overrides as Partial<ThemeConfig>) || themeRelation?.config;

  const restaurantData: RestaurantData = {
    id: restaurant.id,
    name: restaurant.name,
    slug: restaurant.slug,
    logo_url: restaurant.logo_url,
    cover_url: restaurant.cover_url,
    phone: restaurant.phone,
    address: restaurant.address,
  };

  return (
    <PublicMenuClient
      restaurant={restaurantData}
      categories={categories}
      initialThemeKey={themeKey}
      customThemeConfig={customConfig}
    />
  );
}
