"use client";

import { FormEvent, useEffect, useState } from "react";

type Surface = "login" | "admin" | "guest" | "staff";
type AdminSection = "overview" | "menu" | "tables" | "branding" | "settings";
type TicketKind = "order" | "call";
type TicketStatus = "open" | "done";

type Brand = {
  primary: string;
  accent: string;
  background: string;
  text: string;
  radius: number;
  font: "modern" | "classic" | "soft";
};

type Settings = {
  confirmBeforeResolve: boolean;
  soundEnabled: boolean;
  orderingEnabled: boolean;
  waiterCallEnabled: boolean;
  orderingPaused: boolean;
  showTotal: boolean;
};

type MenuItem = {
  id: string;
  categoryId?: string;
  variantId?: string;
  imageAssetId?: string;
  persisted?: boolean;
  translations?: Record<string, { name?: string; description?: string }>;
  name: string;
  description: string;
  category: string;
  portion: string;
  price: number;
  available: boolean;
  featured?: boolean;
  image?: string;
  tags: string[];
  allergens?: string[];
};

type DiningTable = {
  id: string;
  number: number;
  zone: string;
  token: string;
  active: boolean;
};

type TicketItem = {
  id?: string;
  name: string;
  quantity: number;
  portion?: string;
  price: number;
  note?: string;
};

type Ticket = {
  id: string;
  kind: TicketKind;
  status: TicketStatus;
  tableNumber: number;
  zone: string;
  createdAt: string;
  resolvedAt?: string;
  total?: number;
  callReason?: string;
  paymentMethod?: string;
  items?: TicketItem[];
};

type RestaurantState = {
  restaurant: {
    id: string;
    slug: string;
    name: string;
    location: string;
    currency: string;
    brand: Brand;
    settings: Settings;
  };
  categories: string[];
  items: MenuItem[];
  tables: DiningTable[];
  tickets: Ticket[];
};

type CartLine = MenuItem & { quantity: number; note?: string };

type GuestCopy = {
  greeting: string;
  whatToEat: string;
  kitchenHours: string;
  callWaiter: string;
  helpOrBill: string;
  pausedTitle: string;
  pausedBody: string;
  search: string;
  fromKitchen: string;
  itemsLabel: string;
  noResults: string;
  yourOrder: string;
  oneItem: string;
  manyItems: string;
  allergens: string;
  poweredBy: string;
  kitchenNote: string;
  noteExample: string;
  add: string;
  checkItems: string;
  subtotal: string;
  service: string;
  included: string;
  total: string;
  payAtRestaurant: string;
  payBody: string;
  sendOrder: string;
  callTitle: string;
  callBody: string;
  reasons: string[];
  payQuestion: string;
  card: string;
  cash: string;
  notify: string;
  orderSent: string;
  orderSentBody: string;
  prepTime: string;
  continueMenu: string;
};

const GUEST_COPY: Record<"SR" | "EN" | "DE", GuestCopy> = {
  SR: {
    greeting: "Dobro veče 👋", whatToEat: "Šta vam se jede?", kitchenHours: "Kuhinja radi do 22:30 · priprema 15–25 min",
    callWaiter: "Pozovi konobara", helpOrBill: "Pomoć ili račun", pausedTitle: "Poručivanje je trenutno pauzirano.",
    pausedBody: "Meni možete pregledati, a konobara pozvati u svakom trenutku.", search: "Pretražite meni…", fromKitchen: "Iz naše kuhinje",
    itemsLabel: "artikala", noResults: "Nema rezultata za ovu pretragu.", yourOrder: "Vaša porudžbina", oneItem: "stavka", manyItems: "stavke",
    allergens: "Alergeni dostupni", poweredBy: "Digitalni meni pokreće MeniFlow", kitchenNote: "Napomena za kuhinju", noteExample: "Npr. bez luka",
    add: "Dodaj", checkItems: "Proverite stavke pre slanja.", subtotal: "Međuzbir", service: "Usluga", included: "Uključena", total: "Ukupno",
    payAtRestaurant: "Plaćanje u restoranu", payBody: "Porudžbinu plaćate konobaru, karticom ili gotovinom.", sendOrder: "Pošalji porudžbinu",
    callTitle: "Pozovite konobara", callBody: "Recite nam kako možemo da pomognemo.", reasons: ["Potrebna mi je pomoć", "Želim da poručim", "Donesite račun", "Drugo"],
    payQuestion: "Kako želite da platite?", card: "Kartica", cash: "Gotovina", notify: "Obavesti konobara", orderSent: "Porudžbina je poslata",
    orderSentBody: "Osoblje je primilo vaš zahtev. Prijatno!", prepTime: "Procenjeno vreme pripreme", continueMenu: "Nastavi pregled menija",
  },
  EN: {
    greeting: "Good evening 👋", whatToEat: "What are you in the mood for?", kitchenHours: "Kitchen open until 10:30 PM · 15–25 min preparation",
    callWaiter: "Call a waiter", helpOrBill: "Help or the bill", pausedTitle: "Ordering is currently paused.",
    pausedBody: "You can still browse the menu or call a waiter at any time.", search: "Search the menu…", fromKitchen: "From our kitchen",
    itemsLabel: "items", noResults: "No items match your search.", yourOrder: "Your order", oneItem: "item", manyItems: "items",
    allergens: "Allergen info available", poweredBy: "Digital menu powered by MeniFlow", kitchenNote: "Note for the kitchen", noteExample: "E.g. no onions",
    add: "Add", checkItems: "Review your items before sending.", subtotal: "Subtotal", service: "Service", included: "Included", total: "Total",
    payAtRestaurant: "Pay at the restaurant", payBody: "Pay your waiter by card or cash.", sendOrder: "Send order",
    callTitle: "Call a waiter", callBody: "Tell us how we can help.", reasons: ["I need help", "I would like to order", "Bring the bill", "Other"],
    payQuestion: "How would you like to pay?", card: "Card", cash: "Cash", notify: "Notify waiter", orderSent: "Order sent",
    orderSentBody: "The team has received your request. Enjoy!", prepTime: "Estimated preparation time", continueMenu: "Continue browsing",
  },
  DE: {
    greeting: "Guten Abend 👋", whatToEat: "Worauf haben Sie Appetit?", kitchenHours: "Küche bis 22:30 Uhr · Zubereitung 15–25 Min.",
    callWaiter: "Service rufen", helpOrBill: "Hilfe oder Rechnung", pausedTitle: "Bestellungen sind momentan pausiert.",
    pausedBody: "Sie können die Speisekarte ansehen oder jederzeit den Service rufen.", search: "Speisekarte durchsuchen…", fromKitchen: "Aus unserer Küche",
    itemsLabel: "Gerichte", noResults: "Keine passenden Gerichte gefunden.", yourOrder: "Ihre Bestellung", oneItem: "Artikel", manyItems: "Artikel",
    allergens: "Allergeninfo verfügbar", poweredBy: "Digitale Speisekarte von MeniFlow", kitchenNote: "Hinweis an die Küche", noteExample: "Z. B. ohne Zwiebeln",
    add: "Hinzufügen", checkItems: "Bitte prüfen Sie Ihre Auswahl.", subtotal: "Zwischensumme", service: "Service", included: "Inklusive", total: "Gesamt",
    payAtRestaurant: "Zahlung im Restaurant", payBody: "Zahlen Sie beim Service mit Karte oder bar.", sendOrder: "Bestellung senden",
    callTitle: "Service rufen", callBody: "Wie können wir helfen?", reasons: ["Ich brauche Hilfe", "Ich möchte bestellen", "Die Rechnung bitte", "Sonstiges"],
    payQuestion: "Wie möchten Sie zahlen?", card: "Karte", cash: "Bar", notify: "Service benachrichtigen", orderSent: "Bestellung gesendet",
    orderSentBody: "Das Team hat Ihre Anfrage erhalten. Guten Appetit!", prepTime: "Voraussichtliche Zubereitungszeit", continueMenu: "Weiter zur Speisekarte",
  },
};

const FOOD_IMAGES = {
  grill:
    "https://images.unsplash.com/photo-1544025162-d76694265947?auto=format&fit=crop&w=900&q=80",
  salad:
    "https://images.unsplash.com/photo-1540189549336-e6e99c3679fe?auto=format&fit=crop&w=900&q=80",
  pasta:
    "https://images.unsplash.com/photo-1473093295043-cdd812d0e601?auto=format&fit=crop&w=900&q=80",
  dessert:
    "https://images.unsplash.com/photo-1571877227200-a0d98ea607e9?auto=format&fit=crop&w=900&q=80",
};

const bistroItems: MenuItem[] = [
  {
    id: "item-cevapi",
    name: "Ćevapi u somunu",
    description: "Domaći juneći ćevapi, somun, luk i kajmak.",
    category: "Glavna jela",
    portion: "10 kom · 300 g",
    price: 890,
    available: true,
    featured: true,
    image: FOOD_IMAGES.grill,
    tags: ["Preporuka kuće"],
    allergens: ["Gluten", "Mleko"],
  },
  {
    id: "item-pasta",
    name: "Pasta sa tartufima",
    description: "Sveža pasta, krem od parmezana i crni tartuf.",
    category: "Glavna jela",
    portion: "320 g",
    price: 1190,
    available: true,
    featured: true,
    image: FOOD_IMAGES.pasta,
    tags: ["Vegetarijansko"],
    allergens: ["Gluten", "Mleko", "Jaja"],
  },
  {
    id: "item-salata",
    name: "Dunavska salata",
    description: "Zeleniš, pečena paprika, feta, orasi i preliv od nara.",
    category: "Salate",
    portion: "280 g",
    price: 690,
    available: true,
    featured: true,
    image: FOOD_IMAGES.salad,
    tags: ["Vegetarijansko", "Bez glutena"],
    allergens: ["Mleko", "Orašasti plodovi"],
  },
  {
    id: "item-tiramisu",
    name: "Tiramisu",
    description: "Maskarpone, espresso i kakao — naš kućni klasik.",
    category: "Dezerti",
    portion: "160 g",
    price: 490,
    available: true,
    image: FOOD_IMAGES.dessert,
    tags: ["Omiljeno"],
    allergens: ["Mleko", "Jaja", "Gluten"],
  },
  {
    id: "item-limunada",
    name: "Domaća limunada",
    description: "Limun, nana i malo meda. Bez veštačkih dodataka.",
    category: "Bezalkoholna pića",
    portion: "0,4 l",
    price: 360,
    available: true,
    tags: ["Domaće"],
  },
  {
    id: "item-voda",
    name: "Mineralna voda",
    description: "Rosa gazirana ili negazirana.",
    category: "Bezalkoholna pića",
    portion: "0,33 l",
    price: 220,
    available: true,
    tags: [],
  },
  {
    id: "item-rakija",
    name: "Šljivovica Reserve",
    description: "Odležala domaća rakija od požegače.",
    category: "Alkoholna pića",
    portion: "0,03 l",
    price: 390,
    available: false,
    tags: ["18+"],
  },
];

function makeTables(count = 14): DiningTable[] {
  return Array.from({ length: count }, (_, index) => ({
    id: `table-${index + 1}`,
    number: index + 1,
    zone: index < 8 ? "Sala" : index < 12 ? "Terasa" : "Bašta",
    token: `bd-${(index + 1).toString().padStart(2, "0")}-7f3a`,
    active: true,
  }));
}

const initialTickets: Ticket[] = [
  {
    id: "ticket-1",
    kind: "call",
    status: "open",
    tableNumber: 7,
    zone: "Sala",
    createdAt: new Date(Date.now() - 11 * 60_000).toISOString(),
    callReason: "Donesite račun",
    paymentMethod: "Kartica",
  },
  {
    id: "ticket-2",
    kind: "order",
    status: "open",
    tableNumber: 12,
    zone: "Terasa",
    createdAt: new Date(Date.now() - 5 * 60_000).toISOString(),
    total: 2040,
    items: [
      { name: "Ćevapi u somunu", quantity: 2, price: 890, note: "Bez luka" },
      { name: "Mineralna voda", quantity: 1, price: 220, portion: "0,33 l" },
      { name: "Domaća limunada", quantity: 1, price: 360, portion: "0,4 l" },
    ],
  },
  {
    id: "ticket-3",
    kind: "call",
    status: "open",
    tableNumber: 4,
    zone: "Sala",
    createdAt: new Date(Date.now() - 2 * 60_000).toISOString(),
    callReason: "Potrebna mi je pomoć",
  },
  {
    id: "ticket-4",
    kind: "order",
    status: "open",
    tableNumber: 9,
    zone: "Terasa",
    createdAt: new Date(Date.now() - 45_000).toISOString(),
    total: 1050,
    items: [
      { name: "Dunavska salata", quantity: 1, price: 690 },
      { name: "Domaća limunada", quantity: 1, price: 360 },
    ],
  },
  {
    id: "ticket-history",
    kind: "order",
    status: "done",
    tableNumber: 2,
    zone: "Sala",
    createdAt: new Date(Date.now() - 42 * 60_000).toISOString(),
    resolvedAt: new Date(Date.now() - 31 * 60_000).toISOString(),
    total: 1380,
    items: [{ name: "Dunavska salata", quantity: 2, price: 690 }],
  },
];

const bistroFallback: RestaurantState = {
  restaurant: {
    id: "restaurant-bistro-dunav",
    slug: "bistro-dunav",
    name: "Bistro Dunav",
    location: "Dorćol · Beograd",
    currency: "RSD",
    brand: {
      primary: "#1F5A4A",
      accent: "#D77A5B",
      background: "#FFF9F3",
      text: "#24211F",
      radius: 22,
      font: "modern",
    },
    settings: {
      confirmBeforeResolve: true,
      soundEnabled: true,
      orderingEnabled: true,
      waiterCallEnabled: true,
      orderingPaused: false,
      showTotal: true,
    },
  },
  categories: [
    "Sve",
    "Preporučujemo",
    "Glavna jela",
    "Salate",
    "Dezerti",
    "Bezalkoholna pića",
    "Alkoholna pića",
  ],
  items: bistroItems,
  tables: makeTables(),
  tickets: initialTickets,
};

const casaFallback: RestaurantState = {
  restaurant: {
    id: "restaurant-casa-verde",
    slug: "casa-verde",
    name: "Casa Verde",
    location: "Vračar · Beograd",
    currency: "RSD",
    brand: {
      primary: "#305B38",
      accent: "#E5A93F",
      background: "#FBF7EA",
      text: "#27312A",
      radius: 14,
      font: "classic",
    },
    settings: {
      confirmBeforeResolve: false,
      soundEnabled: true,
      orderingEnabled: true,
      waiterCallEnabled: true,
      orderingPaused: false,
      showTotal: true,
    },
  },
  categories: ["Sve", "Preporučujemo", "Paste", "Salate", "Dezerti", "Pića"],
  items: [
    { ...bistroItems[1], id: "casa-pasta", category: "Paste", price: 1290 },
    { ...bistroItems[2], id: "casa-salata", name: "Verde salata", price: 740 },
    { ...bistroItems[3], id: "casa-tiramisu", price: 520 },
  ],
  tables: makeTables(10).map((table) => ({ ...table, token: `cv-${table.number}-4b2e` })),
  tickets: initialTickets.slice(2),
};

function fallbackFor(slug: string) {
  return structuredClone(slug === "casa-verde" ? casaFallback : bistroFallback);
}

function money(value: number, currency = "RSD") {
  return `${new Intl.NumberFormat("sr-RS").format(value)} ${currency}`;
}

function timeAgo(value: string) {
  const minutes = Math.max(0, Math.floor((Date.now() - new Date(value).getTime()) / 60_000));
  if (minutes < 1) return "upravo sada";
  if (minutes === 1) return "pre 1 min";
  return `pre ${minutes} min`;
}

function initials(value: string) {
  return value
    .split(" ")
    .map((part) => part[0])
    .join("")
    .slice(0, 2)
    .toUpperCase();
}

function zoneFromLabel(value: unknown) {
  const raw = String(value ?? "Sala").split("·").at(-1)?.trim() || "Sala";
  return raw.charAt(0).toUpperCase() + raw.slice(1);
}

function normalizeApiState(payload: Partial<RestaurantState> & Record<string, unknown>, fallback: RestaurantState): RestaurantState {
  const source = payload as Record<string, any>;
  const restaurantSource = source.restaurant ?? {};
  const brandingSource = source.branding ?? restaurantSource.brand ?? {};
  const settingsSource = source.settings ?? restaurantSource.settings ?? {};
  const categoryRows = Array.isArray(source.categories) ? source.categories : [];
  const categoryNameById = new Map<string, string>(
    categoryRows
      .filter((entry: any) => entry && typeof entry === "object")
      .map((entry: any) => [String(entry.id), String(entry.name)]),
  );
  const categories = categoryRows.length && typeof categoryRows[0] === "object"
    ? ["Sve", "Preporučujemo", ...categoryRows.map((entry: any) => String(entry.name))]
    : source.categories;
  const apiItems = Array.isArray(source.items) && source.items.some((entry: any) => Array.isArray(entry?.variants))
    ? source.items.map((entry: any) => {
        const variant = entry.variants?.find((candidate: any) => candidate.isAvailable) ?? entry.variants?.[0] ?? {};
        const fallbackMatch = fallback.items.find((candidate) => candidate.name === entry.name);
        const portionAmount = variant.portionAmount ?? "";
        const portionUnit = variant.portionUnit === "piece" ? "kom" : variant.portionUnit === "portion" ? "porcija" : variant.portionUnit ?? "";
        return {
          id: String(entry.id),
          categoryId: String(entry.categoryId),
          variantId: variant.id ? String(variant.id) : undefined,
          imageAssetId: entry.imageAssetId ? String(entry.imageAssetId) : undefined,
          persisted: true,
          translations: entry.translations && typeof entry.translations === "object" ? entry.translations : undefined,
          name: String(entry.name),
          description: String(entry.description ?? ""),
          category: categoryNameById.get(String(entry.categoryId)) ?? "Ostalo",
          portion: [variant.label, portionAmount && portionUnit ? `${portionAmount} ${portionUnit}` : ""].filter(Boolean).join(" · "),
          price: Number(variant.priceMinor ?? 0) / 100,
          available: Boolean(entry.isAvailable && (variant.isAvailable ?? true)),
          featured: Boolean(entry.isFeatured),
          image: entry.imageAssetId ? `/api/demo/media/${encodeURIComponent(String(entry.imageAssetId))}` : fallbackMatch?.image,
          tags: Array.isArray(entry.dietaryTags) ? entry.dietaryTags : [],
          allergens: fallbackMatch?.allergens ?? [],
        } satisfies MenuItem;
      })
    : source.items;
  const apiTables = Array.isArray(source.tables) && source.tables.some((entry: any) => "tableNumber" in entry)
    ? source.tables.map((entry: any) => ({
        id: String(entry.id),
        number: Number(entry.tableNumber),
        zone: zoneFromLabel(entry.label),
        token: String(entry.qrToken),
        active: Boolean(entry.isActive),
      } satisfies DiningTable))
    : source.tables;
  const ticketRows = source.tickets && !Array.isArray(source.tickets)
    ? [...(source.tickets.open ?? []), ...(source.tickets.history ?? [])]
    : source.tickets;
  const apiTickets = Array.isArray(ticketRows) && ticketRows.some((entry: any) => entry.type)
    ? ticketRows.map((entry: any) => ({
        id: String(entry.id),
        kind: entry.type === "waiter_call" ? "call" : "order",
        status: entry.status === "resolved" ? "done" : "open",
        tableNumber: Number(entry.tableNumber),
        zone: zoneFromLabel(entry.tableLabel),
        createdAt: String(entry.createdAt),
        resolvedAt: entry.resolvedAt ? String(entry.resolvedAt) : undefined,
        total: Number(entry.totalMinor ?? 0) / 100,
        callReason: entry.type === "waiter_call" ? String(entry.note ?? "Potrebna mi je pomoć") : undefined,
        items: Array.isArray(entry.items) ? entry.items.map((line: any) => ({
          id: String(line.id), name: String(line.itemName), quantity: Number(line.quantity),
          portion: String(line.variantLabel ?? ""), price: Number(line.unitPriceMinor ?? 0) / 100,
        })) : [],
      } satisfies Ticket))
    : ticketRows;

  return {
    restaurant: source.restaurant
      ? {
          ...fallback.restaurant,
          id: String(restaurantSource.id ?? fallback.restaurant.id),
          slug: String(restaurantSource.slug ?? fallback.restaurant.slug),
          name: String(brandingSource.displayName ?? restaurantSource.name ?? fallback.restaurant.name),
          currency: String(restaurantSource.currency ?? fallback.restaurant.currency),
          brand: {
            ...fallback.restaurant.brand,
            primary: brandingSource.primaryColor ?? brandingSource.primary ?? fallback.restaurant.brand.primary,
            accent: brandingSource.accentColor ?? brandingSource.accent ?? fallback.restaurant.brand.accent,
            background: brandingSource.backgroundColor ?? brandingSource.background ?? fallback.restaurant.brand.background,
            text: brandingSource.textColor ?? brandingSource.text ?? fallback.restaurant.brand.text,
            font: brandingSource.fontFamily === "serif" ? "classic" : fallback.restaurant.brand.font,
          },
          settings: {
            ...fallback.restaurant.settings,
            confirmBeforeResolve: settingsSource.confirmBeforeResolve ?? fallback.restaurant.settings.confirmBeforeResolve,
            orderingEnabled: settingsSource.acceptOrders ?? settingsSource.orderingEnabled ?? fallback.restaurant.settings.orderingEnabled,
            waiterCallEnabled: settingsSource.waiterCallEnabled ?? fallback.restaurant.settings.waiterCallEnabled,
          },
        }
      : fallback.restaurant,
    categories: Array.isArray(categories) && categories.length ? categories : fallback.categories,
    items: Array.isArray(apiItems) && apiItems.length ? apiItems : fallback.items,
    tables: Array.isArray(apiTables) && apiTables.length ? apiTables : fallback.tables,
    tickets: Array.isArray(apiTickets) && apiTickets.length ? apiTickets : fallback.tickets,
  };
}

export default function RestaurantDemo({ initialSurface = "admin", initialSlug = "bistro-dunav", guestToken }: { initialSurface?: Surface; initialSlug?: string; guestToken?: string }) {
  const [surface, setSurface] = useState<Surface>(initialSurface);
  const [section, setSection] = useState<AdminSection>("overview");
  const [slug, setSlug] = useState(initialSlug);
  const [data, setData] = useState<RestaurantState>(() => fallbackFor(initialSlug));
  const [loading, setLoading] = useState(false);
  const [toast, setToast] = useState<string | null>(null);

  useEffect(() => {
    let active = true;
    const fallback = fallbackFor(slug);
    setData(fallback);
    setLoading(true);
    fetch(`/api/demo/state?slug=${encodeURIComponent(slug)}`, { cache: "no-store" })
      .then((response) => (response.ok ? response.json() : Promise.reject()))
      .then((payload) => {
        if (active) setData(normalizeApiState(payload.state ?? payload, fallback));
      })
      .catch(() => undefined)
      .finally(() => active && setLoading(false));
    return () => {
      active = false;
    };
  }, [slug]);

  useEffect(() => {
    if (!toast) return;
    const timer = window.setTimeout(() => setToast(null), 4200);
    return () => window.clearTimeout(timer);
  }, [toast]);

  async function postAction(action: string, payload: Record<string, unknown>) {
    try {
      let actionPayload: Record<string, unknown> = payload;
      if (action === "toggleItem") {
        actionPayload = { itemId: payload.itemId, isAvailable: payload.available };
      } else if (action === "addMenuItem") {
        const item = payload.item as MenuItem;
        const amount = Number.parseFloat(item.portion.replace(",", ".")) || undefined;
        const unit = /\bml\b/i.test(item.portion) ? "ml" : /\bg\b/i.test(item.portion) ? "g" : /kom/i.test(item.portion) ? "piece" : "portion";
        actionPayload = {
          item: {
            itemId: item.persisted ? item.id : undefined,
            categoryId: item.categoryId ?? data.items.find((entry) => entry.category === item.category)?.categoryId,
            name: item.name,
            description: item.description,
            imageAssetId: item.imageAssetId,
            isAvailable: item.available,
            isFeatured: item.featured,
            dietaryTags: item.tags,
            variants: [{ label: item.portion, portionAmount: amount, portionUnit: unit, priceMinor: Math.round(item.price * 100) }],
          },
        };
      } else if (action === "updateBranding") {
        const brand = payload.brand as Brand;
        actionPayload = { branding: { primaryColor: brand.primary, accentColor: brand.accent, backgroundColor: brand.background, textColor: brand.text, fontFamily: brand.font === "classic" ? "serif" : "sans" } };
      } else if (action === "updateSettings") {
        const settings = payload.settings as Settings;
        actionPayload = { settings: { confirmBeforeResolve: settings.confirmBeforeResolve, acceptOrders: settings.orderingEnabled && !settings.orderingPaused, waiterCallEnabled: settings.waiterCallEnabled } };
      } else if (action === "createTable") {
        const table = payload.table as DiningTable;
        actionPayload = { table: { tableNumber: table.number, label: `${table.zone} ${table.number}`, seats: 4 } };
      } else if (action === "createOrder") {
        const items = payload.items as Array<{ itemId: string; quantity: number; note?: string }>;
        actionPayload = {
          qrToken: payload.tableToken,
          clientRequestId: `web-${Date.now()}-${Math.random().toString(16).slice(2)}`,
          note: items.map((item) => item.note).filter(Boolean).join(" · "),
          items: items.map((item) => ({ itemId: item.itemId, variantId: data.items.find((entry) => entry.id === item.itemId)?.variantId, quantity: item.quantity })),
        };
      } else if (action === "createWaiterCall") {
        actionPayload = { qrToken: payload.tableToken, note: [payload.reason, payload.paymentMethod].filter(Boolean).join(" · ") };
      }
      const response = await fetch("/api/demo/action", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ slug, action, ...actionPayload }),
      });
      if (!response.ok) return;
      const result = await response.json();
      if (result.state) setData((current) => normalizeApiState(result.state, current));
    } catch {
      // The fully interactive fallback keeps the preview useful before D1 is attached.
    }
  }

  const sharedProps = { data, setData, postAction, setToast };

  return (
    <div
      className={`restaurant-demo font-${data.restaurant.brand.font}`}
      style={
        {
          "--brand-primary": data.restaurant.brand.primary,
          "--brand-accent": data.restaurant.brand.accent,
          "--brand-bg": data.restaurant.brand.background,
          "--brand-text": data.restaurant.brand.text,
          "--brand-radius": `${data.restaurant.brand.radius}px`,
        } as React.CSSProperties
      }
    >
      {surface !== "login" && (
        <div className="prototype-bar" role="navigation" aria-label="Izaberite deo prototipa">
          <div className="prototype-label"><span className="prototype-dot" /> Klikabilni prototip</div>
          <div className="surface-switcher">
            <button className={surface === "admin" ? "active" : ""} onClick={() => setSurface("admin")}>Admin</button>
            <button className={surface === "guest" ? "active" : ""} onClick={() => setSurface("guest")}>Gost · Sto 12</button>
            <button className={surface === "staff" ? "active" : ""} onClick={() => setSurface("staff")}>Osoblje <span className="count-pill">{data.tickets.filter((ticket) => ticket.status === "open").length}</span></button>
          </div>
        </div>
      )}

      {surface === "login" && <LoginScreen onLogin={() => setSurface("admin")} />}
      {surface === "admin" && (
        <AdminApp
          {...sharedProps}
          section={section}
          setSection={setSection}
          slug={slug}
          setSlug={setSlug}
          loading={loading}
          onOpenStaff={() => setSurface("staff")}
          onOpenGuest={() => setSurface("guest")}
          onLogout={() => setSurface("login")}
        />
      )}
      {surface === "guest" && <LocalizedGuestApp {...sharedProps} guestToken={guestToken} />}
      {surface === "staff" && <StaffApp {...sharedProps} />}

      {toast && <div className="global-toast" role="status"><span>✓</span>{toast}</div>}
    </div>
  );
}

function LoginScreen({ onLogin }: { onLogin: () => void }) {
  const [email, setEmail] = useState("ana@bistrodunav.rs");
  const [password, setPassword] = useState("demo2026");

  function submit(event: FormEvent) {
    event.preventDefault();
    if (email && password) onLogin();
  }

  return (
    <main className="login-screen">
      <section className="login-story">
        <div className="platform-mark light">M</div>
        <p className="eyebrow light-text">MeniFlow za restorane</p>
        <h1>Vaš meni. Vaš brend.<br />Bolja usluga.</h1>
        <p className="login-lead">Od QR menija do porudžbine i poziva konobaru — sve na jednom mestu.</p>
        <div className="login-proof">
          <span>01</span><p><strong>Jednostavan meni</strong>Menjajte ponudu i dostupnost za nekoliko sekundi.</p>
          <span>02</span><p><strong>Brža usluga</strong>Svaki zahtev odmah stiže pravoj osobi.</p>
          <span>03</span><p><strong>Vaš identitet</strong>Boje, logo i stil svakog restorana.</p>
        </div>
      </section>
      <section className="login-form-wrap">
        <form className="login-card" onSubmit={submit}>
          <div className="platform-mark">M</div>
          <p className="eyebrow">Portal za restorane</p>
          <h2>Dobro došli nazad</h2>
          <p>Prijavite se da upravljate svojim restoranom.</p>
          <label>Email adresa<input type="email" value={email} onChange={(event) => setEmail(event.target.value)} /></label>
          <label>Lozinka<input type="password" value={password} onChange={(event) => setPassword(event.target.value)} /></label>
          <div className="form-row"><label className="checkbox-label"><input type="checkbox" defaultChecked /> Zapamti me</label><button type="button" className="text-button">Zaboravljena lozinka?</button></div>
          <button className="primary-button wide" type="submit">Prijavi se <span>→</span></button>
          <div className="demo-note"><span>Demo</span> Podaci su već popunjeni — samo kliknite „Prijavi se“.</div>
        </form>
      </section>
    </main>
  );
}

type SharedProps = {
  data: RestaurantState;
  setData: React.Dispatch<React.SetStateAction<RestaurantState>>;
  postAction: (action: string, payload: Record<string, unknown>) => Promise<void>;
  setToast: React.Dispatch<React.SetStateAction<string | null>>;
};

function AdminApp({
  data,
  setData,
  postAction,
  setToast,
  section,
  setSection,
  slug,
  setSlug,
  loading,
  onOpenStaff,
  onOpenGuest,
  onLogout,
}: SharedProps & {
  section: AdminSection;
  setSection: (section: AdminSection) => void;
  slug: string;
  setSlug: (slug: string) => void;
  loading: boolean;
  onOpenStaff: () => void;
  onOpenGuest: () => void;
  onLogout: () => void;
}) {
  const nav: { id: AdminSection; label: string; icon: string }[] = [
    { id: "overview", label: "Pregled", icon: "⌂" },
    { id: "menu", label: "Meni", icon: "≡" },
    { id: "tables", label: "Stolovi i QR", icon: "▦" },
    { id: "branding", label: "Brendiranje", icon: "◐" },
    { id: "settings", label: "Podešavanja", icon: "⚙" },
  ];

  return (
    <div className="admin-shell">
      <aside className="admin-sidebar">
        <div className="admin-logo"><span>M</span><div><strong>MeniFlow</strong><small>Restaurant OS</small></div></div>
        <div className="restaurant-switch-label">Restoran</div>
        <div className="restaurant-switch">
          <span className="restaurant-avatar">{initials(data.restaurant.name)}</span>
          <label><span>{loading ? "Učitavanje…" : data.restaurant.name}</span><select aria-label="Promenite restoran" value={slug} onChange={(event) => setSlug(event.target.value)}><option value="bistro-dunav">Bistro Dunav</option><option value="casa-verde">Casa Verde</option></select><small>{data.restaurant.location}</small></label>
        </div>
        <nav className="admin-nav" aria-label="Admin navigacija">
          {nav.map((item) => <button key={item.id} className={section === item.id ? "active" : ""} onClick={() => setSection(item.id)}><span>{item.icon}</span>{item.label}{item.id === "overview" && data.tickets.filter((ticket) => ticket.status === "open").length > 0 && <b>{data.tickets.filter((ticket) => ticket.status === "open").length}</b>}</button>)}
          <button onClick={onOpenStaff}><span>↗</span>Operativni ekran<i>Uživo</i></button>
        </nav>
        <div className="sidebar-promo"><span>◌</span><strong>Treba vam pomoć?</strong><p>Naš tim odgovara za manje od 5 minuta.</p><button>Kontaktirajte podršku</button></div>
        <button className="user-card" onClick={onLogout}><span>AP</span><p><strong>Ana Petrović</strong><small>Administrator</small></p><i>•••</i></button>
      </aside>
      <main className="admin-main">
        <header className="admin-topbar">
          <div className="mobile-brand"><span>M</span>MeniFlow</div>
          <div className="topbar-actions"><button className="icon-button" aria-label="Obaveštenja">◔<i /></button><button className="secondary-button" onClick={onOpenGuest}>Pregled stranice gosta <span>↗</span></button></div>
        </header>
        <div className="admin-content">
          {section === "overview" && <AdminOverview data={data} setSection={setSection} onOpenStaff={onOpenStaff} onOpenGuest={onOpenGuest} />}
          {section === "menu" && <MenuManager {...{ data, setData, postAction, setToast }} />}
          {section === "tables" && <TablesManager {...{ data, setData, postAction, setToast }} />}
          {section === "branding" && <BrandingManager {...{ data, setData, postAction, setToast }} />}
          {section === "settings" && <SettingsManager {...{ data, setData, postAction, setToast }} />}
        </div>
      </main>
    </div>
  );
}

function PageHeading({ eyebrow, title, description, action }: { eyebrow?: string; title: string; description?: string; action?: React.ReactNode }) {
  return <div className="page-heading"><div>{eyebrow && <p className="eyebrow">{eyebrow}</p>}<h1>{title}</h1>{description && <p>{description}</p>}</div>{action}</div>;
}

function AdminOverview({ data, setSection, onOpenStaff, onOpenGuest }: { data: RestaurantState; setSection: (value: AdminSection) => void; onOpenStaff: () => void; onOpenGuest: () => void }) {
  const open = data.tickets.filter((ticket) => ticket.status === "open");
  const orders = open.filter((ticket) => ticket.kind === "order");
  const unavailable = data.items.filter((item) => !item.available).length;
  const recent = [...open].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()).slice(0, 3);
  return (
    <>
      <PageHeading eyebrow="Petak, 15. avgust" title="Dobro veče, Ana" description="Evo šta se trenutno dešava u vašem restoranu." action={<button className="primary-button" onClick={onOpenStaff}><span className="live-dot" /> Otvori operativni ekran</button>} />
      <section className="metric-grid">
        <article><span className="metric-icon green">↗</span><div><small>Aktivni zahtevi</small><strong>{open.length}</strong><p><b>{open.filter((ticket) => ticket.kind === "call").length}</b> poziva · <b>{orders.length}</b> porudžbine</p></div><em className="metric-trend">Uživo</em></article>
        <article><span className="metric-icon coral">≡</span><div><small>Artikli u meniju</small><strong>{data.items.length}</strong><p><b>{data.items.filter((item) => item.available).length}</b> dostupno danas</p></div><button onClick={() => setSection("menu")}>Uredi →</button></article>
        <article><span className="metric-icon gold">!</span><div><small>Nedostupno</small><strong>{unavailable}</strong><p>Brzo vratite u ponudu</p></div><button onClick={() => setSection("menu")}>Pregled →</button></article>
        <article><span className="metric-icon blue">▦</span><div><small>Aktivni QR stolovi</small><strong>{data.tables.filter((table) => table.active).length}</strong><p>{new Set(data.tables.map((table) => table.zone)).size} zone restorana</p></div><button onClick={() => setSection("tables")}>Stolovi →</button></article>
      </section>
      <section className="overview-grid">
        <article className="panel live-requests">
          <div className="panel-heading"><div><h2>Aktivni zahtevi</h2><p>Najstariji zahtevi su prvi.</p></div><button onClick={onOpenStaff}>Prikaži sve <span>→</span></button></div>
          <div className="request-list">
            {recent.map((ticket) => <div className="request-row" key={ticket.id}><div className={`request-type ${ticket.kind}`}><span>{ticket.kind === "call" ? "◔" : "≡"}</span></div><div className="request-main"><strong>Sto {ticket.tableNumber}</strong><p>{ticket.kind === "call" ? ticket.callReason : `${ticket.items?.reduce((sum, item) => sum + item.quantity, 0)} stavke · ${money(ticket.total ?? 0)}`}</p></div><span className={`age ${Date.now() - new Date(ticket.createdAt).getTime() > 10 * 60_000 ? "urgent" : ""}`}>{timeAgo(ticket.createdAt)}</span></div>)}
          </div>
          {recent.length === 0 && <div className="empty-small">Sve je rešeno — nema aktivnih zahteva.</div>}
        </article>
        <article className="panel rhythm-card">
          <div className="panel-heading"><div><h2>Današnji ritam</h2><p>Broj zahteva po delu dana</p></div><span className="status-chip">Danas</span></div>
          <div className="rhythm-total"><strong>47</strong><span>ukupno zahteva<br /><b>+12% u odnosu na juče</b></span></div>
          <div className="mini-chart" aria-label="Grafikon zahteva"><span style={{ height: "28%" }} /><span style={{ height: "38%" }} /><span style={{ height: "30%" }} /><span style={{ height: "52%" }} /><span style={{ height: "66%" }} /><span style={{ height: "48%" }} /><span style={{ height: "84%" }} /><span className="current" style={{ height: "100%" }} /><span style={{ height: "72%" }} /><span style={{ height: "45%" }} /></div>
          <div className="chart-labels"><span>12h</span><span>15h</span><span>18h</span><span>21h</span></div>
        </article>
      </section>
      <section className="quick-actions"><button onClick={() => setSection("menu")}><span>＋</span><p><strong>Dodaj artikal</strong><small>Proširite svoj meni</small></p><i>→</i></button><button onClick={() => setSection("tables")}><span>▦</span><p><strong>Kreiraj QR za sto</strong><small>Dodajte novi sto</small></p><i>→</i></button><button onClick={onOpenGuest}><span>◉</span><p><strong>Pogled gosta</strong><small>Proverite kako sve izgleda</small></p><i>→</i></button></section>
    </>
  );
}

function MenuManager({ data, setData, postAction, setToast }: SharedProps) {
  const [query, setQuery] = useState("");
  const [category, setCategory] = useState("Sve");
  const [showForm, setShowForm] = useState(false);
  const [editing, setEditing] = useState<MenuItem | null>(null);
  const filtered = data.items.filter((item) => (category === "Sve" || category === "Preporučujemo" ? category === "Sve" || item.featured : item.category === category) && item.name.toLowerCase().includes(query.toLowerCase()));

  function toggle(item: MenuItem) {
    setData((current) => ({ ...current, items: current.items.map((entry) => entry.id === item.id ? { ...entry, available: !entry.available } : entry) }));
    void postAction("toggleItem", { itemId: item.id, available: !item.available });
    setToast(item.available ? `${item.name} je označen kao nedostupan.` : `${item.name} je ponovo dostupan.`);
  }

  return (
    <>
      <PageHeading eyebrow="Ponuda restorana" title="Meni" description="Upravljajte jelima, pićima, cenama i dostupnošću." action={<button className="primary-button" onClick={() => { setEditing(null); setShowForm(true); }}>＋ Dodaj artikal</button>} />
      <div className="menu-toolbar"><label className="search-box"><span>⌕</span><input placeholder="Pretražite naziv artikla…" value={query} onChange={(event) => setQuery(event.target.value)} /></label><button className="secondary-button">Filteri <span>⌄</span></button><button className="secondary-button">Redosled <span>↕</span></button></div>
      <div className="category-tabs">{data.categories.map((name) => <button key={name} className={category === name ? "active" : ""} onClick={() => setCategory(name)}>{name}{name === "Sve" && <span>{data.items.length}</span>}</button>)}</div>
      <section className="panel menu-panel">
        <div className="menu-table-head"><span>Artikal</span><span>Kategorija</span><span>Porcija</span><span>Cena</span><span>Dostupno</span><span /></div>
        <div className="menu-rows">
          {filtered.map((item) => <article className={`menu-row ${!item.available ? "unavailable" : ""}`} key={item.id}>
            <div className="menu-item-info"><FoodThumb item={item} /><div><strong>{item.name}</strong><p>{item.description}</p><div className="tag-row">{item.tags.slice(0, 2).map((tag) => <span key={tag}>{tag}</span>)}{item.allergens?.length ? <em>i</em> : null}</div></div></div>
            <span className="table-category">{item.category}</span><span>{item.portion}</span><strong className="table-price">{money(item.price, data.restaurant.currency)}</strong>
            <button className={`toggle ${item.available ? "on" : ""}`} onClick={() => toggle(item)} aria-label={`Promenite dostupnost za ${item.name}`}><span /></button>
            <div className="row-actions"><button onClick={() => { setEditing(item); setShowForm(true); }}>Uredi</button><button aria-label="Više opcija">•••</button></div>
          </article>)}
        </div>
        <footer className="table-footer">Prikazano {filtered.length} od {data.items.length} artikala <span><button disabled>←</button><b>1</b><button disabled>→</button></span></footer>
      </section>
      {showForm && <MenuItemModal data={data} existing={editing} onClose={() => setShowForm(false)} onSave={async (item, file) => {
        let savedItem = item;
        if (file) {
          if (file.size > 5 * 1024 * 1024) {
            setToast("Fotografija može imati najviše 5 MB.");
            return false;
          }
          try {
            const form = new FormData();
            form.append("slug", data.restaurant.slug);
            form.append("file", file);
            const response = await fetch("/api/demo/upload", { method: "POST", body: form });
            const result = await response.json();
            if (!response.ok || !result.asset) throw new Error(result?.error?.message ?? "Upload nije uspeo.");
            savedItem = { ...item, imageAssetId: result.asset.id, image: result.asset.url };
          } catch {
            setToast("Fotografija nije sačuvana. Pokušajte ponovo.");
            return false;
          }
        }
        setData((current) => ({ ...current, items: editing ? current.items.map((entry) => entry.id === savedItem.id ? savedItem : entry) : [savedItem, ...current.items] }));
        await postAction("addMenuItem", { item: savedItem });
        setShowForm(false);
        setToast(editing ? "Izmene artikla su sačuvane." : `${savedItem.name} je dodat u meni.`);
        return true;
      }} />}
    </>
  );
}

function FoodThumb({ item, large = false }: { item: MenuItem; large?: boolean }) {
  return <div className={`food-thumb ${large ? "large" : ""}`}>{item.image ? <img src={item.image} alt="" /> : <span>{item.category.includes("pića") ? "0,3" : initials(item.name).slice(0, 1)}</span>}</div>;
}

function MenuItemModal({ data, existing, onClose, onSave }: { data: RestaurantState; existing: MenuItem | null; onClose: () => void; onSave: (item: MenuItem, file: File | null) => Promise<boolean> }) {
  const [name, setName] = useState(existing?.name ?? "");
  const [category, setCategory] = useState(existing?.category ?? "Glavna jela");
  const [description, setDescription] = useState(existing?.description ?? "");
  const [portion, setPortion] = useState(existing?.portion ?? "300 g");
  const [price, setPrice] = useState(existing?.price.toString() ?? "");
  const [tags, setTags] = useState(existing?.tags.join(", ") ?? "");
  const [available, setAvailable] = useState(existing?.available ?? true);
  const [featured, setFeatured] = useState(existing?.featured ?? false);
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [saving, setSaving] = useState(false);

  async function submit(event: FormEvent) {
    event.preventDefault();
    if (!name.trim() || !Number(price)) return;
    setSaving(true);
    const saved = await onSave({
      id: existing?.id ?? `item-${Date.now()}`,
      name: name.trim(), category, description: description.trim(), portion: portion.trim(),
      price: Number(price), available, featured, image: existing?.image, imageAssetId: existing?.imageAssetId, persisted: existing?.persisted,
      tags: tags.split(",").map((tag) => tag.trim()).filter(Boolean), allergens: existing?.allergens ?? [],
      categoryId: existing?.categoryId ?? data.items.find((item) => item.category === category)?.categoryId,
      variantId: existing?.variantId,
    }, selectedFile);
    if (!saved) setSaving(false);
  }

  return <div className="modal-backdrop" role="presentation" onMouseDown={(event) => event.target === event.currentTarget && onClose()}><form className="side-modal item-form" onSubmit={submit}><div className="modal-heading"><div><p className="eyebrow">{existing ? "Izmena ponude" : "Novi artikal"}</p><h2>{existing ? "Uredi artikal" : "Dodajte novi artikal"}</h2><p>Fotografija i dodatne oznake nisu obavezne.</p></div><button type="button" onClick={onClose}>×</button></div><div className="form-grid"><label className="full">Naziv artikla *<input autoFocus value={name} onChange={(event) => setName(event.target.value)} placeholder="npr. Teleći medaljoni" /></label><label>Kategorija *<select value={category} onChange={(event) => setCategory(event.target.value)}>{data.categories.filter((entry) => entry !== "Sve" && entry !== "Preporučujemo").map((entry) => <option key={entry}>{entry}</option>)}</select></label><label>Cena ({data.restaurant.currency}) *<input inputMode="decimal" value={price} onChange={(event) => setPrice(event.target.value)} placeholder="890" /></label><label className="full">Opis<textarea value={description} onChange={(event) => setDescription(event.target.value)} placeholder="Kratak, privlačan opis…" rows={3} /></label><label>Porcija / količina<input value={portion} onChange={(event) => setPortion(event.target.value)} placeholder="300 g ili 0,33 l" /></label><label>Oznake<input value={tags} onChange={(event) => setTags(event.target.value)} placeholder="Ljuto, Bez glutena" /></label><label className="full upload-zone"><input type="file" accept="image/png,image/jpeg,image/webp" onChange={(event) => setSelectedFile(event.target.files?.[0] ?? null)} /><span>＋</span><strong>{selectedFile?.name || (existing?.image ? "Zamenite fotografiju" : "Otpremite fotografiju")}</strong><small>PNG, JPG ili WebP · do 5 MB · opciono</small></label></div><div className="form-toggles"><label><span><strong>Dostupno za poručivanje</strong><small>Gost može da doda artikal u porudžbinu.</small></span><input type="checkbox" checked={available} onChange={(event) => setAvailable(event.target.checked)} /></label><label><span><strong>Istaknut artikal</strong><small>Prikaži u sekciji „Preporučujemo“.</small></span><input type="checkbox" checked={featured} onChange={(event) => setFeatured(event.target.checked)} /></label></div><footer><button type="button" className="secondary-button" onClick={onClose} disabled={saving}>Otkaži</button><button className="primary-button" type="submit" disabled={saving}>{saving ? "Čuvanje…" : existing ? "Sačuvaj izmene" : "Dodaj u meni"}</button></footer></form></div>;
}

function TablesManager({ data, setData, postAction, setToast }: SharedProps) {
  const [selectedId, setSelectedId] = useState(data.tables.find((table) => table.number === 12)?.id ?? data.tables[0]?.id);
  const [showAdd, setShowAdd] = useState(false);
  const [siteOrigin, setSiteOrigin] = useState("");
  useEffect(() => setSiteOrigin(window.location.origin), []);
  const selected = data.tables.find((table) => table.id === selectedId) ?? data.tables[0];
  const guestPath = `/r/${data.restaurant.slug}/t/${selected?.token ?? ""}`;
  const publicUrl = `${siteOrigin}${guestPath}`;
  const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=320x320&margin=16&data=${encodeURIComponent(publicUrl)}`;

  function addTable(zone: string) {
    const number = Math.max(0, ...data.tables.map((table) => table.number)) + 1;
    const table: DiningTable = { id: `table-${Date.now()}`, number, zone, token: `${data.restaurant.slug.slice(0, 2)}-${number}-${Math.random().toString(16).slice(2, 6)}`, active: true };
    setData((current) => ({ ...current, tables: [...current.tables, table] }));
    setSelectedId(table.id); setShowAdd(false); setToast(`Sto ${number} i njegov QR kod su kreirani.`);
    void postAction("createTable", { table });
  }

  return <>
    <PageHeading eyebrow="Fizički prostor" title="Stolovi i QR kodovi" description="Kreirajte siguran QR kod za svaki sto i zonu restorana." action={<div className="button-group"><button className="secondary-button">Preuzmi sve <span>↓</span></button><button className="primary-button" onClick={() => setShowAdd(true)}>＋ Novi sto</button></div>} />
    <div className="table-stats"><span><b>{data.tables.length}</b> ukupno stolova</span><span><b>{data.tables.filter((table) => table.active).length}</b> aktivnih QR kodova</span><span><b>{new Set(data.tables.map((table) => table.zone)).size}</b> zone</span></div>
    <section className="tables-layout">
      <article className="panel tables-list"><div className="panel-heading"><div><h2>Svi stolovi</h2><p>Kliknite na sto za pregled QR koda.</p></div><label className="small-search">⌕ <input placeholder="Pronađi sto" /></label></div><div className="zone-label">Sala <span>{data.tables.filter((table) => table.zone === "Sala").length}</span></div><div className="table-card-grid">{data.tables.filter((table) => table.zone === "Sala").map((table) => <TableCard key={table.id} table={table} selected={selected?.id === table.id} onClick={() => setSelectedId(table.id)} />)}</div>{["Terasa", "Bašta"].map((zone) => data.tables.some((table) => table.zone === zone) && <div key={zone}><div className="zone-label">{zone} <span>{data.tables.filter((table) => table.zone === zone).length}</span></div><div className="table-card-grid">{data.tables.filter((table) => table.zone === zone).map((table) => <TableCard key={table.id} table={table} selected={selected?.id === table.id} onClick={() => setSelectedId(table.id)} />)}</div></div>)}</article>
      {selected && <aside className="panel qr-preview"><div className="qr-header"><span>Pregled kartice</span><button>•••</button></div><div className="print-card"><div className="mini-logo">{initials(data.restaurant.name)}</div><h3>{data.restaurant.name}</h3><p>Skenirajte za meni<br />i poručivanje</p><div className="qr-image"><img src={qrUrl} alt={`QR kod za sto ${selected.number}`} /></div><small>VAŠ STO</small><strong>{selected.number.toString().padStart(2, "0")}</strong><em>{selected.zone}</em></div><div className="qr-actions"><button className="primary-button" onClick={() => window.print()}>Odštampaj karticu</button><a className="secondary-button" href={qrUrl} download={`qr-sto-${selected.number}.png`} target="_blank" rel="noreferrer" onClick={() => setToast("QR kod je otvoren za preuzimanje.")}>Preuzmi PNG</a></div><p className="secure-note"><span>✓</span> Kod koristi siguran token. Broj stola nije izložen u linku.</p></aside>}
    </section>
    {showAdd && <div className="modal-backdrop"><div className="compact-modal"><div className="modal-heading"><div><p className="eyebrow">Novi sto</p><h2>Izaberite zonu</h2></div><button onClick={() => setShowAdd(false)}>×</button></div><div className="zone-choice">{["Sala", "Terasa", "Bašta", "VIP"].map((zone) => <button key={zone} onClick={() => addTable(zone)}><span>▦</span>{zone}<small>Sto {Math.max(0, ...data.tables.map((table) => table.number)) + 1}</small></button>)}</div></div></div>}
  </>;
}

function TableCard({ table, selected, onClick }: { table: DiningTable; selected: boolean; onClick: () => void }) {
  return <button className={`table-card ${selected ? "selected" : ""}`} onClick={onClick}><span className="table-number">{table.number.toString().padStart(2, "0")}</span><span><strong>Sto {table.number}</strong><small><i className={table.active ? "active" : ""} /> {table.active ? "QR aktivan" : "Pauziran"}</small></span><b>›</b></button>;
}

function BrandingManager({ data, setData, postAction, setToast }: SharedProps) {
  const brand = data.restaurant.brand;
  function update(patch: Partial<Brand>) { setData((current) => ({ ...current, restaurant: { ...current.restaurant, brand: { ...current.restaurant.brand, ...patch } } })); }
  function save() { void postAction("updateBranding", { brand: data.restaurant.brand }); setToast("Brending je objavljen na stranici gosta."); }
  return <>
    <PageHeading eyebrow="Vizuelni identitet" title="Brendiranje" description="Prilagodite stranicu gosta identitetu svog restorana." action={<div className="button-group"><button className="secondary-button" onClick={() => update(bistroFallback.restaurant.brand)}>Vrati podrazumevano</button><button className="primary-button" onClick={save}>Objavi izmene</button></div>} />
    <section className="branding-layout"><article className="panel brand-controls"><div className="brand-section"><h2>Logo restorana</h2><p>PNG ili WebP, preporučeno 1:1.</p><div className="logo-upload"><span>{initials(data.restaurant.name)}</span><button className="secondary-button">Promeni logo</button><button className="text-danger">Ukloni</button></div></div><div className="brand-section"><h2>Paleta boja</h2><p>Izaberite boje koje će gost videti.</p><div className="color-grid"><ColorField label="Primarna" value={brand.primary} onChange={(value) => update({ primary: value })} /><ColorField label="Akcentna" value={brand.accent} onChange={(value) => update({ accent: value })} /><ColorField label="Pozadina" value={brand.background} onChange={(value) => update({ background: value })} /><ColorField label="Tekst" value={brand.text} onChange={(value) => update({ text: value })} /></div><div className="contrast-ok"><span>✓</span><p><strong>Odličan kontrast</strong>Tekst je lako čitljiv na izabranoj pozadini.</p></div></div><div className="brand-section"><h2>Stil interfejsa</h2><div className="style-options"><label>Tipografija<select value={brand.font} onChange={(event) => update({ font: event.target.value as Brand["font"] })}><option value="modern">Moderan sans</option><option value="classic">Klasičan serif</option><option value="soft">Mekani sans</option></select></label><label>Zaobljenost kartica<input type="range" min="8" max="28" value={brand.radius} onChange={(event) => update({ radius: Number(event.target.value) })} /><span>{brand.radius}px</span></label></div></div></article><PhonePreview data={data} /></section>
  </>;
}

function ColorField({ label, value, onChange }: { label: string; value: string; onChange: (value: string) => void }) {
  return <label>{label}<span className="color-input"><input type="color" value={value} onChange={(event) => onChange(event.target.value)} /><input value={value.toUpperCase()} onChange={(event) => /^#[0-9A-Fa-f]{0,6}$/.test(event.target.value) && onChange(event.target.value)} /></span></label>;
}

function PhonePreview({ data }: { data: RestaurantState }) {
  return <aside className="brand-preview"><div className="preview-label"><span>Pregled uživo</span><em>Mobilni prikaz</em></div><div className="phone-frame"><div className="phone-speaker" /><div className="preview-app"><header><span>{initials(data.restaurant.name)}</span><div><strong>{data.restaurant.name}</strong><small>Sto 12 · SR⌄</small></div><button>◔</button></header><div className="preview-hero"><p>Dobro veče</p><h3>Šta vam se jede?</h3><label>⌕ Pretražite meni</label></div><div className="preview-pills"><b>Preporuka</b><span>Glavna jela</span><span>Salate</span></div><div className="preview-food-grid">{data.items.filter((item) => item.available).slice(0, 2).map((item) => <div key={item.id}><FoodThumb item={item} large /><strong>{item.name}</strong><p>{item.portion}</p><span>{money(item.price, data.restaurant.currency)}</span><button>＋</button></div>)}</div><button className="preview-cart">Korpa · 2 stavke <strong>{money(1250, data.restaurant.currency)}</strong></button></div></div><p>Izmene se prikazuju odmah. Gost vidi samo objavljenu verziju.</p></aside>;
}

function SettingsManager({ data, setData, postAction, setToast }: SharedProps) {
  const settings = data.restaurant.settings;
  function update(key: keyof Settings, value: boolean) { setData((current) => ({ ...current, restaurant: { ...current.restaurant, settings: { ...current.restaurant.settings, [key]: value } } })); }
  function save() { void postAction("updateSettings", { settings }); setToast("Podešavanja restorana su sačuvana."); }
  return <>
    <PageHeading eyebrow="Način rada" title="Podešavanja" description="Kontrolišite poručivanje, obaveštenja i rad osoblja." action={<button className="primary-button" onClick={save}>Sačuvaj izmene</button>} />
    <section className="settings-layout"><div className="settings-nav"><button className="active">Opšte</button><button>Poručivanje</button><button>Ekran za osoblje</button><button>Nalozi i uloge</button><button>Jezici</button></div><div className="settings-sections"><SettingsSection title="Poručivanje preko QR menija" description="Odredite koje akcije su dostupne gostu za stolom."><SettingRow title="Dozvoli poručivanje" description="Gost može da pošalje porudžbinu direktno iz menija." checked={settings.orderingEnabled} onChange={(value) => update("orderingEnabled", value)} /><SettingRow title="Poziv konobaru" description="Gost može da zatraži pomoć ili račun." checked={settings.waiterCallEnabled} onChange={(value) => update("waiterCallEnabled", value)} /><SettingRow title="Privremeno pauziraj nove porudžbine" description="Meni ostaje vidljiv, ali poručivanje nije dostupno." checked={settings.orderingPaused} onChange={(value) => update("orderingPaused", value)} warning /></SettingsSection><SettingsSection title="Ekran za osoblje" description="Podesite ponašanje aktivnog reda zahteva."><SettingRow title="Potvrda pre uklanjanja zahteva" description="Pre završavanja zahteva pitaj „Da li ste sigurni?“" checked={settings.confirmBeforeResolve} onChange={(value) => update("confirmBeforeResolve", value)} featured /><SettingRow title="Zvuk za novi zahtev" description="Pusti diskretan zvuk kada stigne nova stavka." checked={settings.soundEnabled} onChange={(value) => update("soundEnabled", value)} /><SettingRow title="Prikaži ukupnu cenu" description="Cena porudžbine je vidljiva na kartici zahteva." checked={settings.showTotal} onChange={(value) => update("showTotal", value)} /></SettingsSection><SettingsSection title="Radno vreme poručivanja" description="Porudžbine se primaju u okviru radnog vremena."><div className="hours-row"><span>Pon–Čet</span><input defaultValue="10:00" /><i>—</i><input defaultValue="23:00" /><button>•••</button></div><div className="hours-row"><span>Pet–Ned</span><input defaultValue="10:00" /><i>—</i><input defaultValue="00:00" /><button>•••</button></div></SettingsSection></div></section>
  </>;
}

function SettingsSection({ title, description, children }: { title: string; description: string; children: React.ReactNode }) { return <article className="panel settings-card"><header><h2>{title}</h2><p>{description}</p></header>{children}</article>; }
function SettingRow({ title, description, checked, onChange, warning, featured }: { title: string; description: string; checked: boolean; onChange: (value: boolean) => void; warning?: boolean; featured?: boolean }) { return <label className={`setting-row ${featured ? "featured" : ""}`}><span><strong>{title}{warning && <em>Pauza</em>}</strong><small>{description}</small></span><input type="checkbox" checked={checked} onChange={(event) => onChange(event.target.checked)} /></label>; }

function GuestApp({ data, setData, postAction, setToast, guestToken }: SharedProps & { onBackToAdmin: () => void; guestToken?: string }) {
  const [language, setLanguage] = useState<string | null>(null);
  const [category, setCategory] = useState("Preporučujemo");
  const [query, setQuery] = useState("");
  const [cart, setCart] = useState<CartLine[]>([]);
  const [selectedItem, setSelectedItem] = useState<MenuItem | null>(null);
  const [cartOpen, setCartOpen] = useState(false);
  const [callOpen, setCallOpen] = useState(false);
  const [sent, setSent] = useState(false);
  const table = data.tables.find((entry) => guestToken && entry.token === guestToken) ?? data.tables.find((entry) => entry.number === 12) ?? data.tables[0];
  const visibleItems = data.items.filter((item) => item.available && item.name.toLowerCase().includes(query.toLowerCase()) && (category === "Preporučujemo" ? item.featured : category === "Sve" || item.category === category));
  const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const itemCount = cart.reduce((sum, item) => sum + item.quantity, 0);

  function addToCart(item: MenuItem, quantity = 1, note = "") {
    setCart((current) => {
      const existing = current.find((entry) => entry.id === item.id && entry.note === note);
      if (existing) return current.map((entry) => entry === existing ? { ...entry, quantity: entry.quantity + quantity } : entry);
      return [...current, { ...item, quantity, note }];
    });
    setSelectedItem(null); setToast(`${item.name} je dodat u porudžbinu.`);
  }

  function sendOrder() {
    if (!cart.length || !table) return;
    const ticket: Ticket = { id: `ticket-${Date.now()}`, kind: "order", status: "open", tableNumber: table.number, zone: table.zone, createdAt: new Date().toISOString(), total, items: cart.map((item) => ({ name: item.name, quantity: item.quantity, price: item.price, portion: item.portion, note: item.note })) };
    setData((current) => ({ ...current, tickets: [ticket, ...current.tickets] }));
    void postAction("createOrder", { tableToken: table.token, items: cart.map((item) => ({ itemId: item.id, quantity: item.quantity, note: item.note })) });
    setCart([]); setCartOpen(false); setSent(true);
  }

  function sendCall(reason: string, paymentMethod?: string) {
    if (!table) return;
    const duplicate = data.tickets.some((ticket) => ticket.status === "open" && ticket.kind === "call" && ticket.tableNumber === table.number && ticket.callReason === reason);
    if (duplicate) { setCallOpen(false); setToast("Konobar je već obavešten za ovaj sto."); return; }
    const ticket: Ticket = { id: `ticket-${Date.now()}`, kind: "call", status: "open", tableNumber: table.number, zone: table.zone, createdAt: new Date().toISOString(), callReason: reason, paymentMethod };
    setData((current) => ({ ...current, tickets: [ticket, ...current.tickets] }));
    void postAction("createWaiterCall", { tableToken: table.token, reason, paymentMethod });
    setCallOpen(false); setToast(`Konobar je obavešten · Sto ${table.number}`);
  }

  if (!language) return <LanguageScreen data={data} tableNumber={table?.number ?? 12} onChoose={setLanguage} />;

  return <div className="guest-page"><header className="guest-header"><div className="guest-brand"><span>{initials(data.restaurant.name)}</span><div><strong>{data.restaurant.name}</strong><small>{data.restaurant.location}</small></div></div><div className="guest-header-actions"><button onClick={() => setLanguage(null)}>{language} <span>⌄</span></button><span className="guest-table">Sto <b>{table?.number ?? 12}</b></span></div></header><main className="guest-main"><section className="guest-intro"><div><p>Dobro veče 👋</p><h1>Šta vam se jede?</h1><span>Kuhinja radi do 22:30 · priprema 15–25 min</span></div>{data.restaurant.settings.waiterCallEnabled && <button className="call-waiter" onClick={() => setCallOpen(true)}><span>◔</span><strong>Pozovi konobara</strong><small>Pomoć ili račun</small></button>}</section>{data.restaurant.settings.orderingPaused && <div className="guest-pause"><span>i</span><p><strong>Poručivanje je trenutno pauzirano.</strong>Meni možete pregledati, a konobara pozvati u svakom trenutku.</p></div>}<label className="guest-search"><span>⌕</span><input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Pretražite meni…" /></label><div className="guest-categories">{data.categories.map((name) => <button key={name} className={category === name ? "active" : ""} onClick={() => setCategory(name)}>{name}</button>)}</div><section className="guest-menu-section"><div className="guest-section-heading"><div><p className="eyebrow">Iz naše kuhinje</p><h2>{category}</h2></div><span>{visibleItems.length} artikala</span></div><div className="guest-food-grid">{visibleItems.map((item) => <article className="guest-food-card" key={item.id} onClick={() => setSelectedItem(item)}><FoodThumb item={item} large /><div className="guest-food-copy"><div className="tag-row">{item.tags.slice(0, 1).map((tag) => <span key={tag}>{tag}</span>)}</div><h3>{item.name}</h3><p>{item.description}</p><small>{item.portion}{item.allergens?.length ? " · Alergeni dostupni" : ""}</small><div><strong>{money(item.price, data.restaurant.currency)}</strong><button onClick={(event) => { event.stopPropagation(); addToCart(item); }} disabled={data.restaurant.settings.orderingPaused}>＋</button></div></div></article>)}</div>{visibleItems.length === 0 && <div className="guest-empty">Nema rezultata za ovu pretragu.</div>}</section></main>{cart.length > 0 && <button className="guest-cart-bar" onClick={() => setCartOpen(true)}><span className="cart-count">{itemCount}</span><span><small>Vaša porudžbina</small><strong>{itemCount} {itemCount === 1 ? "stavka" : "stavke"}</strong></span><b>{money(total, data.restaurant.currency)} <i>→</i></b></button>}{selectedItem && <ProductSheet item={selectedItem} currency={data.restaurant.currency} onClose={() => setSelectedItem(null)} onAdd={addToCart} />}{cartOpen && <CartSheet tableNumber={table?.number ?? 12} data={data} cart={cart} setCart={setCart} total={total} onClose={() => setCartOpen(false)} onSend={sendOrder} />}{callOpen && <WaiterCallSheet tableNumber={table?.number ?? 12} onClose={() => setCallOpen(false)} onSend={sendCall} />}{sent && <div className="modal-backdrop"><div className="success-modal"><span>✓</span><p className="eyebrow">Sto {table?.number ?? 12}</p><h2>Porudžbina je poslata</h2><p>Osoblje je primilo vaš zahtev. Prijatno!</p><div className="prep-time"><b>15–25 min</b><small>Procenjeno vreme pripreme</small></div><button className="primary-button wide" onClick={() => setSent(false)}>Nastavi pregled menija</button></div></div>}<footer className="guest-footer"><div className="guest-brand"><span>{initials(data.restaurant.name)}</span><strong>{data.restaurant.name}</strong></div><p>Digitalni meni pokreće MeniFlow</p></footer></div>;
}

function categoryLabel(name: string, language: "SR" | "EN" | "DE") {
  const labels: Record<string, [string, string]> = {
    "Sve": ["All", "Alle"], "Preporučujemo": ["Recommended", "Empfohlen"], "Glavna jela": ["Main courses", "Hauptgerichte"],
    "Salate": ["Salads", "Salate"], "Dezerti": ["Desserts", "Desserts"], "Bezalkoholna pića": ["Soft drinks", "Alkoholfreie Getränke"],
    "Alkoholna pića": ["Alcoholic drinks", "Alkoholische Getränke"], "Predjela": ["Starters", "Vorspeisen"], "Pića": ["Drinks", "Getränke"],
  };
  if (language === "SR") return name;
  return labels[name]?.[language === "EN" ? 0 : 1] ?? name;
}

function localizeMenuItem(item: MenuItem, language: "SR" | "EN" | "DE") {
  const locale = language === "EN" ? "en" : language === "DE" ? "de" : "sr-Latn";
  const translation = item.translations?.[locale] ?? item.translations?.[language.toLowerCase()];
  return translation ? { ...item, name: translation.name || item.name, description: translation.description || item.description } : item;
}

function LocalizedGuestApp({ data, setData, postAction, setToast, guestToken }: SharedProps & { guestToken?: string }) {
  const [language, setLanguage] = useState<"SR" | "EN" | "DE" | null>(null);
  const [category, setCategory] = useState("Preporučujemo");
  const [query, setQuery] = useState("");
  const [cart, setCart] = useState<CartLine[]>([]);
  const [selectedItem, setSelectedItem] = useState<MenuItem | null>(null);
  const [cartOpen, setCartOpen] = useState(false);
  const [callOpen, setCallOpen] = useState(false);
  const [sent, setSent] = useState(false);
  const table = data.tables.find((entry) => guestToken && entry.token === guestToken) ?? data.tables.find((entry) => entry.number === 12) ?? data.tables[0];
  const copy = GUEST_COPY[language ?? "SR"];
  const visibleItems = data.items
    .filter((item) => item.available && (category === "Preporučujemo" ? item.featured : category === "Sve" || item.category === category))
    .map((item) => localizeMenuItem(item, language ?? "SR"))
    .filter((item) => `${item.name} ${item.description}`.toLowerCase().includes(query.toLowerCase()));
  const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const itemCount = cart.reduce((sum, item) => sum + item.quantity, 0);

  function addToCart(item: MenuItem, quantity = 1, note = "") {
    setCart((current) => {
      const existing = current.find((entry) => entry.id === item.id && entry.note === note);
      if (existing) return current.map((entry) => entry === existing ? { ...entry, quantity: entry.quantity + quantity } : entry);
      return [...current, { ...item, quantity, note }];
    });
    setSelectedItem(null);
    setToast(language === "EN" ? `${item.name} added to your order.` : language === "DE" ? `${item.name} wurde hinzugefügt.` : `${item.name} je dodat u porudžbinu.`);
  }

  function sendOrder() {
    if (!cart.length || !table) return;
    const ticket: Ticket = {
      id: `ticket-${Date.now()}`, kind: "order", status: "open", tableNumber: table.number, zone: table.zone,
      createdAt: new Date().toISOString(), total,
      items: cart.map((item) => ({ name: item.name, quantity: item.quantity, price: item.price, portion: item.portion, note: item.note })),
    };
    setData((current) => ({ ...current, tickets: [ticket, ...current.tickets] }));
    void postAction("createOrder", { tableToken: table.token, items: cart.map((item) => ({ itemId: item.id, quantity: item.quantity, note: item.note })) });
    setCart([]);
    setCartOpen(false);
    setSent(true);
  }

  function sendCall(reason: string, paymentMethod?: string) {
    if (!table) return;
    const duplicate = data.tickets.some((ticket) => ticket.status === "open" && ticket.kind === "call" && ticket.tableNumber === table.number);
    if (duplicate) {
      setCallOpen(false);
      setToast(language === "EN" ? "A waiter has already been notified." : language === "DE" ? "Der Service wurde bereits benachrichtigt." : "Konobar je već obavešten za ovaj sto.");
      return;
    }
    const ticket: Ticket = {
      id: `ticket-${Date.now()}`, kind: "call", status: "open", tableNumber: table.number, zone: table.zone,
      createdAt: new Date().toISOString(), callReason: reason, paymentMethod,
    };
    setData((current) => ({ ...current, tickets: [ticket, ...current.tickets] }));
    void postAction("createWaiterCall", { tableToken: table.token, reason, paymentMethod });
    setCallOpen(false);
    setToast(language === "EN" ? `Waiter notified · Table ${table.number}` : language === "DE" ? `Service benachrichtigt · Tisch ${table.number}` : `Konobar je obavešten · Sto ${table.number}`);
  }

  if (!language) return <LanguageScreen data={data} tableNumber={table?.number ?? 12} onChoose={(value) => setLanguage(value as "SR" | "EN" | "DE")} />;

  return (
    <div className="guest-page">
      <header className="guest-header">
        <div className="guest-brand"><span>{initials(data.restaurant.name)}</span><div><strong>{data.restaurant.name}</strong><small>{data.restaurant.location}</small></div></div>
        <div className="guest-header-actions"><button onClick={() => setLanguage(null)}>{language} <span>⌄</span></button><span className="guest-table">{language === "EN" ? "Table" : language === "DE" ? "Tisch" : "Sto"} <b>{table?.number ?? 12}</b></span></div>
      </header>
      <main className="guest-main">
        <section className="guest-intro">
          <div><p>{copy.greeting}</p><h1>{copy.whatToEat}</h1><span>{copy.kitchenHours}</span></div>
          {data.restaurant.settings.waiterCallEnabled && <button className="call-waiter" onClick={() => setCallOpen(true)}><span>◔</span><strong>{copy.callWaiter}</strong><small>{copy.helpOrBill}</small></button>}
        </section>
        {data.restaurant.settings.orderingPaused && <div className="guest-pause"><span>i</span><p><strong>{copy.pausedTitle}</strong>{copy.pausedBody}</p></div>}
        <label className="guest-search"><span>⌕</span><input value={query} onChange={(event) => setQuery(event.target.value)} placeholder={copy.search} /></label>
        <div className="guest-categories">{data.categories.map((name) => <button key={name} className={category === name ? "active" : ""} onClick={() => setCategory(name)}>{categoryLabel(name, language)}</button>)}</div>
        <section className="guest-menu-section">
          <div className="guest-section-heading"><div><p className="eyebrow">{copy.fromKitchen}</p><h2>{categoryLabel(category, language)}</h2></div><span>{visibleItems.length} {copy.itemsLabel}</span></div>
          <div className="guest-food-grid">{visibleItems.map((item) => <article className="guest-food-card" key={item.id} onClick={() => setSelectedItem(item)}><FoodThumb item={item} large /><div className="guest-food-copy"><div className="tag-row">{item.tags.slice(0, 1).map((tag) => <span key={tag}>{tag}</span>)}</div><h3>{item.name}</h3><p>{item.description}</p><small>{item.portion}{item.allergens?.length ? ` · ${copy.allergens}` : ""}</small><div><strong>{money(item.price, data.restaurant.currency)}</strong><button onClick={(event) => { event.stopPropagation(); addToCart(item); }} disabled={data.restaurant.settings.orderingPaused}>＋</button></div></div></article>)}</div>
          {visibleItems.length === 0 && <div className="guest-empty">{copy.noResults}</div>}
        </section>
      </main>
      {cart.length > 0 && <button className="guest-cart-bar" onClick={() => setCartOpen(true)}><span className="cart-count">{itemCount}</span><span><small>{copy.yourOrder}</small><strong>{itemCount} {itemCount === 1 ? copy.oneItem : copy.manyItems}</strong></span><b>{money(total, data.restaurant.currency)} <i>→</i></b></button>}
      {selectedItem && <LocalizedProductSheet item={selectedItem} currency={data.restaurant.currency} copy={copy} onClose={() => setSelectedItem(null)} onAdd={addToCart} />}
      {cartOpen && <LocalizedCartSheet tableNumber={table?.number ?? 12} data={data} cart={cart} setCart={setCart} total={total} copy={copy} onClose={() => setCartOpen(false)} onSend={sendOrder} />}
      {callOpen && <LocalizedWaiterCallSheet tableNumber={table?.number ?? 12} copy={copy} onClose={() => setCallOpen(false)} onSend={sendCall} />}
      {sent && <div className="modal-backdrop"><div className="success-modal"><span>✓</span><p className="eyebrow">{language === "EN" ? "Table" : language === "DE" ? "Tisch" : "Sto"} {table?.number ?? 12}</p><h2>{copy.orderSent}</h2><p>{copy.orderSentBody}</p><div className="prep-time"><b>15–25 min</b><small>{copy.prepTime}</small></div><button className="primary-button wide" onClick={() => setSent(false)}>{copy.continueMenu}</button></div></div>}
      <footer className="guest-footer"><div className="guest-brand"><span>{initials(data.restaurant.name)}</span><strong>{data.restaurant.name}</strong></div><p>{copy.poweredBy}</p></footer>
    </div>
  );
}

function LocalizedProductSheet({ item, currency, copy, onClose, onAdd }: { item: MenuItem; currency: string; copy: GuestCopy; onClose: () => void; onAdd: (item: MenuItem, quantity: number, note: string) => void }) {
  const [quantity, setQuantity] = useState(1);
  const [note, setNote] = useState("");
  return <div className="modal-backdrop sheet-backdrop" onMouseDown={(event) => event.target === event.currentTarget && onClose()}><div className="guest-sheet product-sheet"><button className="sheet-close" onClick={onClose}>×</button><FoodThumb item={item} large /><div className="product-copy"><div className="tag-row">{item.tags.map((tag) => <span key={tag}>{tag}</span>)}</div><h2>{item.name}</h2><p>{item.description}</p><div className="product-meta"><span>{item.portion}</span><strong>{money(item.price, currency)}</strong></div>{item.allergens?.length ? <small>{copy.allergens}: {item.allergens.join(", ")}</small> : null}<label>{copy.kitchenNote}<textarea rows={2} placeholder={copy.noteExample} value={note} onChange={(event) => setNote(event.target.value)} /></label><div className="product-add"><div className="quantity-control"><button onClick={() => setQuantity(Math.max(1, quantity - 1))}>−</button><b>{quantity}</b><button onClick={() => setQuantity(quantity + 1)}>＋</button></div><button className="primary-button" onClick={() => onAdd(item, quantity, note)}>{copy.add} · {money(item.price * quantity, currency)}</button></div></div></div></div>;
}

function LocalizedCartSheet({ data, cart, setCart, total, onClose, onSend, tableNumber, copy }: { data: RestaurantState; cart: CartLine[]; setCart: React.Dispatch<React.SetStateAction<CartLine[]>>; total: number; onClose: () => void; onSend: () => void; tableNumber: number; copy: GuestCopy }) {
  function change(item: CartLine, delta: number) { setCart((current) => current.flatMap((entry) => entry === item ? entry.quantity + delta <= 0 ? [] : [{ ...entry, quantity: entry.quantity + delta }] : [entry])); }
  return <div className="modal-backdrop sheet-backdrop"><div className="guest-sheet cart-sheet"><div className="modal-heading"><div><p className="eyebrow">{tableNumber}</p><h2>{copy.yourOrder}</h2><p>{copy.checkItems}</p></div><button onClick={onClose}>×</button></div><div className="cart-lines">{cart.map((item) => <div className="cart-line" key={`${item.id}-${item.note}`}><FoodThumb item={item} /><div><strong>{item.name}</strong><p>{item.portion}{item.note ? ` · ${item.note}` : ""}</p><span>{money(item.price * item.quantity, data.restaurant.currency)}</span></div><div className="quantity-control small"><button onClick={() => change(item, -1)}>−</button><b>{item.quantity}</b><button onClick={() => change(item, 1)}>＋</button></div></div>)}</div><div className="cart-summary"><span>{copy.subtotal} <b>{money(total, data.restaurant.currency)}</b></span><span>{copy.service} <b>{copy.included}</b></span><strong>{copy.total} <b>{money(total, data.restaurant.currency)}</b></strong></div><div className="pay-note"><span>i</span><p><strong>{copy.payAtRestaurant}</strong>{copy.payBody}</p></div><button className="primary-button wide send-order" onClick={onSend}>{copy.sendOrder} · {money(total, data.restaurant.currency)} <span>→</span></button></div></div>;
}

function LocalizedWaiterCallSheet({ onClose, onSend, tableNumber, copy }: { onClose: () => void; onSend: (reason: string, payment?: string) => void; tableNumber: number; copy: GuestCopy }) {
  const [reason, setReason] = useState("");
  const [payment, setPayment] = useState(copy.card);
  return <div className="modal-backdrop sheet-backdrop"><div className="guest-sheet waiter-sheet"><div className="modal-heading"><div><p className="eyebrow">{tableNumber}</p><h2>{copy.callTitle}</h2><p>{copy.callBody}</p></div><button onClick={onClose}>×</button></div><div className="reason-list">{copy.reasons.map((entry, index) => <button key={entry} className={reason === entry ? "selected" : ""} onClick={() => setReason(entry)}><span>{index === 2 ? "▤" : index === 1 ? "≡" : "◔"}</span>{entry}<b>✓</b></button>)}</div>{reason === copy.reasons[2] && <div className="payment-choice"><p>{copy.payQuestion}</p><button className={payment === copy.card ? "active" : ""} onClick={() => setPayment(copy.card)}>{copy.card}</button><button className={payment === copy.cash ? "active" : ""} onClick={() => setPayment(copy.cash)}>{copy.cash}</button></div>}<button disabled={!reason} className="primary-button wide" onClick={() => onSend(reason, reason === copy.reasons[2] ? payment : undefined)}>{copy.notify} <span>→</span></button></div></div>;
}

function LanguageScreen({ data, tableNumber, onChoose }: { data: RestaurantState; tableNumber: number; onChoose: (language: string) => void }) {
  return <main className="language-screen"><div className="language-art"><div className="language-orb one" /><div className="language-orb two" /><div className="language-logo">{initials(data.restaurant.name)}</div><p>Dobro došli u</p><h1>{data.restaurant.name}</h1><span>Sto {tableNumber}</span></div><div className="language-card"><p className="eyebrow">Digitalni meni</p><h2>Izaberite jezik</h2><p>Choose your language · Sprache wählen</p><div className="language-list"><button onClick={() => onChoose("SR")}><span>SR</span><p><strong>Srpski</strong><small>Nastavite na srpskom</small></p><b>→</b></button><button onClick={() => onChoose("EN")}><span>EN</span><p><strong>English</strong><small>Continue in English</small></p><b>→</b></button><button onClick={() => onChoose("DE")}><span>DE</span><p><strong>Deutsch</strong><small>Auf Deutsch fortfahren</small></p><b>→</b></button></div><small className="language-footnote">Jezik možete promeniti u svakom trenutku.</small></div></main>;
}

function ProductSheet({ item, currency, onClose, onAdd }: { item: MenuItem; currency: string; onClose: () => void; onAdd: (item: MenuItem, quantity: number, note: string) => void }) {
  const [quantity, setQuantity] = useState(1); const [note, setNote] = useState("");
  return <div className="modal-backdrop sheet-backdrop" onMouseDown={(event) => event.target === event.currentTarget && onClose()}><div className="guest-sheet product-sheet"><button className="sheet-close" onClick={onClose}>×</button><FoodThumb item={item} large /><div className="product-copy"><div className="tag-row">{item.tags.map((tag) => <span key={tag}>{tag}</span>)}</div><h2>{item.name}</h2><p>{item.description}</p><div className="product-meta"><span>{item.portion}</span><strong>{money(item.price, currency)}</strong></div>{item.allergens?.length ? <small>Alergeni: {item.allergens.join(", ")}</small> : null}<label>Napomena za kuhinju <textarea rows={2} placeholder="Npr. bez luka" value={note} onChange={(event) => setNote(event.target.value)} /></label><div className="product-add"><div className="quantity-control"><button onClick={() => setQuantity(Math.max(1, quantity - 1))}>−</button><b>{quantity}</b><button onClick={() => setQuantity(quantity + 1)}>＋</button></div><button className="primary-button" onClick={() => onAdd(item, quantity, note)}>Dodaj · {money(item.price * quantity, currency)}</button></div></div></div></div>;
}

function CartSheet({ data, cart, setCart, total, onClose, onSend, tableNumber }: { data: RestaurantState; cart: CartLine[]; setCart: React.Dispatch<React.SetStateAction<CartLine[]>>; total: number; onClose: () => void; onSend: () => void; tableNumber: number }) {
  function change(item: CartLine, delta: number) { setCart((current) => current.flatMap((entry) => entry === item ? entry.quantity + delta <= 0 ? [] : [{ ...entry, quantity: entry.quantity + delta }] : [entry])); }
  return <div className="modal-backdrop sheet-backdrop"><div className="guest-sheet cart-sheet"><div className="modal-heading"><div><p className="eyebrow">Sto {tableNumber}</p><h2>Vaša porudžbina</h2><p>Proverite stavke pre slanja.</p></div><button onClick={onClose}>×</button></div><div className="cart-lines">{cart.map((item) => <div className="cart-line" key={`${item.id}-${item.note}`}><FoodThumb item={item} /><div><strong>{item.name}</strong><p>{item.portion}{item.note ? ` · ${item.note}` : ""}</p><span>{money(item.price * item.quantity, data.restaurant.currency)}</span></div><div className="quantity-control small"><button onClick={() => change(item, -1)}>−</button><b>{item.quantity}</b><button onClick={() => change(item, 1)}>＋</button></div></div>)}</div><div className="cart-summary"><span>Međuzbir <b>{money(total, data.restaurant.currency)}</b></span><span>Usluga <b>Uključena</b></span><strong>Ukupno <b>{money(total, data.restaurant.currency)}</b></strong></div><div className="pay-note"><span>i</span><p><strong>Plaćanje u restoranu</strong>Porudžbinu plaćate konobaru, karticom ili gotovinom.</p></div><button className="primary-button wide send-order" onClick={onSend}>Pošalji porudžbinu · {money(total, data.restaurant.currency)} <span>→</span></button></div></div>;
}

function WaiterCallSheet({ onClose, onSend, tableNumber }: { onClose: () => void; onSend: (reason: string, payment?: string) => void; tableNumber: number }) {
  const [reason, setReason] = useState(""); const [payment, setPayment] = useState("Kartica");
  const reasons = ["Potrebna mi je pomoć", "Želim da poručim", "Donesite račun", "Drugo"];
  return <div className="modal-backdrop sheet-backdrop"><div className="guest-sheet waiter-sheet"><div className="modal-heading"><div><p className="eyebrow">Sto {tableNumber}</p><h2>Pozovite konobara</h2><p>Recite nam kako možemo da pomognemo.</p></div><button onClick={onClose}>×</button></div><div className="reason-list">{reasons.map((entry) => <button key={entry} className={reason === entry ? "selected" : ""} onClick={() => setReason(entry)}><span>{entry === "Donesite račun" ? "▤" : entry === "Želim da poručim" ? "≡" : "◔"}</span>{entry}<b>✓</b></button>)}</div>{reason === "Donesite račun" && <div className="payment-choice"><p>Kako želite da platite?</p><button className={payment === "Kartica" ? "active" : ""} onClick={() => setPayment("Kartica")}>Kartica</button><button className={payment === "Gotovina" ? "active" : ""} onClick={() => setPayment("Gotovina")}>Gotovina</button></div>}<button disabled={!reason} className="primary-button wide" onClick={() => onSend(reason, reason === "Donesite račun" ? payment : undefined)}>Obavesti konobara <span>→</span></button></div></div>;
}

function StaffApp({ data, setData, postAction, setToast }: SharedProps) {
  const [tab, setTab] = useState<"active" | "history">("active");
  const [filter, setFilter] = useState<"all" | TicketKind>("all");
  const [zone, setZone] = useState("Sve zone");
  const [confirmTicket, setConfirmTicket] = useState<Ticket | null>(null);
  const [lastResolved, setLastResolved] = useState<Ticket | null>(null);
  const open = data.tickets.filter((ticket) => ticket.status === "open");
  const history = data.tickets.filter((ticket) => ticket.status === "done");
  const shown = (tab === "active" ? open : history).filter((ticket) => (filter === "all" || ticket.kind === filter) && (zone === "Sve zone" || ticket.zone === zone)).sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());

  function requestResolve(ticket: Ticket) { if (data.restaurant.settings.confirmBeforeResolve) setConfirmTicket(ticket); else resolve(ticket); }
  function resolve(ticket: Ticket) {
    setData((current) => ({ ...current, tickets: current.tickets.map((entry) => entry.id === ticket.id ? { ...entry, status: "done", resolvedAt: new Date().toISOString() } : entry) }));
    setConfirmTicket(null); setLastResolved(ticket); setToast("Zahtev je završen. Možete ga vratiti narednih nekoliko sekundi.");
    void postAction("resolveTicket", { ticketId: ticket.id });
  }
  function undo() {
    if (!lastResolved) return;
    setData((current) => ({ ...current, tickets: current.tickets.map((entry) => entry.id === lastResolved.id ? { ...entry, status: "open", resolvedAt: undefined } : entry) }));
    void postAction("undoTicket", { ticketId: lastResolved.id }); setLastResolved(null); setToast("Zahtev je vraćen u aktivni red.");
  }

  return <div className="staff-page"><header className="staff-header"><div className="staff-brand"><span>M</span><div><strong>MeniFlow</strong><small>{data.restaurant.name}</small></div></div><div className="staff-status"><span><i /> Uživo</span><button className={data.restaurant.settings.soundEnabled ? "active" : ""}>◕ Zvuk</button><button>AP</button></div></header><main className="staff-main"><div className="staff-heading"><div><p className="eyebrow">Operativni ekran</p><h1>Aktivni zahtevi</h1><p>Sve što gost pošalje, na jednom mestu i u realnom vremenu.</p></div><div className="clock"><strong>{new Date().toLocaleTimeString("sr-RS", { hour: "2-digit", minute: "2-digit" })}</strong><span>Petak, 15. avgust</span></div></div><div className="staff-toolbar"><div className="staff-tabs"><button className={tab === "active" ? "active" : ""} onClick={() => setTab("active")}>Aktivno <span>{open.length}</span></button><button className={tab === "history" ? "active" : ""} onClick={() => setTab("history")}>Istorija <span>{history.length}</span></button></div><div className="staff-filters"><button className={filter === "all" ? "active" : ""} onClick={() => setFilter("all")}>Sve</button><button className={filter === "order" ? "active" : ""} onClick={() => setFilter("order")}>Porudžbine</button><button className={filter === "call" ? "active" : ""} onClick={() => setFilter("call")}>Pozivi</button><select value={zone} onChange={(event) => setZone(event.target.value)}><option>Sve zone</option>{[...new Set(data.tables.map((table) => table.zone))].map((entry) => <option key={entry}>{entry}</option>)}</select></div></div>{shown.length > 0 ? <section className="ticket-grid">{shown.map((ticket) => <TicketCard key={ticket.id} ticket={ticket} currency={data.restaurant.currency} showTotal={data.restaurant.settings.showTotal} onResolve={() => requestResolve(ticket)} />)}</section> : <div className="empty-queue"><span>✓</span><h2>Sve je rešeno</h2><p>Trenutno nema aktivnih zahteva. Novi će se pojaviti automatski.</p></div>}</main>{lastResolved && <div className="undo-bar"><span>✓ Zahtev za Sto {lastResolved.tableNumber} je završen.</span><button onClick={undo}>Vrati</button></div>}{confirmTicket && <div className="modal-backdrop"><div className="confirm-modal"><span>?</span><p className="eyebrow">Potvrda</p><h2>Završiti ovaj zahtev?</h2><p>Sto {confirmTicket.tableNumber} biće uklonjen iz aktivnog reda i sačuvan u istoriji.</p><div><button className="secondary-button" onClick={() => setConfirmTicket(null)}>Otkaži</button><button className="primary-button" onClick={() => resolve(confirmTicket)}>Da, završi</button></div></div></div>}</div>;
}

function TicketCard({ ticket, currency, showTotal, onResolve }: { ticket: Ticket; currency: string; showTotal: boolean; onResolve: () => void }) {
  const ageMinutes = Math.floor((Date.now() - new Date(ticket.createdAt).getTime()) / 60_000);
  return <article className={`ticket-card ${ticket.kind} ${ageMinutes >= 10 ? "urgent" : ""} ${ticket.status === "done" ? "done" : ""}`}><header><div className="ticket-label"><span>{ticket.kind === "call" ? "◔" : "≡"}</span><div><small>{ticket.kind === "call" ? "Poziv konobaru" : "Nova porudžbina"}</small><strong>Sto {ticket.tableNumber}</strong></div></div><div className="ticket-age"><span className={ageMinutes >= 10 ? "urgent" : ""}>{timeAgo(ticket.createdAt)}</span><small>{ticket.zone}</small></div></header>{ticket.kind === "order" ? <div className="ticket-items">{ticket.items?.map((item, index) => <div key={`${item.name}-${index}`}><b>{item.quantity}×</b><span><strong>{item.name}</strong>{item.note && <small>Napomena: {item.note}</small>}</span>{showTotal && <em>{money(item.price * item.quantity, currency)}</em>}</div>)}</div> : <div className="call-reason"><span>{ticket.callReason === "Donesite račun" ? "▤" : "◔"}</span><p><small>Zahtev gosta</small><strong>{ticket.callReason}</strong>{ticket.paymentMethod && <em>Plaćanje: {ticket.paymentMethod}</em>}</p></div>}{ticket.kind === "order" && showTotal && <div className="ticket-total"><span>Ukupno</span><strong>{money(ticket.total ?? 0, currency)}</strong></div>}<footer>{ticket.status === "open" ? <button onClick={onResolve}><span>✓</span> Označi kao završeno</button> : <span className="done-label">✓ Završeno {ticket.resolvedAt ? timeAgo(ticket.resolvedAt) : ""}</span>}<button className="more-button">•••</button></footer></article>;
}
