// Mock data — Warung Kopi Senja (coffee shop + light kitchen, dine-in/take-away)

const TENANT = {
  name: 'Warung Kopi Senja',
  legal: 'CV Senja Kopi Nusantara',
  short: 'WKS',
  npwp: '03.214.567.8-422.000',
  address: 'Jl. Cipete Raya No. 88, Jakarta Selatan',
  phone: '021-7592-3344',
  segment: 'Coffee shop & light kitchen — dine-in & take-away',
};

const TODAY = '2026-04-22';
const NOW_HHMM = '14:32'; // simulated current time
const SHIFT = 'Siang (12:00 — 20:00)';

const PERIOD_LIST = [
  { id: '2026-02', label: 'Februari 2026' },
  { id: '2026-03', label: 'Maret 2026' },
  { id: '2026-04', label: 'April 2026' },
];
const CURRENT_PERIOD = '2026-04';

const ROLES = {
  kasir: {
    id: 'kasir', name: 'Dewi Lestari', title: 'Kasir Shift Siang', initials: 'DL',
    can: { order: true, payment: true, kitchen: false, edit_menu: false, void: false, report: false, eod: false },
  },
  barista: {
    id: 'barista', name: 'Rangga Pratama', title: 'Barista', initials: 'RP',
    can: { order: false, payment: false, kitchen: true, edit_menu: false, void: false, report: false, eod: false },
  },
  dapur: {
    id: 'dapur', name: 'Pak Yanto', title: 'Cook / Dapur', initials: 'YT',
    can: { order: false, payment: false, kitchen: true, edit_menu: false, void: false, report: false, eod: false },
  },
  manajer: {
    id: 'manajer', name: 'Bambang Setiawan', title: 'Manajer Outlet', initials: 'BS',
    can: { order: true, payment: true, kitchen: true, edit_menu: true, void: true, report: true, eod: true },
  },
};

// Menu kategori
const KATEGORI = [
  { id: 'all',     label: 'Semua' },
  { id: 'kopi',    label: 'Kopi', station: 'bar' },
  { id: 'noncoffee', label: 'Non-Coffee', station: 'bar' },
  { id: 'manual',  label: 'Manual Brew', station: 'bar' },
  { id: 'main',    label: 'Main Course', station: 'kitchen' },
  { id: 'snack',   label: 'Snack', station: 'kitchen' },
  { id: 'dessert', label: 'Dessert', station: 'kitchen' },
];

// Menu items
const MENU = [
  // Kopi
  { sku: 'CFE-ESP', name: 'Espresso',                cat: 'kopi',      price:  22_000, cost:  6_500, station: 'bar', desc: 'Single shot, ristretto profile' },
  { sku: 'CFE-AME', name: 'Americano',               cat: 'kopi',      price:  25_000, cost:  6_800, station: 'bar' },
  { sku: 'CFE-CAP', name: 'Cappuccino',              cat: 'kopi',      price:  32_000, cost:  9_200, station: 'bar' },
  { sku: 'CFE-LAT', name: 'Caffè Latte',             cat: 'kopi',      price:  32_000, cost:  9_500, station: 'bar' },
  { sku: 'CFE-PIC', name: 'Piccolo Latte',           cat: 'kopi',      price:  30_000, cost:  8_400, station: 'bar' },
  { sku: 'CFE-MOC', name: 'Mocha',                   cat: 'kopi',      price:  38_000, cost: 11_200, station: 'bar' },
  { sku: 'CFE-CTL', name: 'Caramel Macchiato',       cat: 'kopi',      price:  42_000, cost: 12_800, station: 'bar', popular: true },
  { sku: 'CFE-VIE', name: 'Vietnam Drip Susu',       cat: 'kopi',      price:  28_000, cost:  8_200, station: 'bar' },
  { sku: 'CFE-KSU', name: 'Kopi Susu Senja',         cat: 'kopi',      price:  24_000, cost:  7_400, station: 'bar', popular: true, signature: true },

  // Manual brew
  { sku: 'MBR-V60', name: 'V60 Pour Over',           cat: 'manual',    price:  38_000, cost:  9_800, station: 'bar' },
  { sku: 'MBR-AER', name: 'Aeropress',               cat: 'manual',    price:  36_000, cost:  9_400, station: 'bar' },
  { sku: 'MBR-FRP', name: 'French Press (250ml)',    cat: 'manual',    price:  42_000, cost: 11_200, station: 'bar' },

  // Non-coffee
  { sku: 'NCF-MAT', name: 'Matcha Latte',            cat: 'noncoffee', price:  36_000, cost: 11_400, station: 'bar' },
  { sku: 'NCF-CHO', name: 'Chocolate Hot/Ice',       cat: 'noncoffee', price:  32_000, cost:  9_800, station: 'bar' },
  { sku: 'NCF-RTH', name: 'Red Velvet Latte',        cat: 'noncoffee', price:  38_000, cost: 12_200, station: 'bar' },
  { sku: 'NCF-LET', name: 'Lemon Tea',               cat: 'noncoffee', price:  22_000, cost:  5_800, station: 'bar' },
  { sku: 'NCF-LIT', name: 'Lychee Tea',              cat: 'noncoffee', price:  26_000, cost:  7_200, station: 'bar' },
  { sku: 'NCF-MIN', name: 'Air Mineral 600ml',       cat: 'noncoffee', price:   8_000, cost:  3_500, station: 'bar' },

  // Main course
  { sku: 'MAI-NSG', name: 'Nasi Goreng Senja',       cat: 'main',      price:  42_000, cost: 14_500, station: 'kitchen', signature: true },
  { sku: 'MAI-MGR', name: 'Mie Goreng Special',      cat: 'main',      price:  38_000, cost: 12_800, station: 'kitchen' },
  { sku: 'MAI-NAY', name: 'Nasi Ayam Geprek',        cat: 'main',      price:  42_000, cost: 14_200, station: 'kitchen', popular: true },
  { sku: 'MAI-CRB', name: 'Chicken Rice Bowl',       cat: 'main',      price:  48_000, cost: 16_800, station: 'kitchen' },
  { sku: 'MAI-BUR', name: 'Beef Burger Senja',       cat: 'main',      price:  58_000, cost: 22_400, station: 'kitchen' },
  { sku: 'MAI-PSC', name: 'Pasta Aglio Olio',        cat: 'main',      price:  48_000, cost: 15_200, station: 'kitchen' },
  { sku: 'MAI-SDW', name: 'Club Sandwich',           cat: 'main',      price:  45_000, cost: 14_800, station: 'kitchen' },

  // Snack
  { sku: 'SNK-FRY', name: 'French Fries',            cat: 'snack',     price:  28_000, cost:  9_400, station: 'kitchen', popular: true },
  { sku: 'SNK-CWG', name: 'Chicken Wings (6pc)',     cat: 'snack',     price:  42_000, cost: 14_800, station: 'kitchen' },
  { sku: 'SNK-PSP', name: 'Pisang Nutella',          cat: 'snack',     price:  28_000, cost:  8_400, station: 'kitchen' },
  { sku: 'SNK-MOZ', name: 'Mozzarella Stick',        cat: 'snack',     price:  32_000, cost: 10_400, station: 'kitchen' },

  // Dessert
  { sku: 'DSR-CCK', name: 'Chocolate Cake',          cat: 'dessert',   price:  38_000, cost: 12_400, station: 'kitchen' },
  { sku: 'DSR-CHC', name: 'Cheesecake Original',     cat: 'dessert',   price:  42_000, cost: 13_800, station: 'kitchen' },
  { sku: 'DSR-AFD', name: 'Affogato',                cat: 'dessert',   price:  36_000, cost: 11_200, station: 'bar', signature: true },
];
const MENU_BY_SKU = Object.fromEntries(MENU.map(m => [m.sku, m]));

// Tables (floor plan)
// Layout zones: indoor, outdoor (semi), bar
const TABLES = [
  // Indoor
  { id: 'T01', label: 'T01', zone: 'indoor', x:  6, y:  8, w: 12, h: 10, seats: 2, status: 'occupied',  occupiedSince: '13:48', orderId: 'ORD-2026-0418', guests: 2 },
  { id: 'T02', label: 'T02', zone: 'indoor', x: 22, y:  8, w: 12, h: 10, seats: 2, status: 'available' },
  { id: 'T03', label: 'T03', zone: 'indoor', x: 38, y:  8, w: 14, h: 10, seats: 4, status: 'occupied',  occupiedSince: '13:30', orderId: 'ORD-2026-0419', guests: 3 },
  { id: 'T04', label: 'T04', zone: 'indoor', x: 56, y:  8, w: 14, h: 10, seats: 4, status: 'available' },
  { id: 'T05', label: 'T05', zone: 'indoor', x:  6, y: 22, w: 12, h: 10, seats: 2, status: 'reserved', reservedAt: '15:00', reservedBy: 'Pak Tono' },
  { id: 'T06', label: 'T06', zone: 'indoor', x: 22, y: 22, w: 12, h: 10, seats: 2, status: 'occupied',  occupiedSince: '14:12', orderId: 'ORD-2026-0420', guests: 2 },
  { id: 'T07', label: 'T07', zone: 'indoor', x: 38, y: 22, w: 14, h: 10, seats: 4, status: 'cleaning' },
  { id: 'T08', label: 'T08', zone: 'indoor', x: 56, y: 22, w: 14, h: 10, seats: 6, status: 'occupied',  occupiedSince: '13:05', orderId: 'ORD-2026-0421', guests: 5 },
  // Outdoor
  { id: 'T09',  label: 'T09', zone: 'outdoor', x:  6, y: 40, w: 14, h: 12, seats: 4, status: 'occupied', occupiedSince: '14:20', orderId: 'ORD-2026-0422', guests: 4 },
  { id: 'T10',  label: 'T10', zone: 'outdoor', x: 24, y: 40, w: 14, h: 12, seats: 4, status: 'available' },
  { id: 'T11',  label: 'T11', zone: 'outdoor', x: 42, y: 40, w: 14, h: 12, seats: 4, status: 'available' },
  { id: 'T12',  label: 'T12', zone: 'outdoor', x: 60, y: 40, w: 14, h: 12, seats: 4, status: 'occupied', occupiedSince: '14:25', orderId: 'ORD-2026-0423', guests: 2 },
  // Bar seats
  { id: 'B01', label: 'B1', zone: 'bar', x:  6, y: 60, w:  6, h:  8, seats: 1, status: 'available' },
  { id: 'B02', label: 'B2', zone: 'bar', x: 14, y: 60, w:  6, h:  8, seats: 1, status: 'occupied', occupiedSince: '14:00', orderId: 'ORD-2026-0424', guests: 1 },
  { id: 'B03', label: 'B3', zone: 'bar', x: 22, y: 60, w:  6, h:  8, seats: 1, status: 'available' },
  { id: 'B04', label: 'B4', zone: 'bar', x: 30, y: 60, w:  6, h:  8, seats: 1, status: 'available' },
];

// Active orders (live)
const ORDERS = [
  {
    id: 'ORD-2026-0424', table: 'B02', kasir: 'Dewi Lestari', opened: '14:00', status: 'preparing', guests: 1,
    items: [
      { sku: 'MBR-V60', qty: 1, status: 'in-progress', station: 'bar', startedAt: '14:02', notes: 'Beans Aceh Gayo' },
      { sku: 'SNK-PSP', qty: 1, status: 'queued', station: 'kitchen' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0423', table: 'T12', kasir: 'Dewi Lestari', opened: '14:25', status: 'open', guests: 2,
    items: [
      { sku: 'CFE-CAP', qty: 2, status: 'queued', station: 'bar' },
      { sku: 'SNK-FRY', qty: 1, status: 'queued', station: 'kitchen' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0422', table: 'T09', kasir: 'Dewi Lestari', opened: '14:20', status: 'preparing', guests: 4,
    items: [
      { sku: 'CFE-LAT', qty: 2, status: 'ready',       station: 'bar', readyAt: '14:28' },
      { sku: 'NCF-MAT', qty: 1, status: 'in-progress', station: 'bar', startedAt: '14:26' },
      { sku: 'MAI-NAY', qty: 2, status: 'in-progress', station: 'kitchen', startedAt: '14:24' },
      { sku: 'SNK-FRY', qty: 1, status: 'ready',       station: 'kitchen', readyAt: '14:30' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0421', table: 'T08', kasir: 'Dewi Lestari', opened: '13:05', status: 'served', guests: 5,
    items: [
      { sku: 'CFE-CAP', qty: 2, status: 'served', station: 'bar' },
      { sku: 'CFE-KSU', qty: 2, status: 'served', station: 'bar' },
      { sku: 'NCF-CHO', qty: 1, status: 'served', station: 'bar' },
      { sku: 'MAI-NSG', qty: 2, status: 'served', station: 'kitchen' },
      { sku: 'MAI-BUR', qty: 1, status: 'served', station: 'kitchen' },
      { sku: 'SNK-CWG', qty: 1, status: 'served', station: 'kitchen' },
      { sku: 'DSR-CCK', qty: 2, status: 'served', station: 'kitchen' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0420', table: 'T06', kasir: 'Dewi Lestari', opened: '14:12', status: 'preparing', guests: 2,
    items: [
      { sku: 'CFE-CTL', qty: 1, status: 'in-progress', station: 'bar', startedAt: '14:14' },
      { sku: 'CFE-AME', qty: 1, status: 'ready',       station: 'bar', readyAt: '14:18' },
      { sku: 'DSR-AFD', qty: 1, status: 'queued',      station: 'bar' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0419', table: 'T03', kasir: 'Eko Wahyudi', opened: '13:30', status: 'served', guests: 3,
    items: [
      { sku: 'CFE-LAT', qty: 1, status: 'served', station: 'bar' },
      { sku: 'CFE-MOC', qty: 1, status: 'served', station: 'bar' },
      { sku: 'NCF-LET', qty: 1, status: 'served', station: 'bar' },
      { sku: 'MAI-PSC', qty: 1, status: 'served', station: 'kitchen' },
      { sku: 'MAI-CRB', qty: 1, status: 'served', station: 'kitchen' },
      { sku: 'SNK-MOZ', qty: 1, status: 'served', station: 'kitchen' },
    ],
    payment: null,
  },
  {
    id: 'ORD-2026-0418', table: 'T01', kasir: 'Eko Wahyudi', opened: '13:48', status: 'served', guests: 2,
    items: [
      { sku: 'CFE-PIC', qty: 1, status: 'served', station: 'bar' },
      { sku: 'CFE-VIE', qty: 1, status: 'served', station: 'bar' },
      { sku: 'SNK-FRY', qty: 1, status: 'served', station: 'kitchen' },
      { sku: 'DSR-CHC', qty: 1, status: 'served', station: 'kitchen' },
    ],
    payment: null,
  },
];

// Closed/paid orders (today, for sales report)
const SALES_TODAY = [
  { id: 'ORD-2026-0417', table: 'T-O', closedAt: '13:42', total: 184_000, method: 'qris',  items: 5, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0416', table: 'B04', closedAt: '13:28', total:  62_000, method: 'cash',  items: 2, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0415', table: 'T07', closedAt: '13:15', total: 248_000, method: 'qris',  items: 7, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0414', table: 'T-O', closedAt: '12:58', total:  86_000, method: 'cash',  items: 3, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0413', table: 'T04', closedAt: '12:42', total: 168_000, method: 'qris',  items: 4, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0412', table: 'T-O', closedAt: '12:24', total:  52_000, method: 'cash',  items: 2, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0411', table: 'T11', closedAt: '12:08', total: 312_000, method: 'edc',   items: 8, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0410', table: 'B01', closedAt: '11:48', total:  74_000, method: 'qris',  items: 2, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0409', table: 'T-O', closedAt: '11:32', total: 124_000, method: 'cash',  items: 4, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0408', table: 'T05', closedAt: '11:15', total: 196_000, method: 'qris',  items: 5, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0407', table: 'T-O', closedAt: '10:48', total:  48_000, method: 'cash',  items: 2, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0406', table: 'T-O', closedAt: '10:22', total: 102_000, method: 'qris',  items: 3, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0405', table: 'B02', closedAt: '10:08', total:  66_000, method: 'cash',  items: 2, kasir: 'Eko Wahyudi' },
  { id: 'ORD-2026-0404', table: 'T01', closedAt: '09:42', total: 156_000, method: 'qris',  items: 4, kasir: 'Eko Wahyudi' },
];

// Reservations (today)
const RESERVATIONS = [
  { id: 'RSV-001', name: 'Pak Tono',          phone: '081234-***-456', time: '15:00', table: 'T05', guests: 2, note: 'Anniversary, request meja dekat jendela' },
  { id: 'RSV-002', name: 'Ibu Wina',          phone: '081234-***-122', time: '17:30', table: 'T08', guests: 5, note: '—' },
  { id: 'RSV-003', name: 'Studio Kreatif XY', phone: '021-7882-***',  time: '18:00', table: 'T03+T04', guests: 8, note: 'Meeting, butuh colokan' },
  { id: 'RSV-004', name: 'Sdr. Ferry',        phone: '081234-***-019', time: '19:00', table: 'T11', guests: 3, note: '—' },
];

// Daily revenue trend (last 22 days)
const DAILY_REVENUE = [
  { date: '2026-04-01', total:  4_120_000, orders: 86 }, { date: '2026-04-02', total:  3_840_000, orders: 78 },
  { date: '2026-04-03', total:  5_240_000, orders: 102 }, { date: '2026-04-04', total:  6_480_000, orders: 124 },
  { date: '2026-04-05', total:  6_820_000, orders: 138 }, { date: '2026-04-06', total:  3_240_000, orders: 64 },
  { date: '2026-04-07', total:  4_480_000, orders: 88 }, { date: '2026-04-08', total:  4_780_000, orders: 96 },
  { date: '2026-04-09', total:  5_120_000, orders: 102 }, { date: '2026-04-10', total:  6_240_000, orders: 124 },
  { date: '2026-04-11', total:  7_120_000, orders: 142 }, { date: '2026-04-12', total:  3_680_000, orders: 72 },
  { date: '2026-04-13', total:  4_240_000, orders: 86 }, { date: '2026-04-14', total:  4_820_000, orders: 96 },
  { date: '2026-04-15', total:  5_480_000, orders: 108 }, { date: '2026-04-16', total:  4_960_000, orders: 98 },
  { date: '2026-04-17', total:  6_120_000, orders: 122 }, { date: '2026-04-18', total:  7_240_000, orders: 144 },
  { date: '2026-04-19', total:  5_840_000, orders: 116 }, { date: '2026-04-20', total:  6_480_000, orders: 128 },
  { date: '2026-04-21', total:  6_120_000, orders: 122 }, { date: '2026-04-22', total:  3_840_000, orders: 73 }, // today (in progress)
];

// Sales by hour (today, 08:00-14:00 done; 14:00-22:00 forecasted/empty)
const HOURLY_TODAY = [
  { hour: '08', revenue:  248_000, orders:  8 },
  { hour: '09', revenue:  386_000, orders: 12 },
  { hour: '10', revenue:  428_000, orders: 11 },
  { hour: '11', revenue:  524_000, orders: 14 },
  { hour: '12', revenue:  748_000, orders: 18 },
  { hour: '13', revenue:  892_000, orders: 22 },
  { hour: '14', revenue:  614_000, orders: 16 }, // partial (14:32)
  { hour: '15', revenue:  0, orders: 0 },
  { hour: '16', revenue:  0, orders: 0 },
  { hour: '17', revenue:  0, orders: 0 },
  { hour: '18', revenue:  0, orders: 0 },
  { hour: '19', revenue:  0, orders: 0 },
  { hour: '20', revenue:  0, orders: 0 },
  { hour: '21', revenue:  0, orders: 0 },
];

// Best-sellers (last 7 days)
const TOP_ITEMS = [
  { sku: 'CFE-KSU', sold: 184, revenue:  4_416_000 },
  { sku: 'CFE-CTL', sold: 142, revenue:  5_964_000 },
  { sku: 'CFE-LAT', sold: 138, revenue:  4_416_000 },
  { sku: 'MAI-NAY', sold:  86, revenue:  3_612_000 },
  { sku: 'SNK-FRY', sold:  82, revenue:  2_296_000 },
  { sku: 'CFE-CAP', sold:  78, revenue:  2_496_000 },
  { sku: 'MAI-NSG', sold:  64, revenue:  2_688_000 },
  { sku: 'CFE-AME', sold:  58, revenue:  1_450_000 },
];

// Inventory bahan baku (consumable inventory)
const BAHAN = [
  { id: 'BB-COF-AC',  name: 'Biji Kopi Aceh Gayo (1kg)',  unit: 'kg',  stock:  4.2, par:  6, supplier: 'Klasik Beans',  cost: 285_000, lastIn: '2026-04-18' },
  { id: 'BB-COF-TR',  name: 'Biji Kopi Toraja (1kg)',     unit: 'kg',  stock:  2.8, par:  4, supplier: 'Klasik Beans',  cost: 320_000, lastIn: '2026-04-18' },
  { id: 'BB-COF-HSE', name: 'House Blend (1kg)',          unit: 'kg',  stock:  6.4, par: 10, supplier: 'Klasik Beans',  cost: 248_000, lastIn: '2026-04-20' },
  { id: 'BB-MLK-FRS', name: 'Susu Segar UHT (1L)',        unit: 'L',   stock: 28,   par: 36, supplier: 'PT Greenfields', cost:  18_500, lastIn: '2026-04-21' },
  { id: 'BB-MLK-OAT', name: 'Oat Milk (1L)',              unit: 'L',   stock:  6,   par: 12, supplier: 'CV Plant Co',   cost:  42_000, lastIn: '2026-04-19' },
  { id: 'BB-SYR-VAN', name: 'Sirup Vanilla (700ml)',      unit: 'btl', stock:  3,   par:  4, supplier: 'Monin ID',      cost: 168_000, lastIn: '2026-04-15' },
  { id: 'BB-SYR-CRM', name: 'Sirup Caramel (700ml)',      unit: 'btl', stock:  1,   par:  4, supplier: 'Monin ID',      cost: 168_000, lastIn: '2026-04-08' }, // low!
  { id: 'BB-AYM-FIL', name: 'Ayam Fillet (kg)',           unit: 'kg',  stock:  4.6, par:  8, supplier: 'Pasar Cipete',  cost:  62_000, lastIn: '2026-04-22' },
  { id: 'BB-DG-GIL',  name: 'Daging Sapi Giling (kg)',    unit: 'kg',  stock:  2.4, par:  4, supplier: 'Pasar Cipete',  cost: 142_000, lastIn: '2026-04-22' },
  { id: 'BB-RSI-PUT', name: 'Beras Putih (kg)',           unit: 'kg',  stock: 18,   par: 24, supplier: 'Pasar Cipete',  cost:  14_500, lastIn: '2026-04-19' },
  { id: 'BB-KEN-MOZ', name: 'Keju Mozzarella (kg)',       unit: 'kg',  stock:  1.8, par:  3, supplier: 'CV Dairy ID',   cost: 168_000, lastIn: '2026-04-17' },
  { id: 'BB-MAT-PWD', name: 'Bubuk Matcha (200gr)',       unit: 'pak', stock:  2,   par:  4, supplier: 'Monin ID',      cost: 248_000, lastIn: '2026-04-12' },
];

// KPI snapshot
const KPI = {
  revenueToday: 4_454_000,    // sum of HOURLY_TODAY
  ordersToday: 73,
  avgTicket:  61_014,         // revenue / orders
  occupancyNow: 9 / 16,       // tables occupied / total
  ordersOpen: 6,              // ORDERS yet to be paid
  itemsInProgress: 8,         // items in queued+in-progress in KDS
  topItem: 'CFE-KSU',
  bahanBawahPar: 6,
  shiftCount: 2,
  refundsToday: 0,
};

// Activity stream
const ACTIVITY = [
  { id: 'A1', time: '14:32', type: 'order',  text: 'ORD-2026-0424 dibuka di Bar 2 (1 tamu)',           who: 'Dewi Lestari', urgent: false },
  { id: 'A2', time: '14:30', type: 'kds',    text: 'French Fries siap di KDS dapur (ORD-...0422)',      who: 'sistem',       urgent: false },
  { id: 'A3', time: '14:28', type: 'kds',    text: 'Caffè Latte ×2 siap di Bar (ORD-...0422)',         who: 'sistem',       urgent: false },
  { id: 'A4', time: '14:25', type: 'order',  text: 'ORD-2026-0423 dibuka di T12',                       who: 'Dewi Lestari', urgent: false },
  { id: 'A5', time: '14:18', type: 'kds',    text: 'Americano siap di Bar (ORD-...0420) — overdue 4mnt', who: 'sistem',       urgent: true },
  { id: 'A6', time: '14:00', type: 'rsv',    text: 'Reminder: Pak Tono reservasi T05 jam 15:00 (2 tamu)', who: 'sistem',       urgent: false },
  { id: 'A7', time: '13:42', type: 'paid',   text: 'ORD-2026-0417 dibayar QRIS Rp 184.000',             who: 'Eko Wahyudi',  urgent: false },
];

// ── Helpers ────────────────────────────────────────────────────────────────

function rupiah(n, opts = {}) {
  if (n == null || isNaN(n)) return '—';
  const sign = n < 0 ? '-' : '';
  const abs = Math.abs(Math.round(n));
  if (opts.compact && abs >= 1_000_000_000) return sign + (abs / 1_000_000_000).toFixed(2).replace('.', ',') + ' M';
  if (opts.compact && abs >= 1_000_000)     return sign + (abs / 1_000_000).toFixed(1).replace('.', ',') + ' jt';
  if (opts.compact && abs >= 1_000)         return sign + (abs / 1_000).toFixed(0) + 'rb';
  const str = abs.toLocaleString('id-ID');
  return (opts.sym ? 'Rp ' : '') + sign + str;
}

function formatDateID(iso) {
  if (!iso) return '—';
  const m = ['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Agu','Sep','Okt','Nov','Des'];
  const d = new Date(iso);
  return `${d.getDate()} ${m[d.getMonth()]} ${d.getFullYear()}`;
}

function periodLabel(id) {
  return PERIOD_LIST.find(p => p.id === id)?.label || id;
}

function minutesSince(hhmm) {
  if (!hhmm) return 0;
  const [h, m] = hhmm.split(':').map(Number);
  const [nh, nm] = NOW_HHMM.split(':').map(Number);
  return (nh * 60 + nm) - (h * 60 + m);
}

function fmtMin(mins) {
  if (mins < 1) return 'baru saja';
  if (mins < 60) return `${mins} menit`;
  const h = Math.floor(mins / 60), m = mins % 60;
  return `${h}j ${m}m`;
}

function orderTotal(o) {
  return o.items.reduce((s, it) => s + (MENU_BY_SKU[it.sku]?.price || 0) * it.qty, 0);
}

function statusTone(s) {
  return ({
    available: 'success', occupied: 'warn', reserved: 'accent', cleaning: 'neutral',
    open: 'accent', preparing: 'warn', served: 'success', paid: 'success',
    queued: 'neutral', 'in-progress': 'warn', ready: 'success', delivered: 'success',
    cash: 'neutral', qris: 'accent', edc: 'accent',
    rendah: 'warn', kritis: 'danger',
  })[s] || 'neutral';
}

function statusLabel(s) {
  return ({
    available: 'Kosong', occupied: 'Terisi', reserved: 'Reserved', cleaning: 'Cleaning',
    open: 'Open', preparing: 'Preparing', served: 'Served', paid: 'Paid',
    queued: 'Queued', 'in-progress': 'Bikin', ready: 'Ready', delivered: 'Sajikan',
    cash: 'Cash', qris: 'QRIS', edc: 'Kartu',
    bar: 'Bar', kitchen: 'Dapur',
  })[s] || s;
}

Object.assign(window, {
  TENANT, TODAY, NOW_HHMM, SHIFT, PERIOD_LIST, CURRENT_PERIOD, ROLES,
  KATEGORI, MENU, MENU_BY_SKU, TABLES, ORDERS,
  SALES_TODAY, RESERVATIONS, DAILY_REVENUE, HOURLY_TODAY, TOP_ITEMS,
  BAHAN, KPI, ACTIVITY,
  rupiah, formatDateID, periodLabel, minutesSince, fmtMin, orderTotal,
  statusTone, statusLabel,
});
