import React, { useState, useMemo, useRef, useEffect } from "react";
import { createRoot } from "react-dom/client";
import * as XLSX from "xlsx";
import { api } from "./api.js";
import {
  ShoppingCart, LayoutGrid, CalendarDays, Settings2, ChefHat, Coffee,
  Users, Award, Percent, Gift, History, UtensilsCrossed, Tag, Megaphone,
  Plus, Minus, X, Search, Clock, Star, Trash2, Pencil, ChevronLeft,
  ChevronRight, Flame, GlassWater, CheckCircle2, CircleDot, Timer, Check,
  Armchair, MapPin, PhoneCall, ReceiptText, Sparkles, Store, Building2, ExternalLink,
  QrCode, Truck, ChevronDown, ChevronUp, ImageIcon, CreditCard, Printer, RefreshCw, Ban, MessageCircle, Wifi, Mail,
  Briefcase, ShieldCheck, Copy, Link2, Banknote, Eye, ClipboardList, Volume2,
  Package, Boxes, AlertTriangle, BookUser, LayoutDashboard, TrendingUp,
  Download, FileSpreadsheet, FileText, Bell, Palette, Upload
} from "lucide-react";

const LOGO_DATA_URI = "data:image/jpeg;base64,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";
const LOGIN_BG_DATA_URI = "data:image/jpeg;base64,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";

/* =========================================================================
   MOCK DATA
   ========================================================================= */

const CATEGORY_SEED = [
  { id: "c1", name: "อาหารคาว", kind: "food" },
  { id: "c2", name: "ของทานเล่น", kind: "food" },
  { id: "c3", name: "อาหารหวาน", kind: "food" },
  { id: "c4", name: "เครื่องดื่ม", kind: "drink" },
];

const MENU_SEED = [
  { id: "m1", name: "ผัดกะเพราหมูสับ", price: 65, catId: "c1", desc: "ราดข้าว ไข่ดาว 1 ฟอง", recipe: [{ stockItemId: "st1", qty: 0.15 }, { stockItemId: "st5", qty: 0.03 }, { stockItemId: "st11", qty: 0.02 }] },
  {
    id: "m1b", name: "เตี๋ยวหมูต้มยำ โบราณ", price: 60, catId: "c1",
    desc: "เตี๋ยวต้มยำโบราณรสจัดจ้าน หมูสับบะช่อเน้นๆ ไม่ใส่กุ้งแห้ง ไม่ใส่น้ำพริกเผา ใช้มะนาวสด",
    recipe: [{ stockItemId: "st1", qty: 0.1 }, { stockItemId: "st8", qty: 0.02 }],
    optionGroups: [
      { id: "og-type", name: "ประเภท", type: "single", required: true, max: 1, choices: [
        { id: "oc-soup", name: "น้ำ (แยกน้ำ)", price: 0 },
        { id: "oc-dry", name: "แห้ง (พร้อมน้ำซุป)", price: 0 },
      ]},
      { id: "og-extra", name: "พิเศษเครื่องต่างๆ", type: "multiple", required: false, max: 14, choices: [
        { id: "oc-noodle", name: "เพิ่มเส้น", price: 15 },
        { id: "oc-pork", name: "หมูสับ (บะช่อ)", price: 25 },
        { id: "oc-liver", name: "ตับ", price: 15 },
        { id: "oc-porkball", name: "ลูกชิ้นหมู", price: 15 },
        { id: "oc-dumpling", name: "เกี๊ยวหมู", price: 20 },
      ]},
    ],
  },
  { id: "m2", name: "ข้าวผัดปู", price: 95, catId: "c1", desc: "เนื้อปูล้วน หอมน้ำมันกระเทียม", recipe: [{ stockItemId: "st4", qty: 0.1 }, { stockItemId: "st12", qty: 0.2 }, { stockItemId: "st11", qty: 0.02 }] },
  { id: "m3", name: "ต้มยำกุ้งน้ำข้น", price: 150, catId: "c1", desc: "กุ้งแม่น้ำ เห็ดฟาง ใบมะกรูด", recipe: [{ stockItemId: "st2", qty: 0.2 }] },
  { id: "m4", name: "แกงเขียวหวานไก่", price: 80, catId: "c1", desc: "เสิร์ฟพร้อมข้าวสวย", recipe: [{ stockItemId: "st3", qty: 0.12 }, { stockItemId: "st12", qty: 0.2 }] },
  { id: "m5", name: "ปีกไก่ทอดน้ำปลา", price: 70, catId: "c2", desc: "ทอดกรอบ หอมกระเทียม", recipe: [{ stockItemId: "st3", qty: 0.15 }, { stockItemId: "st9", qty: 0.01 }] },
  { id: "m6", name: "ปอเปี๊ยะทอด", price: 60, catId: "c2", desc: "6 ชิ้น พร้อมซอสบ๊วย" },
  { id: "m7", name: "ข้าวเหนียวมะม่วง", price: 89, catId: "c3", desc: "มะม่วงน้ำดอกไม้ตามฤดูกาล", recipe: [{ stockItemId: "st6", qty: 0.15 }, { stockItemId: "st13", qty: 0.1 }] },
  { id: "m8", name: "บัวลอยไข่หวาน", price: 45, catId: "c3", desc: "เสิร์ฟร้อน" },
  { id: "m9", name: "ชาไทยเย็น", price: 45, catId: "c4", desc: "หวานมัน สูตรต้นตำรับ", recipe: [{ stockItemId: "st14", qty: 0.05 }, { stockItemId: "st15", qty: 0.3 }] },
  { id: "m10", name: "น้ำมะนาวโซดา", price: 40, catId: "c4", desc: "สดชื่น เปรี้ยวหวาน", recipe: [{ stockItemId: "st8", qty: 0.1 }, { stockItemId: "st15", qty: 0.2 }] },
  { id: "m11", name: "อเมริกาโน่เย็น", price: 55, catId: "c4", desc: "เอสเปรสโซ่เข้มข้น", recipe: [{ stockItemId: "st15", qty: 0.2 }] },
  { id: "m12", name: "น้ำเปล่า", price: 15, catId: "c4", desc: "ขวดเย็น" },
];

const ZONE_SEED = ["โซนในร้าน", "โซนระเบียง", "ห้องส่วนตัว"];

const TABLE_SEED = [
  { id: "T1", branchId: "br1", zone: "โซนในร้าน", seats: 4, status: "available" },
  { id: "T2", branchId: "br1", zone: "โซนในร้าน", seats: 4, status: "ordering", ticket: 231, total: 340, channelName: "หน้าร้าน", guestCount: "2" },
  { id: "T3", branchId: "br1", zone: "โซนในร้าน", seats: 2, status: "sentToKitchen", ticket: 228, total: 210, channelName: "หน้าร้าน", guestCount: "2" },
  { id: "T4", branchId: "br1", zone: "โซนในร้าน", seats: 6, status: "available" },
  { id: "T5", branchId: "br2", zone: "โซนระเบียง", seats: 2, status: "ordering", ticket: 232, total: 95, channelName: "GRAB Food", fulfillment: "ไรเดอร์" },
  { id: "T6", branchId: "br2", zone: "โซนระเบียง", seats: 4, status: "reserved" },
  { id: "T7", branchId: "br2", zone: "โซนระเบียง", seats: 4, status: "available" },
  { id: "T8", branchId: "br2", zone: "ห้องส่วนตัว", seats: 8, status: "available" },
];

const CANCEL_HISTORY_SEED = [
  { id: "cx1", branchId: "br1", billNo: "TNSKV26070003", table: "T3", item: "ต้มยำกุ้งน้ำข้น x1", reason: "ลูกค้าสั่งผิด", time: "วันนี้ 15:20", by: "พนักงาน อร" },
  { id: "cx2", branchId: "br2", billNo: null, table: "T6", item: "ทั้งบิล", reason: "ลูกค้ายกเลิกการจอง", time: "เมื่อวาน 19:05", by: "พนักงาน มด" },
];

const MEMBER_SEED = [
  { id: "MB001", name: "สมชาย ใจดี", phone: "081-234-5678", email: "somchai.jaidee@email.com", birthday: "1990-07-16", tier: "Gold", points: 1280, joined: "2024-02-10", nationalId: "1100801234561", address: "45/12 ถนนลาดพร้าว แขวงจันทรเกษม เขตจตุจักร กรุงเทพฯ 10900", lineUserId: "U4af9c8e2b1234567890abcdef123456", taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" } },
  { id: "MB002", name: "วรรณา สุขสันต์", phone: "089-111-2222", email: "", birthday: "1995-11-03", tier: "Silver", points: 340, joined: "2024-08-01", nationalId: "", address: "", lineUserId: "", taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" } },
  { id: "MB003", name: "ธนกร พงษ์เจริญ", phone: "062-555-9090", email: "thanakorn.p@email.com", birthday: "1988-03-22", tier: "Platinum", points: 5120, joined: "2023-05-19", nationalId: "", address: "", lineUserId: "", taxInvoiceInfo: { name: "บริษัท พงษ์เจริญ คอนซัลติ้ง จำกัด", address: "99/9 ถนนพระราม 9 แขวงห้วยขวาง เขตห้วยขวาง กรุงเทพฯ 10310", taxId: "0105566001234", branch: "สำนักงานใหญ่" } },
  { id: "MB004", name: "อรุณี แสงทอง", phone: "095-777-3344", email: "", birthday: "1999-07-30", tier: "Silver", points: 120, joined: "2025-01-22", nationalId: "", address: "", lineUserId: "", taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" } },
];

const TIER_SEED = [
  {
    id: "t1", name: "Silver", minPoints: 0, color: "stone",
    birthdayDiscount: { enabled: true, percent: 5, categoryIds: [] },
    pointsMultiplier: { enabled: false, multiplier: 1 },
    otherPerks: [],
  },
  {
    id: "t2", name: "Gold", minPoints: 1000, color: "amber",
    birthdayDiscount: { enabled: true, percent: 10, categoryIds: [] },
    pointsMultiplier: { enabled: true, multiplier: 1.2 },
    otherPerks: ["จองโต๊ะล่วงหน้าพิเศษ"],
  },
  {
    id: "t3", name: "Platinum", minPoints: 5000, color: "purple",
    birthdayDiscount: { enabled: true, percent: 15, categoryIds: [] },
    pointsMultiplier: { enabled: true, multiplier: 1.5 },
    otherPerks: ["ที่จอดรถ VIP", "ของขวัญประจำปี"],
  },
];

const REWARD_SEED = [
  { id: "r1", type: "food", name: "ข้าวเหนียวมะม่วง ฟรี 1 ที่", startDate: "2026-07-01", endDate: "2026-07-31", quota: 20, usedCount: 0, points: 150, limitPerMember: 1, limitPerBill: 1, redemptionsByMember: {}, food: { itemId: "m7" } },
  { id: "r2", type: "discount", name: "ส่วนลด 50 บาท", startDate: "2026-07-01", endDate: "2026-08-31", quota: "", usedCount: 0, points: 200, limitPerMember: "", limitPerBill: 1, redemptionsByMember: {}, discount: { mode: "amount", value: 50 } },
  { id: "r3", type: "food", name: "เครื่องดื่มฟรี 1 แก้ว", startDate: "2026-07-01", endDate: "2026-07-31", quota: 35, usedCount: 0, points: 100, limitPerMember: 2, limitPerBill: "", redemptionsByMember: {}, food: { itemId: "m9" } },
  { id: "r4", type: "discount", name: "ส่วนลด 10%", startDate: "2026-07-01", endDate: "2026-08-31", quota: "", usedCount: 0, points: 400, limitPerMember: "", limitPerBill: 1, redemptionsByMember: {}, discount: { mode: "percent", value: 10 } },
];

const HISTORY_SEED = [
  { id: "h1", branchId: "br1", member: "สมชาย ใจดี", date: "2026-07-14", action: "รับประทานอาหาร", amount: 480, pointChange: "+48" },
  { id: "h2", branchId: "br2", member: "วรรณา สุขสันต์", date: "2026-07-13", action: "แลกของรางวัล: เครื่องดื่มฟรี", amount: 0, pointChange: "-100" },
  { id: "h3", branchId: "br1", member: "ธนกร พงษ์เจริญ", date: "2026-07-12", action: "รับประทานอาหาร", amount: 1250, pointChange: "+125" },
  { id: "h4", branchId: "br2", member: "อรุณี แสงทอง", date: "2026-07-10", action: "รับประทานอาหาร", amount: 260, pointChange: "+26" },
  // Today's transactions for the currently-open sales shift demo.
  { id: "h5", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "22:45", action: "รับประทานอาหาร · โต๊ะ T1", amount: 420, financeAccountId: "fa4", pointChange: "-" },
  { id: "h6", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "22:50", action: "รับประทานอาหาร · โต๊ะ T2", amount: 380, financeAccountId: "fa4", pointChange: "-" },
  { id: "h7", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:00", action: "รับประทานอาหาร · โต๊ะ T3", amount: 450, financeAccountId: "fa4", pointChange: "-" },
  { id: "h8", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:05", action: "รับประทานอาหาร · โต๊ะ T4", amount: 336, financeAccountId: "fa4", pointChange: "-" },
  { id: "h9", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:15", action: "รับประทานอาหาร · โต๊ะ T5", amount: 410, financeAccountId: "fa4", pointChange: "-" },
  { id: "h10", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:20", action: "รับประทานอาหาร · โต๊ะ T6", amount: 420, financeAccountId: "fa4", pointChange: "-" },
  { id: "h11", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "22:55", action: "รับประทานอาหาร · โต๊ะ T7", amount: 450, financeAccountId: "fa5", pointChange: "-" },
  { id: "h12", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:02", action: "รับประทานอาหาร · โต๊ะ T8", amount: 380, financeAccountId: "fa5", pointChange: "-" },
  { id: "h13", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:10", action: "รับประทานอาหาร · โต๊ะ T1", amount: 300, financeAccountId: "fa5", pointChange: "-" },
  { id: "h14", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:18", action: "รับประทานอาหาร · โต๊ะ T2", amount: 371, financeAccountId: "fa5", pointChange: "-" },
  { id: "h15", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "22:48", action: "รับประทานอาหาร · โต๊ะ T3", amount: 200, financeAccountId: "fa6", pointChange: "-" },
  { id: "h16", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "22:58", action: "รับประทานอาหาร · โต๊ะ T4", amount: 180, financeAccountId: "fa6", pointChange: "-" },
  { id: "h17", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:06", action: "รับประทานอาหาร · โต๊ะ T5", amount: 150, financeAccountId: "fa6", pointChange: "-" },
  { id: "h18", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:12", action: "รับประทานอาหาร · โต๊ะ T6", amount: 220, financeAccountId: "fa6", pointChange: "-" },
  { id: "h19", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-18", time: "23:22", action: "รับประทานอาหาร · โต๊ะ T7", amount: 172, financeAccountId: "fa6", pointChange: "-" },
  // Today (2026-07-19) and last-month (June) sales, so the dashboard can show
  // today's total and a this-month-vs-last-month comparison.
  { id: "h20", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "11:45", action: "รับประทานอาหาร", amount: 260, pointChange: "-", items: [{ name: "ผัดกะเพราหมูสับ", qty: 2, unitPrice: 90 }, { name: "ชาไทยเย็น", qty: 2, unitPrice: 40 }] },
  { id: "h21", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "12:10", action: "รับประทานอาหาร", amount: 190, pointChange: "-", items: [{ name: "ข้าวผัดปู", qty: 1, unitPrice: 150 }, { name: "น้ำมะนาวโซดา", qty: 1, unitPrice: 40 }] },
  { id: "h22", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "12:35", action: "รับประทานอาหาร", amount: 340, pointChange: "-", items: [{ name: "ผัดกะเพราหมูสับ", qty: 2, unitPrice: 90 }, { name: "ข้าวเหนียวมะม่วง", qty: 1, unitPrice: 120 }, { name: "ชาไทยเย็น", qty: 1, unitPrice: 40 }] },
  { id: "h23", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "18:20", action: "รับประทานอาหาร", amount: 420, pointChange: "-", items: [{ name: "ต้มยำกุ้งน้ำข้น", qty: 1, unitPrice: 220 }, { name: "ปีกไก่ทอดน้ำปลา", qty: 1, unitPrice: 100 }, { name: "อเมริกาโน่เย็น", qty: 2, unitPrice: 50 }] },
  { id: "h24", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "19:05", action: "รับประทานอาหาร", amount: 275, pointChange: "-", items: [{ name: "ผัดกะเพราหมูสับ", qty: 1, unitPrice: 90 }, { name: "ชาไทยเย็น", qty: 2, unitPrice: 40 }, { name: "ปอเปี๊ยะทอด", qty: 1, unitPrice: 105 }] },
  { id: "h25", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-19", time: "19:40", action: "รับประทานอาหาร", amount: 165, pointChange: "-", items: [{ name: "ปอเปี๊ยะทอด", qty: 1, unitPrice: 105 }, { name: "น้ำเปล่า", qty: 3, unitPrice: 20 }] },
  { id: "h26", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-07-17", time: "18:45", action: "รับประทานอาหาร", amount: 380, pointChange: "-" },
  { id: "h27", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-07-16", time: "12:30", action: "รับประทานอาหาร", amount: 195, pointChange: "-" },
  { id: "h28", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-06-20", time: "19:10", action: "รับประทานอาหาร", amount: 260, pointChange: "-" },
  { id: "h29", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-06-15", time: "12:20", action: "รับประทานอาหาร", amount: 300, pointChange: "-" },
  { id: "h30", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-06-10", time: "18:30", action: "รับประทานอาหาร", amount: 220, pointChange: "-" },
  { id: "h31", branchId: "br2", member: "ลูกค้าทั่วไป", date: "2026-06-05", time: "19:15", action: "รับประทานอาหาร", amount: 350, pointChange: "-" },
  { id: "h32", branchId: "br1", member: "ลูกค้าทั่วไป", date: "2026-06-01", time: "12:00", action: "รับประทานอาหาร", amount: 410, pointChange: "-" },
];

/* Itemized visit log (per member) used to power the member profile analytics:
   favorite items, visit frequency, and time-of-day patterns. New visits are
   appended here automatically whenever a bill is closed for a linked member. */
const ORDER_HISTORY_SEED = [
  { id: "oh1", memberId: "MB001", date: "2026-07-14", time: "19:20", channel: "หน้าร้าน", amount: 480, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 2 }, { name: "ชาไทยเย็น", catId: "c4", qty: 2 }] },
  { id: "oh2", memberId: "MB001", date: "2026-07-07", time: "12:40", channel: "หน้าร้าน", amount: 240, items: [{ name: "ข้าวผัดปู", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh3", memberId: "MB001", date: "2026-06-29", time: "19:05", channel: "LINE MAN", amount: 320, items: [{ name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 1 }, { name: "ข้าวเหนียวมะม่วง", catId: "c3", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh4", memberId: "MB001", date: "2026-06-20", time: "18:50", channel: "หน้าร้าน", amount: 210, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 1 }, { name: "ปีกไก่ทอดน้ำปลา", catId: "c2", qty: 1 }] },
  { id: "oh5", memberId: "MB001", date: "2026-06-08", time: "13:15", channel: "หน้าร้าน", amount: 200, items: [{ name: "แกงเขียวหวานไก่", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh6", memberId: "MB002", date: "2026-07-13", time: "20:10", channel: "GRAB Food", amount: 180, items: [{ name: "ปอเปี๊ยะทอด", catId: "c2", qty: 1 }, { name: "น้ำมะนาวโซดา", catId: "c4", qty: 1 }] },
  { id: "oh7", memberId: "MB002", date: "2026-06-25", time: "19:30", channel: "GRAB Food", amount: 220, items: [{ name: "ข้าวผัดปู", catId: "c1", qty: 1 }, { name: "น้ำมะนาวโซดา", catId: "c4", qty: 1 }] },
  { id: "oh8", memberId: "MB003", date: "2026-07-12", time: "12:30", channel: "หน้าร้าน", amount: 550, items: [{ name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 2 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 2 }] },
  { id: "oh9", memberId: "MB003", date: "2026-07-01", time: "12:20", channel: "หน้าร้าน", amount: 340, items: [{ name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 1 }, { name: "ข้าวเหนียวมะม่วง", catId: "c3", qty: 1 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 1 }] },
  { id: "oh10", memberId: "MB003", date: "2026-06-15", time: "13:00", channel: "หน้าร้าน", amount: 205, items: [{ name: "แกงเขียวหวานไก่", catId: "c1", qty: 1 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 1 }] },
  { id: "oh11", memberId: "MB004", date: "2026-07-10", time: "18:15", channel: "หน้าร้าน", amount: 130, items: [{ name: "ปีกไก่ทอดน้ำปลา", catId: "c2", qty: 1 }, { name: "น้ำเปล่า", catId: "c4", qty: 1 }] },
  // Walk-in (non-member) orders, so dashboard-level "top sellers" / "peak hours" analytics reflect the whole shop, not just members.
  { id: "oh12", memberId: null, date: "2026-07-19", time: "11:45", channel: "หน้าร้าน", amount: 260, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 2 }, { name: "ชาไทยเย็น", catId: "c4", qty: 2 }] },
  { id: "oh13", memberId: null, date: "2026-07-19", time: "12:10", channel: "หน้าร้าน", amount: 190, items: [{ name: "ข้าวผัดปู", catId: "c1", qty: 1 }, { name: "น้ำมะนาวโซดา", catId: "c4", qty: 1 }] },
  { id: "oh14", memberId: null, date: "2026-07-19", time: "12:35", channel: "GRAB Food", amount: 340, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 2 }, { name: "ข้าวเหนียวมะม่วง", catId: "c3", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh15", memberId: null, date: "2026-07-19", time: "18:20", channel: "หน้าร้าน", amount: 420, items: [{ name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 1 }, { name: "ปีกไก่ทอดน้ำปลา", catId: "c2", qty: 1 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 2 }] },
  { id: "oh16", memberId: null, date: "2026-07-19", time: "19:05", channel: "LINE MAN", amount: 275, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 2 }] },
  { id: "oh17", memberId: null, date: "2026-07-19", time: "19:40", channel: "หน้าร้าน", amount: 165, items: [{ name: "ปอเปี๊ยะทอด", catId: "c2", qty: 1 }, { name: "น้ำเปล่า", catId: "c4", qty: 1 }] },
  { id: "oh18", memberId: null, date: "2026-07-18", time: "12:15", channel: "หน้าร้าน", amount: 230, items: [{ name: "แกงเขียวหวานไก่", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh19", memberId: null, date: "2026-07-18", time: "19:00", channel: "Shopee Food", amount: 310, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 2 }, { name: "น้ำมะนาวโซดา", catId: "c4", qty: 1 }] },
  { id: "oh20", memberId: null, date: "2026-07-17", time: "18:45", channel: "หน้าร้าน", amount: 380, items: [{ name: "ข้าวผัดปู", catId: "c1", qty: 1 }, { name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 2 }] },
  { id: "oh21", memberId: null, date: "2026-07-16", time: "12:30", channel: "หน้าร้าน", amount: 195, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 1 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 1 }] },
  { id: "oh22", memberId: null, date: "2026-06-20", time: "19:10", channel: "หน้าร้าน", amount: 260, items: [{ name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 2 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh23", memberId: null, date: "2026-06-15", time: "12:20", channel: "GRAB Food", amount: 300, items: [{ name: "ข้าวผัดปู", catId: "c1", qty: 1 }, { name: "ข้าวเหนียวมะม่วง", catId: "c3", qty: 1 }, { name: "น้ำมะนาวโซดา", catId: "c4", qty: 1 }] },
  { id: "oh24", memberId: null, date: "2026-06-10", time: "18:30", channel: "หน้าร้าน", amount: 220, items: [{ name: "แกงเขียวหวานไก่", catId: "c1", qty: 1 }, { name: "ชาไทยเย็น", catId: "c4", qty: 1 }] },
  { id: "oh25", memberId: null, date: "2026-06-05", time: "19:15", channel: "LINE MAN", amount: 350, items: [{ name: "ต้มยำกุ้งน้ำข้น", catId: "c1", qty: 1 }, { name: "ผัดกะเพราหมูสับ", catId: "c1", qty: 1 }, { name: "อเมริกาโน่เย็น", catId: "c4", qty: 1 }] },
];

const PROMO_SEED = [
  {
    id: "p1", type: "minSpend", name: "ลดพิเศษยอดขั้นต่ำ", active: true, start: "2026-07-01", end: "2026-07-31",
    excludedCategoryIds: ["c4"],
    minSpend: { amount: 300, discountType: "percent", value: 10 },
  },
  {
    id: "p2", type: "bundle", name: "อิ่มฟินยกเซต!", active: true, start: "2026-07-01", end: "2026-07-31",
    excludedCategoryIds: [],
    bundle: { foodItemIds: ["m1", "m2"], drinkItemIds: ["m9"], fullPrice: 205, promoMode: "fixed", promoPrice: 169, promoPercent: 15 },
  },
  {
    id: "p3", type: "happyHour", name: "Happy Hour บ่ายแซ่บ", active: true, start: "2026-07-01", end: "2026-07-31",
    excludedCategoryIds: ["c4"],
    happyHour: { startTime: "14:00", endTime: "17:00", discountType: "percent", value: 20 },
  },
  {
    id: "p4", type: "mixMatch", name: "Mix and Match เลือกได้ตามใจ", active: true, start: "2026-07-01", end: "2026-07-31",
    excludedCategoryIds: [],
    mixMatch: { itemIds: ["m1", "m5", "m6", "m8"], chooseCount: 3, price: 199 },
  },
  {
    id: "p5", type: "points", name: "โบนัสแต้มเดือนเกิด", active: true, start: "2026-07-01", end: "2026-12-31",
    excludedCategoryIds: [],
    points: { trigger: "birthdayMonth", rewardType: "multiplier", multiplier: 2, bonusPoints: 50, thresholdAmount: 500 },
  },
];

const KITCHEN_FOOD_SEED = [
  { id: 231, branchId: "br1", table: "T2", items: [
    { name: "ผัดกะเพราหมูสับ", qty: 2, options: [], note: "" },
    { name: "เตี๋ยวหมูต้มยำ โบราณ", qty: 1, options: ["แห้ง (พร้อมน้ำซุป)", "เพิ่มเส้น", "หมูสับ (บะช่อ)"], note: "ไม่ใส่ผัก ไม่เผ็ด" },
  ], status: "cooking", time: "12 นาทีที่แล้ว" },
  { id: 233, branchId: "br1", table: "T4", items: [{ name: "ต้มยำกุ้งน้ำข้น", qty: 1, options: [], note: "" }], status: "queued", time: "2 นาทีที่แล้ว" },
  { id: 227, branchId: "br2", table: "T8", items: [
    { name: "แกงเขียวหวานไก่", qty: 3, options: [], note: "" },
    { name: "ปีกไก่ทอดน้ำปลา", qty: 2, options: [], note: "" },
  ], status: "done", time: "20 นาทีที่แล้ว" },
];

const KITCHEN_DRINK_SEED = [
  { id: 232, branchId: "br2", table: "T5", items: [
    { name: "ชาไทยเย็น", qty: 2, options: ["หวานน้อย"], note: "" },
    { name: "น้ำมะนาวโซดา", qty: 1, options: [], note: "" },
  ], status: "cooking", time: "4 นาทีที่แล้ว" },
  { id: 234, branchId: "br1", table: "T1", items: [{ name: "อเมริกาโน่เย็น", qty: 1, options: [], note: "" }], status: "queued", time: "1 นาทีที่แล้ว" },
];

const WEEKDAYS = ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส"];

const STORE_INFO_SEED = {
  name: "เดอะนัวล์",
  tagline: "The Nur — ตำ ยำ แซ่บ",
  phone: "022244545",
  companyName: "บริษัท เดอะนัวล์ จำกัด",
  officeType: "สำนักงานใหญ่",
  taxId: "0-1055-56789-01-2",
  address: "123/45 ถนนสุขุมวิท แขวงคลองตัน เขตคลองเตย กรุงเทพฯ 10110",
  openTime: "10:00",
  closeTime: "22:00",
  logoDataUrl: null, // null = use default LOGO_DATA_URI
  contactChannels: [
    { id: "cc1", type: "Facebook", value: "THE NUR TUM YUM SAP" },
  ],
  lineOaId: "",
  lineQrDataUrl: null,
  lineQrShowOnReceipt: true,
  lineQrOnPlainReceipt: true,
  lineQrOnFullTaxInvoice: true,
};

const OWNER_PROFILE_SEED = {
  name: "กฤตธนา ช.",
  phone: "081-999-8888",
  email: "owner@thenuar.com",
  pin: "000000",
  owners: [], // additional owners: [{ id, name, phone, email, pin }]
};

const SLIP_SETTINGS_SEED = {
  receipt: {
    fullTaxInvoice: false,
    headerText: "เดอะนัวล์ — ตำ ยำ แซ่บ",
    footerText: "ขอบคุณที่ใช้บริการ เดอะนัวล์",
    posNumber: "POS-001",
    posNumberEnabled: false,
    taxPayerNumber: "",
    billPrefixStore: "TN",
    billStartStore: 1,
    billPrefixOnline: "TNO",
    billStartOnline: 1,
  },
  orderQr: { showTableName: true, qrSize: "large", headline: "สแกนเพื่อสั่งอาหาร", message: "เลือกเมนูที่ต้องการแล้วกดยืนยัน ทางร้านจะจัดส่งถึงโต๊ะ" },
  kitchenOrder: { showPrice: false, showTime: true, fontSize: "large", groupByCategory: true },
  precheckBill: {
    headerText: "ตำ ยำ แซ่บ",
    footerText: "ขอบคุณที่ใช้บริการ เดอะนัวล์\nกรุณาชำระเงินที่แคชเชียร์",
  },
};

const CHANNEL_SEED = [
  { id: "ch1", name: "หน้าร้าน", adjustType: "none", value: 0, color: "navy", fulfillmentOptions: ["ทานที่ร้าน", "สั่งกลับบ้าน"] },
  { id: "ch2", name: "LINE MAN", adjustType: "percent", value: 15, color: "emerald", fulfillmentOptions: ["รับเอง", "ไรเดอร์"] },
  { id: "ch3", name: "GRAB Food", adjustType: "percent", value: 18, color: "green", fulfillmentOptions: ["รับเอง", "ไรเดอร์"] },
  { id: "ch4", name: "Shopee Food", adjustType: "percent", value: 12, color: "orange", fulfillmentOptions: ["รับเอง", "ไรเดอร์"] },
];

const BRANCH_SEED = [
  { id: "br1", name: "สาขาสุขุมวิท", branchCode: "SKV", color: "#2563eb", address: "123/45 ถนนสุขุมวิท กรุงเทพฯ", priceAdjust: 0, active: true },
  { id: "br2", name: "สาขาทองหล่อ", branchCode: "TL", color: "#059669", address: "88 ซอยทองหล่อ 10 กรุงเทพฯ", priceAdjust: 8, active: true },
  { id: "br3", name: "สาขาเชียงใหม่", branchCode: "CM", color: "#dc2626", address: "9 ถนนนิมมานเหมินท์ เชียงใหม่", priceAdjust: -5, active: false },
];

const PAYMENT_SETTINGS_SEED = {
  serviceCharge: { enabled: true, rate: 10 },
  vat: { enabled: true, rate: 7, mode: "included" }, // included | added
  rounding: "none", // none | toBaht | to5Baht
  enabledFinanceAccountIds: ["fa4", "fa2", "fa3", "fa5", "fa6"], // default: cash-for-receiving + both bank accounts + card + QR
};

const SOUND_SETTINGS_SEED = {
  newOrder: {
    source: "tts", // tts | file | youtube
    fileName: "",
    fileDataUrl: null,
    youtubeUrl: "",
    positionIds: null, // null = every position hears it (default); array = only these positions (+ owner, always)
  },
  callStaff: {
    source: "tts", // tts | file | youtube
    fileName: "",
    fileDataUrl: null,
    youtubeUrl: "",
    positionIds: null,
  },
};

const PRINTER_SEED = [
  {
    id: "pr1", name: "Xprinter C300H (Wi-Fi / USB)", connectionType: "Wi-Fi / USB", connected: true, branchId: "br1",
    receiptMode: "auto", // auto | duplicate2
    kitchenEnabled: true, kitchenCategoryIds: ["c1", "c2", "c3"],
    drinkEnabled: false, drinkCategoryIds: ["c4"],
  },
  { id: "pr2", name: "XPrinter XP-58C (Wi-Fi)", connectionType: "Wi-Fi", connected: true, branchId: "br2", receiptMode: "auto", kitchenEnabled: false, kitchenCategoryIds: [], drinkEnabled: false, drinkCategoryIds: [] },
  { id: "pr3", name: "Star SP700 (USB)", connectionType: "USB", connected: false, branchId: null, receiptMode: "auto", kitchenEnabled: false, kitchenCategoryIds: [], drinkEnabled: false, drinkCategoryIds: [] },
];

/* =========================================================================
   SHARED UI PRIMITIVES
   ========================================================================= */

const STATUS_STYLE = {
  available: { label: "ว่าง", bg: "bg-white", border: "border-stone-200", text: "text-stone-500", dot: "bg-stone-300", checkbox: "border-stone-400" },
  reserved: { label: "จอง", bg: "bg-sky-50", border: "border-sky-300", text: "text-sky-700", dot: "bg-sky-500", checkbox: "border-sky-400" },
  ordering: { label: "กำลังสั่ง", bg: "bg-amber-50", border: "border-amber-300", text: "text-amber-700", dot: "bg-amber-500", checkbox: "border-amber-400" },
  sentToKitchen: { label: "ส่งครัวแล้ว", bg: "bg-emerald-50", border: "border-emerald-300", text: "text-emerald-700", dot: "bg-emerald-500", checkbox: "border-emerald-400" },
};

const TIER_COLOR = {
  stone: "bg-stone-100 text-stone-700 border-stone-300",
  amber: "bg-amber-100 text-amber-800 border-amber-300",
  purple: "bg-purple-100 text-purple-800 border-purple-300",
  emerald: "bg-emerald-100 text-emerald-800 border-emerald-300",
  sky: "bg-sky-100 text-sky-800 border-sky-300",
  rose: "bg-rose-100 text-rose-800 border-rose-300",
  indigo: "bg-indigo-100 text-indigo-800 border-indigo-300",
  pink: "bg-pink-100 text-pink-800 border-pink-300",
  teal: "bg-teal-100 text-teal-800 border-teal-300",
  orange: "bg-orange-100 text-orange-800 border-orange-300",
};

const TIER_COLOR_DOT = {
  stone: "bg-stone-400", amber: "bg-amber-400", purple: "bg-purple-400", emerald: "bg-emerald-400",
  sky: "bg-sky-400", rose: "bg-rose-400", indigo: "bg-indigo-400", pink: "bg-pink-400", teal: "bg-teal-400", orange: "bg-orange-400",
};

/* =========================================================================
   DATA EXPORT (Excel / CSV) — shared across list/report pages
   ========================================================================= */

function exportToExcel(filename, sheetName, rows) {
  if (!rows || rows.length === 0) return;
  const ws = XLSX.utils.json_to_sheet(rows);
  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, sheetName.slice(0, 31));
  XLSX.writeFile(wb, `${filename}.xlsx`);
}

function exportToCSV(filename, rows) {
  if (!rows || rows.length === 0) return;
  const headers = Object.keys(rows[0]);
  const escape = v => `"${String(v == null ? "" : v).replace(/"/g, '""')}"`;
  const csvLines = [headers.map(escape).join(",")];
  rows.forEach(row => csvLines.push(headers.map(h => escape(row[h])).join(",")));
  // Leading BOM so Excel opens Thai (UTF-8) text correctly instead of mangling it.
  const blob = new Blob(["\uFEFF" + csvLines.join("\r\n")], { type: "text/csv;charset=utf-8;" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${filename}.csv`;
  document.body.appendChild(a);
  a.click();
  a.remove();
  URL.revokeObjectURL(url);
}

/* Dropdown button offering "export to Excel" / "export to CSV" for a given
   set of plain-object rows (each key becomes a column). */
function ExportButton({ data, filename, sheetName }) {
  const [open, setOpen] = useState(false);
  const disabled = !data || data.length === 0;
  return (
    <div className="relative">
      <Btn variant="ghost" disabled={disabled} onClick={() => setOpen(v => !v)}>
        <Download size={14} /> ส่งออกข้อมูล <ChevronDown size={12} />
      </Btn>
      {open && !disabled && (
        <div className="absolute right-0 top-full mt-1 bg-white border border-stone-200 rounded-lg shadow-lg z-10 w-48 overflow-hidden">
          <button onClick={() => { exportToExcel(filename, sheetName || "Sheet1", data); setOpen(false); }}
            className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2 border-b border-stone-100">
            <FileSpreadsheet size={14} className="text-emerald-600" /> Excel (.xlsx)
          </button>
          <button onClick={() => { exportToCSV(filename, data); setOpen(false); }}
            className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2">
            <FileText size={14} className="text-stone-400" /> CSV (.csv)
          </button>
        </div>
      )}
    </div>
  );
}

/* Formats an ISO "YYYY-MM-DD" date string as "DD/MM/YYYY" for display everywhere in the app. */
function fmtDate(iso) {
  if (!iso) return "-";
  const parts = String(iso).split("-");
  if (parts.length !== 3) return iso;
  const [y, m, d] = parts;
  if (!y || !m || !d) return iso;
  return `${d.padStart(2, "0")}/${m.padStart(2, "0")}/${y}`;
}

/* Formats a number as money with thousand separators and 2 decimal places. */
function fmtMoney(v) {
  const n = Number(v || 0);
  return n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

/* Generates the next sequential receipt number for this month, e.g. "TN2026070001".
   Resets the counter every calendar month and counts against records that already
   carry a receiptNumber for that same month-prefix, so numbers stay in order even
   as bills are closed throughout the day. */
/* Stock items keep one shared catalog entry (name, unit, cost, supplier) so
   recipes can reference a single stockItemId regardless of branch, but the
   actual quantity on hand is tracked per branch via item.branchStock[branchId].
   Falls back to the item's legacy top-level currentStock/minStock when no
   branch is selected or that branch hasn't been split out yet. */
function stockQtyFor(item, branchId) {
  if (branchId && item.branchStock?.[branchId]) return item.branchStock[branchId].currentStock;
  return item.currentStock;
}
function stockMinFor(item, branchId) {
  if (branchId && item.branchStock?.[branchId]) return item.branchStock[branchId].minStock;
  return item.minStock;
}
/* Adjusts one stock item's quantity for a specific branch by `delta` (use a
   negative delta to consume stock, positive to receive/restock). If that
   branch doesn't have its own split yet, it's initialized from the item's
   legacy currentStock first. Never lets quantity go below zero. */
function adjustBranchStock(setStockItems, itemId, branchId, delta) {
  setStockItems(prev => prev.map(s => {
    if (s.id !== itemId) return s;
    if (!branchId) {
      return { ...s, currentStock: Math.max(0, Math.round((s.currentStock + delta) * 1000) / 1000) };
    }
    const existing = s.branchStock?.[branchId] || { currentStock: s.currentStock, minStock: s.minStock };
    const nextQty = Math.max(0, Math.round((existing.currentStock + delta) * 1000) / 1000);
    return { ...s, branchStock: { ...s.branchStock, [branchId]: { ...existing, currentStock: nextQty } } };
  }));
}

function nextReceiptNumber(history, prefix, branchId, branches) {
  const now = new Date();
  const branchCode = branchId ? (branches?.find(b => b.id === branchId)?.branchCode || "") : "";
  const yy = String(now.getFullYear()).slice(-2);
  const monthPrefix = `${prefix || "R"}${branchCode}${yy}${String(now.getMonth() + 1).padStart(2, "0")}`;
  // Count only against receipts already carrying this exact branch's prefix, so
  // each branch keeps its own independent, non-colliding sequence.
  const seq = (history || []).filter(h => (h.receiptNumber || "").startsWith(monthPrefix) && (h.branchId || null) === (branchId || null)).length + 1;
  return `${monthPrefix}${String(seq).padStart(4, "0")}`;
}

/* Downloads the currently-rendered hidden print template (e.g. .print-receipt or
   .print-po) as a standalone .html file. This sidesteps window.print(), which can
   silently fail to open a system dialog inside a sandboxed preview — the template
   already has all its visual styling inline, so its outerHTML is a faithful,
   self-contained copy of what would have been printed. */
/* Sends a print job to the local print-agent (see print-agent/README.md),
   which forwards it as raw ESC/POS bytes directly to the thermal printer's IP
   — no printer driver, no browser print dialog. Returns true/false; callers
   decide their own fallback (window.print(), download, etc.) if it's false,
   so the app keeps working exactly as before agent support was added even
   when the agent isn't running. */
/* Mutable so the "ตั้งค่า Port" settings page can change it at runtime without
   threading a prop through every single printViaAgent() call site. */
let PRINT_AGENT_HOST = "localhost";
let PRINT_AGENT_PORT = "9200";
function setPrintAgentConnection(host, port) {
  PRINT_AGENT_HOST = host || "localhost";
  PRINT_AGENT_PORT = port || "9200";
}
async function printViaAgent(printerName, doc) {
  try {
    const res = await fetch(`http://${PRINT_AGENT_HOST}:${PRINT_AGENT_PORT}/print`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ printer: printerName, doc }),
    });
    const data = await res.json().catch(() => ({ ok: false }));
    if (!res.ok || !data.ok) throw new Error(data.error || `HTTP ${res.status}`);
    return true;
  } catch (err) {
    console.warn("[print-agent] unavailable:", err.message);
    return false;
  }
}

/* Sends a real email via SMTP through the print agent's "/send-email"
   endpoint (see the emailed brief for adding this to print-agent) — reuses
   the same host/port connection as printing since it's meant to run on the
   same local backend. Returns false (not an error) if that endpoint doesn't
   exist yet or isn't reachable, so callers can fall back to mailto:. */
async function sendEmailViaAgent(to, subject, body) {
  try {
    const res = await fetch(`http://${PRINT_AGENT_HOST}:${PRINT_AGENT_PORT}/send-email`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ to, subject, body }),
    });
    const data = await res.json().catch(() => ({ ok: false }));
    if (!res.ok || !data.ok) throw new Error(data.error || `HTTP ${res.status}`);
    return true;
  } catch (err) {
    console.warn("[print-agent] send-email unavailable:", err.message);
    return false;
  }
}

/* window.print() alone leaves the printed paper size up to whatever the
   browser/printer-driver defaults to (often A4/Letter), which is why an
   80mm thermal receipt can come out tiny-in-the-corner-of-a-big-page, cut
   off, or scaled wrong. This injects a temporary @page rule that pins the
   actual paper size for just this one print job, then removes it again —
   .print-receipt (80mm rolls) and .print-po (A4 documents) need different
   sizes, and CSS's @page can't be scoped to a class, only set globally. */
function printWithPageSize(sizeCss) {
  const style = document.createElement("style");
  style.setAttribute("data-dynamic-page-size", "true");
  style.textContent = `@page { size: ${sizeCss}; margin: 0; }`;
  document.head.appendChild(style);
  window.print();
  const cleanup = () => {
    style.remove();
    window.removeEventListener("afterprint", cleanup);
  };
  window.addEventListener("afterprint", cleanup);
  setTimeout(cleanup, 3000); // safety net for browsers that don't fire afterprint
}
function printReceiptPage() { printWithPageSize("80mm auto"); }
function printA4Page() { printWithPageSize("A4"); }

/* QR code images (order table-tents, PromptPay, etc.) are <img> tags pointing
   at an external QR-generation API, loaded over the network. window.print()
   fires synchronously and does not wait for that fetch, so printing right
   after the image is inserted into the DOM can produce a blank QR box if the
   image hasn't finished loading yet. Call this (with the same src the hidden
   print template uses, so it hits cache) and await it before printing. */
function preloadImage(src) {
  return new Promise(resolve => {
    if (!src) return resolve();
    let done = false;
    const finish = () => { if (!done) { done = true; resolve(); } };
    const img = new Image();
    img.onload = finish;
    img.onerror = finish;
    img.src = src;
    setTimeout(finish, 2500);
  });
}

/* Some pages mount more than one hidden .print-receipt/.print-po template at
   once — e.g. the payment modal keeps both the "precheck bill" and the final
   receipt template in the DOM together. The print CSS shows ANY element with
   those classes during @media print, so calling printReceiptPage()/
   printA4Page() directly there makes every template visible at once and
   prints them stacked on top of each other (garbled/overlapping text). This
   temporarily hides every OTHER template, prints just the one matching id,
   then restores everything afterward — same trick already used for kitchen
   tickets (which can have several open at once too), generalized so any
   print button can opt in by id instead of duplicating the hide/restore code. */
function printOnlyTemplate(id, sizeCss) {
  const target = document.getElementById(id);
  if (!target) { printWithPageSize(sizeCss); return; }
  const others = Array.from(document.querySelectorAll(".print-receipt, .print-po")).filter(el => el !== target);
  const prevDisplay = others.map(el => el.style.display);
  others.forEach(el => { el.style.display = "none"; });
  printWithPageSize(sizeCss);
  const restore = () => {
    others.forEach((el, i) => { el.style.display = prevDisplay[i]; });
    window.removeEventListener("afterprint", restore);
  };
  window.addEventListener("afterprint", restore);
  setTimeout(restore, 3000);
}

function buildKitchenTicketDoc(t) {
  const blocks = [
    { type: "text", value: `#${t.id} · โต๊ะ ${String(t.table || "").replace(/^T/, "")}`, align: "center", bold: true, size: "wide" },
    { type: "text", value: `${t.kitchenLabel || ""}${t.time ? ` · ${t.time}` : ""}`.trim(), align: "center" },
    { type: "rule" },
  ];
  (t.items || []).forEach(it => {
    blocks.push({ type: "text", value: `${it.name} x${it.qty}`, bold: true });
    (it.options || []).forEach(opt => blocks.push({ type: "text", value: `  — ${opt}` }));
    if (it.note) blocks.push({ type: "text", value: `  หมายเหตุ: ${it.note}` });
  });
  return { charsPerLine: 32, cut: true, blocks };
}

function downloadPrintTemplate(selector, filename) {
  const el = document.querySelector(selector);
  if (!el) {
    alert("ไม่พบเอกสารสำหรับดาวน์โหลด กรุณาลองใหม่อีกครั้ง");
    return;
  }
  const html = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>${filename}</title>
<style>body{font-family:'Sarabun','Noto Sans Thai',sans-serif;padding:24px;background:#fff;} .print-receipt{width:320px;margin:0 auto;} .print-po{width:100%;max-width:850px;margin:0 auto;}</style>
</head><body>${el.outerHTML}</body></html>`;
  const blob = new Blob([html], { type: "text/html;charset=utf-8;" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  URL.revokeObjectURL(url);
}

/* Some stock items are purchased in bulk units (kg, l) but used in small amounts
   per recipe (g, ml). This maps a stock item's purchase unit to the smaller unit
   used when specifying recipe quantities, and the conversion factor between them. */
const UNIT_SUBDIVISION = {
  "กิโลกรัม": { label: "g", factor: 1000 },
  "ลิตร": { label: "มล.", factor: 1000 },
};
/* Builds a PromptPay QR payload string (EMVCo format used by Thai banks) from a
   mobile number (10 digits) or citizen/tax ID (13 digits), optionally with a
   fixed amount baked in (dynamic QR). Rendered as an image via a public QR
   image API — no external QR library needed. */
function crc16CCITT(str) {
  let crc = 0xFFFF;
  for (let i = 0; i < str.length; i++) {
    crc ^= str.charCodeAt(i) << 8;
    for (let j = 0; j < 8; j++) {
      crc = (crc & 0x8000) ? ((crc << 1) ^ 0x1021) : (crc << 1);
      crc &= 0xFFFF;
    }
  }
  return crc.toString(16).toUpperCase().padStart(4, "0");
}
function tlv(id, value) {
  return `${id}${String(value.length).padStart(2, "0")}${value}`;
}
function buildPromptPayPayload(promptPayId, amount) {
  const target = (promptPayId || "").replace(/[^0-9]/g, "");
  if (!target) return null;
  let merchantValue;
  if (target.length === 10) {
    // Mobile number: drop leading 0, prefix with country code 66, pad to 13 digits total.
    merchantValue = tlv("00", "A000000677010111") + tlv("01", "0066" + target.slice(1));
  } else if (target.length === 13) {
    // Citizen ID or corporate tax ID.
    merchantValue = tlv("00", "A000000677010111") + tlv("02", target);
  } else {
    return null;
  }
  let payload = tlv("00", "01") + tlv("01", amount ? "12" : "11") + tlv("29", merchantValue) + tlv("53", "764");
  if (amount) payload += tlv("54", Number(amount).toFixed(2));
  payload += tlv("58", "TH") + "6304";
  return payload + crc16CCITT(payload);
}
function promptPayQrImageUrl(promptPayId, amount, size = 200) {
  const payload = buildPromptPayPayload(promptPayId, amount);
  if (!payload) return null;
  return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(payload)}`;
}
function qrImageUrl(data, size = 200) {
  if (!data) return null;
  return `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(data)}`;
}

function getRecipeUnitInfo(stockItem) {
  if (!stockItem) return { label: "", costPerRecipeUnit: 0 };
  const sub = UNIT_SUBDIVISION[stockItem.unit];
  if (sub) return { label: sub.label, costPerRecipeUnit: stockItem.costPerUnit / sub.factor };
  return { label: stockItem.unit, costPerRecipeUnit: stockItem.costPerUnit };
}

/* Extracts a YouTube video ID from common URL formats (watch, youtu.be, embed). */
/* Speaks the new-order notification using a cheerful-sounding female voice when one is available. */
function speakOrderAlert(text = "Order เข้าแล้ว") {
  if (!window.speechSynthesis) return;
  const utter = new SpeechSynthesisUtterance(text);
  utter.lang = "th-TH";
  utter.pitch = 1.35; // higher pitch reads as brighter / more cheerful
  utter.rate = 1.05;

  function pickVoice() {
    const voices = window.speechSynthesis.getVoices();
    if (!voices.length) return null;
    const thaiVoices = voices.filter(v => v.lang && v.lang.toLowerCase().startsWith("th"));
    const pool = thaiVoices.length ? thaiVoices : voices;
    const femaleNamePattern = /female|women|kanya|narisa|premwadee|athiwara|woman/i;
    const maleNamePattern = /male|man\b/i;
    const female = pool.find(v => femaleNamePattern.test(v.name) && !maleNamePattern.test(v.name));
    return female || pool[0];
  }

  const voice = pickVoice();
  if (voice) {
    utter.voice = voice;
  } else if (window.speechSynthesis.getVoices().length === 0) {
    // Voices list loads asynchronously on first use in some browsers — try again once ready.
    window.speechSynthesis.onvoiceschanged = () => {
      const v = pickVoice();
      if (v) utter.voice = v;
      window.speechSynthesis.speak(utter);
    };
    return;
  }
  window.speechSynthesis.speak(utter);
}

function getYouTubeId(url) {
  if (!url) return null;
  const m = url.match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/))([\w-]{11})/);
  return m ? m[1] : null;
}

// Shared by every sound-alert event type (new kitchen order, customer calling
// staff, ...): plays whatever source the shop configured for that specific
// event — an uploaded audio file, a YouTube clip (via a hidden <iframe> the
// caller must render somewhere with the given id), or the default
// text-to-speech voice as a fallback. Pulled out of KitchenBoard so the new
// "เรียกพนักงาน" alert can reuse the exact same playback logic instead of
// duplicating it.
function playAlertSound(soundConfig, ttsText, youtubeFrameId) {
  const s = soundConfig || { source: "tts" };
  if (s.source === "file" && s.fileDataUrl) {
    new Audio(s.fileDataUrl).play().catch(() => {});
  } else if (s.source === "youtube" && getYouTubeId(s.youtubeUrl)) {
    const id = getYouTubeId(s.youtubeUrl);
    const frame = document.getElementById(youtubeFrameId);
    if (frame) frame.src = `https://www.youtube.com/embed/${id}?autoplay=1`;
  } else {
    speakOrderAlert(ttsText);
  }
}

// Whether the currently logged-in user should hear a given sound-alert event
// at all, per that event's positionIds restriction (set in "ตั้งค่า →
// ตั้งค่าเสียงแจ้งเตือน"). positionIds === null/undefined means "not
// restricted" (the default — everyone hears it, same as before this
// restriction existed). When an array is set, only staff in one of those
// positions hear it — the owner always hears every alert regardless, since
// they're not tied to any one position and should never accidentally mute
// themselves out of a customer-facing alert.
function shouldHearAlert(soundConfig, currentUser) {
  const ids = soundConfig?.positionIds;
  if (ids == null) return true;
  if (currentUser?.type === "owner") return true;
  return currentUser?.type === "staff" && ids.includes(currentUser.positionId);
}

function PageHeader({ eyebrow, title, subtitle, right }) {
  return (
    <div className="flex items-start justify-between gap-4 mb-6">
      <div>
        <div className="text-xs font-semibold tracking-widest text-amber-700 uppercase mb-1">{eyebrow}</div>
        <h1 className="text-2xl font-serif text-stone-900">{title}</h1>
        {subtitle && <p className="text-sm text-stone-500 mt-1">{subtitle}</p>}
      </div>
      {right}
    </div>
  );
}

function Btn({ children, onClick, variant = "primary", className = "", type = "button", disabled }) {
  const base = "inline-flex items-center gap-1.5 px-3.5 py-2 rounded-md text-sm font-medium transition-colors disabled:opacity-40 disabled:cursor-not-allowed";
  const variants = {
    primary: "bg-stone-900 text-stone-50 hover:bg-amber-700",
    ghost: "bg-transparent text-stone-600 hover:bg-stone-100 border border-stone-300",
    danger: "bg-transparent text-rose-600 hover:bg-rose-50 border border-rose-200",
    subtle: "bg-amber-50 text-amber-800 hover:bg-amber-100 border border-amber-200",
  };
  return (
    <button type={type} disabled={disabled} onClick={onClick} className={`${base} ${variants[variant]} ${className}`}>
      {children}
    </button>
  );
}

function Card({ children, className = "" }) {
  return <div className={`bg-white border border-stone-200 rounded-lg ${className}`}>{children}</div>;
}

function Field({ label, children }) {
  return (
    <label className="block">
      <span className="block text-xs font-medium text-stone-500 mb-1">{label}</span>
      {children}
    </label>
  );
}

const inputCls = "w-full rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400";

/* =========================================================================
   NAVIGATION CONFIG
   ========================================================================= */

const NAV = [
  { group: "ภาพรวม", groupIcon: LayoutDashboard, items: [
    { key: "dashboard", label: "แดชบอร์ด", icon: LayoutDashboard },
    { key: "profitLoss", label: "รายงานกำไร-ขาดทุน", icon: TrendingUp },
    { key: "staffSales", label: "แยกตามพนักงาน", icon: Users },
    { key: "vatReport", label: "ภาษีมูลค่าเพิ่ม (ภ.พ.30)", icon: ReceiptText },
    { key: "foodCost", label: "รายงานต้นทุนเมนู", icon: Percent },
  ]},
  { group: "หน้าร้าน", groupIcon: ShoppingCart, items: [
    { key: "pos", label: "POS Order", icon: ShoppingCart },
    { key: "openTables", label: "โต๊ะที่เปิดอยู่", icon: LayoutGrid },
    { key: "reservations", label: "จองโต๊ะล่วงหน้า", icon: CalendarDays },
    { key: "salesShifts", label: "รอบการขาย", icon: Clock },
    { key: "receiptHistory", label: "ประวัติใบเสร็จ", icon: ReceiptText },
    { key: "cancelHistoryPage", label: "ประวัติการยกเลิก", icon: Ban },
    { key: "tableSettings", label: "ตั้งค่าพื้นที่โต๊ะ", icon: Settings2 },
  ]},
  { group: "ครัว", groupIcon: ChefHat, items: [
    { key: "kitchenFood", label: "ครัวอาหาร", icon: ChefHat },
    { key: "kitchenDrinks", label: "ครัวเครื่องดื่ม", icon: Coffee },
    { key: "kitchenDisplaySettings", label: "ตั้งค่าจอครัว", icon: Settings2 },
  ]},
  { group: "บัตรสะสมแต้ม", groupIcon: Award, items: [
    { key: "members", label: "สมาชิกทั้งหมด", icon: Users },
    { key: "tiers", label: "จัดระดับสมาชิก", icon: Award },
    { key: "rewards", label: "แลกของรางวัล", icon: Gift },
    { key: "pointRate", label: "อัตราสะสมแต้ม", icon: Percent },
    { key: "history", label: "ประวัติการใช้บริการ", icon: History },
    { key: "lineOaSettings", label: "ตั้งค่า LINE OA", icon: MessageCircle },
  ]},
  { group: "จัดการเมนู", groupIcon: UtensilsCrossed, items: [
    { key: "addMenu", label: "เพิ่มเมนูอาหาร", icon: UtensilsCrossed },
    { key: "categories", label: "หมวดหมู่อาหาร", icon: Tag },
  ]},
  { group: "โปรโมชั่น", groupIcon: Megaphone, items: [
    { key: "promotions", label: "โปรโมชั่นทั้งหมด", icon: Megaphone },
  ]},
  { group: "พนักงาน", groupIcon: Briefcase, items: [
    { key: "staffList", label: "รายชื่อพนักงาน", icon: Users },
    { key: "attendance", label: "ลงเวลาเข้า-ออกงาน", icon: Clock },
    { key: "staffPositions", label: "กำหนดตำแหน่ง", icon: ShieldCheck },
    { key: "staffApplicants", label: "รายชื่อผู้สมัคร", icon: ClipboardList },
    { key: "staffRecruitment", label: "รับสมัครพนักงาน", icon: Briefcase },
  ]},
  { group: "ฝ่ายบุคคล", groupIcon: Timer, items: [
    { key: "workSchedule", label: "กำหนดเวลาทำงาน", icon: Timer },
    { key: "attendanceSettings", label: "ตั้งค่าการลงเวลา", icon: Settings2 },
    { key: "staffDaysOff", label: "กำหนดวันหยุด", icon: CalendarDays },
    { key: "leaveEntitlements", label: "กำหนดสิทธิ์วันลา", icon: Gift },
    { key: "attendanceReport", label: "รายงานเวลาเข้า-ออกงาน", icon: ClipboardList },
    { key: "payroll", label: "จัดทำเงินเดือน", icon: Banknote },
  ]},
  { group: "การจัดการสต๊อก", groupIcon: Package, items: [
    { key: "stockItems", label: "สินค้า", icon: Package },
    { key: "stockCategories", label: "หมวดหมู่สินค้า", icon: Tag },
    { key: "purchaseOrders", label: "ใบสั่งซื้อ", icon: ClipboardList },
    { key: "goodsReceipts", label: "ใบรับสินค้า", icon: Boxes },
    { key: "wasteLog", label: "บันทึกของเสีย", icon: AlertTriangle },
  ]},
  { group: "ค่าใช้จ่าย", groupIcon: Banknote, items: [
    { key: "expenses", label: "ค่าใช้จ่าย", icon: Banknote },
  ]},
  { group: "ตั้งค่าระบบ", groupIcon: Settings2, items: [
    { key: "storeInfo", label: "ข้อมูลร้านค้า", icon: Store },
    { key: "ownerProfile", label: "โปรไฟล์เจ้าของ", icon: ShieldCheck },
    { key: "themeSettings", label: "ธีมและการแสดงผล", icon: Palette },
    { key: "vendors", label: "สมุดรายชื่อ", icon: BookUser },
    { key: "slipDesign", label: "ออกแบบสลิป", icon: ReceiptText, children: [
      { key: "slipReceipt", label: "ใบเสร็จ" },
      { key: "slipOrderQr", label: "ใบสั่งอาหาร (QR สั่งอาหาร)" },
      { key: "slipKitchenOrder", label: "ใบออเดอร์ (สำหรับครัว)" },
      { key: "slipPrecheckBill", label: "ใบสรุปยอด" },
    ]},
    { key: "salesChannels", label: "ช่องทางการขาย", icon: Truck },
    { key: "emailReceiptSettings", label: "ตั้งค่าส่งใบเสร็จ", icon: Mail },
    { key: "financeAccounts", label: "ช่องทางการเงิน", icon: Banknote },
    { key: "branches", label: "สาขา", icon: Building2 },
    { key: "paymentSettings", label: "การชำระเงิน", icon: CreditCard },
    { key: "printerSettings", label: "ตั้งค่าเครื่องพิมพ์", icon: Printer },
    { key: "printAgentPort", label: "ตั้งค่า Port", icon: Wifi },
    { key: "soundSettings", label: "ตั้งค่าเสียงแจ้งเตือน", icon: Volume2 },
  ]},
  { group: "Log", groupIcon: History, items: [
    { key: "activityLog", label: "All Activity", icon: History },
    { key: "loginLog", label: "Log Login", icon: History },
  ]},
];

const PAGE_TITLE = {
  activityLog: ["Log", "All Activity", "ประวัติการกระทำทั้งหมดในระบบ เก็บย้อนหลังสูงสุด 3 เดือน"],
  loginLog: ["Log", "Log Login", "ประวัติการเข้าสู่ระบบของพนักงานและเจ้าของร้าน"],
  dashboard: ["ภาพรวม", "แดชบอร์ด", "สรุปภาพรวมยอดขาย เมนูขายดี และผลประกอบการของร้าน"],
  profitLoss: ["ภาพรวม", "รายงานกำไร-ขาดทุน", "สรุปรายได้ ต้นทุน ค่าใช้จ่าย และกำไรสุทธิตามช่วงเวลา"],
  staffSales: ["ภาพรวม", "แยกตามพนักงาน", "สรุปยอดปิดบิลของพนักงานแต่ละคนตามช่วงเวลา"],
  vatReport: ["ภาพรวม", "ภาษีมูลค่าเพิ่ม (ภ.พ.30)", "สรุปภาษีขาย-ภาษีซื้อรายเดือน สำหรับยื่นแบบต่อกรมสรรพากร"],
  foodCost: ["ภาพรวม", "รายงานต้นทุนเมนู", "เทียบราคาขายกับต้นทุนวัตถุดิบของแต่ละเมนู (Food Cost %)"],
  pos: ["หน้าร้าน", "POS Order", "เปิดออเดอร์ใหม่และส่งเข้าครัวได้ทันที"],
  openTables: ["หน้าร้าน", "โต๊ะที่เปิดอยู่", "ภาพรวมสถานะโต๊ะทั้งหมดแบบเรียลไทม์"],
  reservations: ["หน้าร้าน", "จองโต๊ะล่วงหน้า", "ปฏิทินการจองของลูกค้า"],
  salesShifts: ["หน้าร้าน", "รอบการขาย", "เปิด-ปิดรอบการขาย และตรวจนับเงินสดประจำกะ"],
  receiptHistory: ["หน้าร้าน", "ประวัติใบเสร็จ", "ดูและพิมพ์ใบเสร็จย้อนหลังของทุกบิลที่ปิดแล้ว"],
  cancelHistoryPage: ["หน้าร้าน", "ประวัติการยกเลิก", "ดูประวัติการยกเลิก/void รายการอาหารและการจองโต๊ะ"],
  tableSettings: ["ตั้งค่า", "ตั้งค่าพื้นที่โต๊ะ", "จัดการโซนและผังโต๊ะภายในร้าน"],
  kitchenFood: ["ครัว", "ครัวอาหาร", "คิวออเดอร์อาหารที่ต้องปรุง"],
  kitchenDrinks: ["ครัว", "ครัวเครื่องดื่ม", "คิวออเดอร์เครื่องดื่มที่ต้องเตรียม"],
  kitchenDisplaySettings: ["ครัว", "ตั้งค่าจอครัว", "เลือกว่าแต่ละหมวดหมู่อาหารจะส่งออเดอร์ไปจอครัวใด"],
  members: ["บัตรสะสมแต้ม", "สมาชิกทั้งหมด", "รายชื่อสมาชิกและแต้มสะสมปัจจุบัน"],
  tiers: ["บัตรสะสมแต้ม", "จัดระดับสมาชิก", "กำหนดเงื่อนไขและสิทธิประโยชน์แต่ละระดับ"],
  pointRate: ["บัตรสะสมแต้ม", "อัตราสะสมแต้ม", "กำหนดอัตราแลกเปลี่ยนบาทเป็นแต้ม"],
  rewards: ["บัตรสะสมแต้ม", "แลกของรางวัล", "คลังของรางวัลให้สมาชิกแลกด้วยแต้ม"],
  history: ["บัตรสะสมแต้ม", "ประวัติการใช้บริการ", "ประวัติการมาใช้บริการและการแลกแต้ม"],
  lineOaSettings: ["บัตรสะสมแต้ม", "ตั้งค่า LINE OA", "ใส่ข้อมูล Token/LIFF เพื่อให้สมาชิกเชื่อมต่อผ่าน LINE ได้"],
  addMenu: ["จัดการเมนู", "เพิ่มเมนูอาหาร", "เพิ่มและแก้ไขรายการอาหาร/เครื่องดื่ม"],
  categories: ["จัดการเมนู", "หมวดหมู่อาหาร", "จัดกลุ่มหมวดหมู่เมนูของร้าน"],
  promotions: ["โปรโมชั่น", "โปรโมชั่นทั้งหมด", "จัดการแคมเปญส่วนลดและโปรโมชั่น"],
  storeInfo: ["ตั้งค่าระบบ", "ข้อมูลร้านค้า", "ข้อมูลพื้นฐานของร้านที่แสดงบนสลิปและเอกสารต่าง ๆ"],
  ownerProfile: ["ตั้งค่าระบบ", "โปรไฟล์เจ้าของ", "ข้อมูลเจ้าของร้านและ PIN สำหรับอนุมัติรายการสำคัญ"],
  themeSettings: ["ตั้งค่าระบบ", "ธีมและการแสดงผล", "ปรับโหมดมืด/สว่าง และสีธีมของระบบเอง"],
  slipReceipt: ["ตั้งค่าระบบ · ออกแบบสลิป", "ใบเสร็จ", "กำหนดรูปแบบใบเสร็จรับเงินที่พิมพ์ให้ลูกค้า"],
  slipOrderQr: ["ตั้งค่าระบบ · ออกแบบสลิป", "ใบสั่งอาหาร (QR สั่งอาหาร)", "ออกแบบป้าย QR Code สำหรับให้ลูกค้าสแกนสั่งอาหารเอง"],
  slipKitchenOrder: ["ตั้งค่าระบบ · ออกแบบสลิป", "ใบออเดอร์ (สำหรับครัว)", "กำหนดรูปแบบใบออเดอร์ที่พิมพ์ส่งเข้าครัว"],
  slipPrecheckBill: ["ตั้งค่าระบบ · ออกแบบสลิป", "ใบสรุปยอด", "กำหนดรูปแบบใบแจ้งยอดที่พิมพ์ให้ลูกค้าชำระเงิน"],
  salesChannels: ["ตั้งค่าระบบ", "ช่องทางการขาย", "กำหนดส่วนต่างราคาของแต่ละช่องทางการขาย"],
  emailReceiptSettings: ["ตั้งค่าระบบ", "ตั้งค่าส่งใบเสร็จ", "กำหนดหัวข้อและรายละเอียดอีเมลที่ส่งใบเสร็จให้ลูกค้า"],
  financeAccounts: ["ตั้งค่าระบบ", "ช่องทางการเงิน", "จัดการบัญชีเงินสด บัญชีธนาคาร และช่องทางรับ-จ่ายเงินอื่นๆ"],
  branches: ["ตั้งค่าระบบ", "สาขา", "กำหนดส่วนต่างราคาและข้อมูลของแต่ละสาขา"],
  paymentSettings: ["ตั้งค่าระบบ", "การชำระเงิน", "ตั้งค่าค่าบริการ ภาษี และการปัดเศษยอดชำระ"],
  printerSettings: ["ตั้งค่าระบบ", "ตั้งค่าเครื่องพิมพ์", "ค้นหา เชื่อมต่อ และตั้งค่าเครื่องพิมพ์ใบเสร็จ/ใบออเดอร์"],
  printAgentPort: ["ตั้งค่าระบบ", "ตั้งค่า Port", "กำหนด host/port ที่ใช้เชื่อมต่อ print agent สำหรับพิมพ์ตรงไปเครื่องพิมพ์"],
  soundSettings: ["ตั้งค่าระบบ", "ตั้งค่าเสียงแจ้งเตือน", "กำหนดเสียงแจ้งเตือนเมื่อมีออเดอร์ใหม่เข้าครัว หรือลูกค้าเรียกพนักงาน"],
  staffList: ["พนักงาน", "รายชื่อพนักงาน", "รายชื่อพนักงานทั้งหมดและตำแหน่งที่รับผิดชอบ"],
  attendance: ["พนักงาน", "ลงเวลาเข้า-ออกงาน", "ลงเวลาด้วย PIN (ตรวจสอบ GPS ได้ถ้าเปิดใช้งาน)"],
  attendanceReport: ["ฝ่ายบุคคล", "รายงานเวลาเข้า-ออกงาน", "ดูและแก้ไขประวัติการลงเวลาของพนักงาน"],
  payroll: ["ฝ่ายบุคคล", "จัดทำเงินเดือน", "คำนวณเงินเดือนจากอัตราค่าตอบแทนของพนักงานแต่ละคน"],
  workSchedule: ["ฝ่ายบุคคล", "กำหนดเวลาทำงาน", "ตั้งเวลาเข้า-ออกงานและกำหนดให้พนักงานแต่ละคน"],
  attendanceSettings: ["ฝ่ายบุคคล", "ตั้งค่าการลงเวลา", "กำหนดว่าต้องถ่ายรูปตอนลงเวลาเข้า-ออกงานหรือไม่"],
  staffDaysOff: ["ฝ่ายบุคคล", "กำหนดวันหยุด", "กำหนดวันหยุดประจำสัปดาห์และวันลาพิเศษของพนักงานแต่ละคน"],
  leaveEntitlements: ["ฝ่ายบุคคล", "กำหนดสิทธิ์วันลา", "กำหนดสิทธิ์วันลาป่วย ลากิจ ลาพักร้อน ให้พนักงานแต่ละคน"],
  staffPositions: ["พนักงาน", "กำหนดตำแหน่ง", "กำหนดตำแหน่งงานและสิทธิ์เข้าถึงเมนูต่างๆ"],
  staffApplicants: ["พนักงาน", "รายชื่อผู้สมัคร", "รายชื่อผู้สมัครงานทั้งหมดที่ส่งใบสมัครเข้ามา"],
  staffRecruitment: ["พนักงาน", "รับสมัครพนักงาน", "เปิดรับสมัครตำแหน่งงานและแชร์ลิงก์ใบสมัคร"],
  stockItems: ["การจัดการสต๊อก", "สินค้า", "รายการสินค้าและวัตถุดิบคงคลังทั้งหมด"],
  stockCategories: ["การจัดการสต๊อก", "หมวดหมู่สินค้า", "จัดกลุ่มหมวดหมู่สินค้าและวัตถุดิบ"],
  vendors: ["ตั้งค่าระบบ", "สมุดรายชื่อ", "รายชื่อผู้ขาย/ผู้จำหน่ายวัตถุดิบและข้อมูลติดต่อ"],
  purchaseOrders: ["การจัดการสต๊อก", "ใบสั่งซื้อ", "สร้างและจัดการใบสั่งซื้อวัตถุดิบ"],
  goodsReceipts: ["การจัดการสต๊อก", "ใบรับสินค้า", "รับสินค้าเข้าคลังตามใบสั่งซื้อ"],
  wasteLog: ["การจัดการสต๊อก", "บันทึกของเสีย", "บันทึกวัตถุดิบที่เสียหาย ทำหก หรือหมดอายุ แยกจากยอดขายปกติ"],
  expenses: ["ค่าใช้จ่าย", "ค่าใช้จ่าย", "บันทึกเงินเดือนและค่าใช้จ่ายต่างๆ ของร้าน"],
};

/* Flattened list of every menu item (incl. children) for the permissions picker */
const PERMISSION_OPTIONS = NAV.flatMap(group =>
  group.items.flatMap(item =>
    item.children
      ? item.children.map(child => ({ key: child.key, label: `${item.label} · ${child.label}`, group: group.group }))
      : [{ key: item.key, label: item.label, group: group.group }]
  )
);

/* Actions elsewhere in the app that require a manager/owner PIN before they run.
   Each position can be granted permission to approve some or all of these. */
const PIN_DELETE_ACTIONS = [
  { key: "posVoidApproval", label: "ยกเลิก/ลบรายการอาหารที่ส่งครัวแล้ว (POS Order)" },
  { key: "staffDaysOffDelete", label: "ลบวันหยุดพนักงาน" },
  { key: "menuItemDelete", label: "ลบเมนูอาหาร" },
  { key: "applicantDelete", label: "ลบรายชื่อผู้สมัครงาน" },
  { key: "kitchenClearDone", label: "เคลียร์รายการในหน้าจอครัว" },
];

const POSITION_SEED = [
  { id: "pos1", name: "ผู้จัดการร้าน", permissions: PERMISSION_OPTIONS.map(p => p.key), pinPermissions: PIN_DELETE_ACTIONS.map(a => a.key) },
  { id: "pos2", name: "พนักงานเสิร์ฟ", permissions: ["pos", "openTables", "reservations", "members", "rewards"], pinPermissions: [] },
  { id: "pos3", name: "พนักงานครัว", permissions: ["kitchenFood", "kitchenDrinks"], pinPermissions: [] },
];

function emptyCompensation() {
  return {
    baseSalary: "", positionAllowance: "", travelAllowance: "", fuelAllowance: "",
    commission: { minSales: "", type: "percent", value: "", excludedCategoryIds: [] },
    otMultiplier: "1.5",
    diligenceBonus: { amount: "", conditions: [] },
    annualBonusMonths: "",
    socialSecurityEnabled: false, socialSecurityAmount: "", // blank amount = use the standard 5% (capped at 750/month) calculation
  };
}

const WORK_SCHEDULE_SEED = [
  { id: "sch1", name: "กะปกติ (09:00-18:00)", startTime: "09:00", endTime: "18:00", graceMinutes: 10 },
  { id: "sch2", name: "กะบ่าย (12:00-21:00)", startTime: "12:00", endTime: "21:00", graceMinutes: 15 },
];

const LATE_ABSENT_POLICY_SEED = { lateCountForAbsent: 3 }; // N ครั้งมาสาย = ขาดงาน 1 วัน

const STAFF_SEED = [
  {
    id: "st1", name: "สมชาย รักงาน", displayName: "สมชาย", branchIds: ["br1", "br2"], phone: "081-111-2222", positionId: "pos1", pin: "194720", startDate: "2023-01-10", active: true, scheduleId: "sch1", leaveQuotas: {},
    compensation: { baseSalary: "18000", positionAllowance: "3000", travelAllowance: "1000", fuelAllowance: "500", commission: { minSales: "50000", type: "percent", value: "2", excludedCategoryIds: ["c4"] }, otMultiplier: "1.5", diligenceBonus: { amount: "500", conditions: ["noAbsent", "noLeave", "noLate"] }, annualBonusMonths: "1", socialSecurityEnabled: true, socialSecurityAmount: "" },
    bankInfo: { bankName: "ธนาคารกสิกรไทย", accountNumber: "123-4-56789-0", accountName: "สมชาย รักงาน" },
  },
  { id: "st2", name: "มะลิ ใจดี", displayName: "มะลิ", branchIds: ["br1"], phone: "089-222-3333", positionId: "pos2", pin: "582013", startDate: "2024-03-15", active: true, scheduleId: "sch1", leaveQuotas: {}, compensation: emptyCompensation(), bankInfo: { bankName: "ธนาคารไทยพาณิชย์", accountNumber: "234-5-67890-1", accountName: "มะลิ ใจดี" } },
  { id: "st3", name: "วิชัย ตั้งใจ", displayName: "วิชัย", branchIds: ["br2"], phone: "062-333-4444", positionId: "pos3", pin: "367498", startDate: "2024-06-01", active: true, scheduleId: "sch2", leaveQuotas: {}, compensation: emptyCompensation(), bankInfo: { bankName: "", accountNumber: "", accountName: "" } },
];

/* =========================================================================
   STAFF DAYS OFF (วันหยุดพนักงาน) — leave types + seed data
   ========================================================================= */

const LEAVE_TYPE_SEED = [
  { id: "lt1", name: "ลาป่วย", defaultQuotaDays: 30 },
  { id: "lt2", name: "ลากิจ", defaultQuotaDays: 3 },
  { id: "lt3", name: "ลาพักร้อน", defaultQuotaDays: 6 },
];

const DAYS_OFF_SEED = [
  { id: "do1", date: "2026-07-20", staffId: "st1", leaveType: "lt1" },
  { id: "do2", date: "2026-07-21", staffId: "st2", leaveType: "lt2" },
  { id: "do3", date: "2026-07-21", staffId: "st3", leaveType: "lt1" },
  { id: "do4", date: "2026-07-27", staffId: "st1", leaveType: "lt3" },
  { id: "do5", date: "2026-07-27", staffId: "st2", leaveType: "lt3" },
];

/* =========================================================================
   TIME ATTENDANCE (ลงเวลาเข้า-ออกงาน) — seed data
   ========================================================================= */

const ATTENDANCE_SEED = [
  { id: "att1", staffId: "st1", date: "2026-07-17", clockIn: "08:55", clockOut: "18:10" },
  { id: "att2", staffId: "st2", date: "2026-07-17", clockIn: "09:12", clockOut: "18:02" },
  { id: "att3", staffId: "st3", date: "2026-07-17", clockIn: "08:58", clockOut: "19:05" },
  { id: "att4", staffId: "st1", date: "2026-07-18", clockIn: "08:50", clockOut: "18:05" },
  { id: "att5", staffId: "st2", date: "2026-07-18", clockIn: "09:20", clockOut: "18:00" },
  { id: "att6", staffId: "st3", date: "2026-07-18", clockIn: "09:00", clockOut: "20:30" },
  { id: "att7", staffId: "st1", date: "2026-07-19", clockIn: "08:57", clockOut: null },
];

const ATTENDANCE_SETTINGS_SEED = { requirePhoto: false, gpsEnabled: false, gpsLat: null, gpsLng: null, gpsRadiusMeters: 100 };

const JOB_SEED = [
  {
    id: "job1", title: "พนักงานเสิร์ฟ (Part-time)", active: true,
    qualifications: ["อายุ 18 ปีขึ้นไป", "บุคลิกดี ยิ้มแย้ม", "ทำงานเป็นกะได้"],
    salaryMin: "400", salaryMax: "500", salaryUnit: "บาท/วัน",
    contactChannels: [{ type: "โทรศัพท์", value: "02-224-4545" }, { type: "LINE", value: "@thenur" }],
  },
];

const APPLICANT_SEED = [
  {
    id: "app1", jobTitle: "พนักงานเสิร์ฟ (Part-time)",
    fullName: "ปรียา ขยันดี", nickname: "แนน", birthday: "2001-04-12", nationalId: "1234567890123",
    phone: "089-876-5432", email: "prenan@example.com", lineId: "@preenan",
    currentAddress: { houseNo: "88/1", village: "", moo: "", road: "สุขุมวิท", province: "กรุงเทพมหานคร", district: "เขตคลองเตย", subdistrict: "คลองเตย", zipcode: "10110" },
    houseRegAddress: { houseNo: "88/1", village: "", moo: "", road: "สุขุมวิท", province: "กรุงเทพมหานคร", district: "เขตคลองเตย", subdistrict: "คลองเตย", zipcode: "10110" },
    workHistory: [{ startDate: "2022-01-01", endDate: "2023-12-31", company: "ร้านกาแฟบ้านสวน", position: "พนักงานเสิร์ฟ", salary: "12000", description: "ดูแลลูกค้า เสิร์ฟอาหารและเครื่องดื่ม" }],
    appliedDate: "2026-07-10", status: "รอพิจารณา",
  },
];

/* =========================================================================
   STOCK MANAGEMENT — seed data
   ========================================================================= */

const STOCK_CATEGORY_SEED = [
  { id: "sc1", name: "เนื้อสัตว์และอาหารทะเล" },
  { id: "sc2", name: "ผักและผลไม้" },
  { id: "sc3", name: "เครื่องปรุงและซอส" },
  { id: "sc4", name: "ของแห้งและธัญพืช" },
  { id: "sc5", name: "เครื่องดื่มและน้ำแข็ง" },
  { id: "sc6", name: "บรรจุภัณฑ์และอื่นๆ" },
];
const STOCK_UNIT_SEED = [
  "กิโลกรัม", "กรัม", "ลิตร", "มิลลิลิตร", "ชิ้น", "ลูก", "แพ็ค", "ถุง", "ขวด", "กล่อง",
].map((name, i) => ({ id: "su" + (i + 1), name }));

const STOCK_ITEM_SEED = [
  { id: "st1", name: "หมูสับ", category: "เนื้อสัตว์และอาหารทะเล", unit: "กิโลกรัม", currentStock: 12, minStock: 5, costPerUnit: 130, supplier: "แผงหมูป้านิด ตลาดสด", branchStock: { br1: { currentStock: 12, minStock: 5 }, br2: { currentStock: 7.8, minStock: 5 } } },
  { id: "st2", name: "กุ้งแม่น้ำ", category: "เนื้อสัตว์และอาหารทะเล", unit: "กิโลกรัม", currentStock: 3, minStock: 4, costPerUnit: 420, supplier: "ร้านอาหารทะเลสมชาย", branchStock: { br1: { currentStock: 3, minStock: 4 }, br2: { currentStock: 1.95, minStock: 4 } } },
  { id: "st3", name: "ไก่สด (สับ)", category: "เนื้อสัตว์และอาหารทะเล", unit: "กิโลกรัม", currentStock: 8, minStock: 5, costPerUnit: 90, supplier: "แผงไก่เจ๊แดง", branchStock: { br1: { currentStock: 8, minStock: 5 }, br2: { currentStock: 5.2, minStock: 5 } } },
  { id: "st4", name: "ปูม้า", category: "เนื้อสัตว์และอาหารทะเล", unit: "กิโลกรัม", currentStock: 5, minStock: 3, costPerUnit: 350, supplier: "ร้านอาหารทะเลสมชาย", branchStock: { br1: { currentStock: 5, minStock: 3 }, br2: { currentStock: 3.25, minStock: 3 } } },
  { id: "st5", name: "กะเพรา", category: "ผักและผลไม้", unit: "กิโลกรัม", currentStock: 2, minStock: 2, costPerUnit: 60, supplier: "แผงผักป้าสมศรี", branchStock: { br1: { currentStock: 2, minStock: 2 }, br2: { currentStock: 1.3, minStock: 2 } } },
  { id: "st6", name: "มะม่วงน้ำดอกไม้", category: "ผักและผลไม้", unit: "กิโลกรัม", currentStock: 6, minStock: 3, costPerUnit: 55, supplier: "สวนผลไม้บางลี่", branchStock: { br1: { currentStock: 6, minStock: 3 }, br2: { currentStock: 3.9, minStock: 3 } } },
  { id: "st7", name: "พริกขี้หนู", category: "ผักและผลไม้", unit: "กิโลกรัม", currentStock: 1.5, minStock: 2, costPerUnit: 80, supplier: "แผงผักป้าสมศรี", branchStock: { br1: { currentStock: 1.5, minStock: 2 }, br2: { currentStock: 0.975, minStock: 2 } } },
  { id: "st8", name: "มะนาว", category: "ผักและผลไม้", unit: "กิโลกรัม", currentStock: 4, minStock: 2, costPerUnit: 45, supplier: "แผงผักป้าสมศรี", branchStock: { br1: { currentStock: 4, minStock: 2 }, br2: { currentStock: 2.6, minStock: 2 } } },
  { id: "st9", name: "น้ำปลา", category: "เครื่องปรุงและซอส", unit: "ขวด", currentStock: 10, minStock: 4, costPerUnit: 35, supplier: "ยี่ปั๊วรุ่งเรือง", branchStock: { br1: { currentStock: 10, minStock: 4 }, br2: { currentStock: 6.5, minStock: 4 } } },
  { id: "st10", name: "ซอสหอยนางรม", category: "เครื่องปรุงและซอส", unit: "ขวด", currentStock: 6, minStock: 3, costPerUnit: 48, supplier: "ยี่ปั๊วรุ่งเรือง", branchStock: { br1: { currentStock: 6, minStock: 3 }, br2: { currentStock: 3.9, minStock: 3 } } },
  { id: "st11", name: "น้ำมันพืช", category: "เครื่องปรุงและซอส", unit: "ลิตร", currentStock: 15, minStock: 6, costPerUnit: 55, supplier: "ยี่ปั๊วรุ่งเรือง", branchStock: { br1: { currentStock: 15, minStock: 6 }, br2: { currentStock: 9.75, minStock: 6 } } },
  { id: "st12", name: "ข้าวสารหอมมะลิ", category: "ของแห้งและธัญพืช", unit: "กิโลกรัม", currentStock: 40, minStock: 15, costPerUnit: 32, supplier: "โรงสีข้าวไทยเจริญ", branchStock: { br1: { currentStock: 40, minStock: 15 }, br2: { currentStock: 26, minStock: 15 } } },
  { id: "st13", name: "ข้าวเหนียว", category: "ของแห้งและธัญพืช", unit: "กิโลกรัม", currentStock: 8, minStock: 5, costPerUnit: 38, supplier: "โรงสีข้าวไทยเจริญ", branchStock: { br1: { currentStock: 8, minStock: 5 }, br2: { currentStock: 5.2, minStock: 5 } } },
  { id: "st14", name: "ชาไทย (ผงชง)", category: "เครื่องดื่มและน้ำแข็ง", unit: "แพ็ค", currentStock: 5, minStock: 3, costPerUnit: 180, supplier: "ร้านวัตถุดิบเครื่องดื่ม", branchStock: { br1: { currentStock: 5, minStock: 3 }, br2: { currentStock: 3.25, minStock: 3 } } },
  { id: "st15", name: "น้ำแข็งหลอด", category: "เครื่องดื่มและน้ำแข็ง", unit: "ถุง", currentStock: 20, minStock: 10, costPerUnit: 15, supplier: "โรงน้ำแข็งบางนา", branchStock: { br1: { currentStock: 20, minStock: 10 }, br2: { currentStock: 13, minStock: 10 } } },
  { id: "st16", name: "กล่องใส่อาหารเดลิเวอรี่", category: "บรรจุภัณฑ์และอื่นๆ", unit: "แพ็ค", currentStock: 3, minStock: 5, costPerUnit: 120, supplier: "ร้านบรรจุภัณฑ์สยาม", branchStock: { br1: { currentStock: 3, minStock: 5 }, br2: { currentStock: 1.95, minStock: 5 } } },
  { id: "st17", name: "ถุงร้อนใส่อาหาร", category: "บรรจุภัณฑ์และอื่นๆ", unit: "แพ็ค", currentStock: 10, minStock: 4, costPerUnit: 45, supplier: "ร้านบรรจุภัณฑ์สยาม", branchStock: { br1: { currentStock: 10, minStock: 4 }, br2: { currentStock: 6.5, minStock: 4 } } },
  { id: "st18", name: "ไข่ไก่", category: "เนื้อสัตว์และอาหารทะเล", unit: "ฟอง", currentStock: 60, minStock: 20, costPerUnit: 4.5, supplier: "ฟาร์มไข่สดชื่นใจ", branchStock: { br1: { currentStock: 60, minStock: 20 }, br2: { currentStock: 39, minStock: 20 } } },
];

/* =========================================================================
   WASTE TRACKING (บันทึกของเสีย) — reasons + seed data
   ========================================================================= */

const WASTE_REASONS = ["หมดอายุ", "เสียหาย/ชำรุด", "ทำหก/ทำตก", "ลูกค้าคืน", "อื่นๆ"];

const WASTE_LOG_SEED = [
  { id: "wl1", branchId: "br1", date: "2026-07-16", stockItemId: "st5", qty: 0.5, reason: "หมดอายุ", note: "กะเพราเหี่ยวเหลือทิ้ง" },
  { id: "wl2", branchId: "br1", date: "2026-07-17", stockItemId: "st1", qty: 0.3, reason: "ทำหก/ทำตก", note: "หมูสับตกพื้นตอนเตรียมของ" },
  { id: "wl3", branchId: "br2", date: "2026-07-18", stockItemId: "st18", qty: 4, reason: "เสียหาย/ชำรุด", note: "ไข่แตกระหว่างขนย้าย" },
];

/* =========================================================================
   VENDOR MANAGEMENT — seed data
   ========================================================================= */

const THAI_BANKS = [
  "ธนาคารกรุงเทพ", "ธนาคารกสิกรไทย", "ธนาคารกรุงไทย", "ธนาคารไทยพาณิชย์",
  "ธนาคารกรุงศรีอยุธยา", "ธนาคารทหารไทยธนชาต", "ธนาคารเกียรตินาคินภัทร",
  "ธนาคารซีไอเอ็มบีไทย", "ธนาคารยูโอบี", "ธนาคารออมสิน", "ธนาคารอาคารสงเคราะห์",
  "ธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร (ธ.ก.ส.)", "ธนาคารอิสลามแห่งประเทศไทย",
  "ธนาคารซิตี้แบงก์", "ธนาคารสแตนดาร์ดชาร์เตอร์ด (ไทย)",
];

function emptyVendorForm() {
  return {
    contactType: "corporate", isCustomer: false, isVendor: true, creditDays: "",
    location: "thailand", contactCode: "", businessName: "", taxId: "",
    officeType: "hq", address: "", zipcode: "", shippingInfo: "",
    officePhone: "", faxNumber: "", website: "",
    contactPersonName: "", email: "", mobile: "",
    bank: "", accountName: "", accountNumber: "", branchCode: "", branchName: "",
    accountType: "savings", qrPaymentImage: null,
    foreignBankInfo: false, swiftCode: "", bankAddress: "",
    attachmentName: "", note: "",
  };
}

const VENDOR_SEED = [
  {
    id: "vd1", contactType: "corporate", isCustomer: false, isVendor: true, creditDays: "30",
    location: "thailand", contactCode: "V001", businessName: "บริษัท ตลาดสดเจริญพืชผล จำกัด", taxId: "0105561000123",
    officeType: "hq", address: "88 ถ.เจริญกรุง แขวงบางรัก เขตบางรัก กรุงเทพมหานคร", zipcode: "10500", shippingInfo: "ส่งของทุกวันจันทร์-เสาร์ ก่อน 08:00 น.",
    officePhone: "02-234-5678", faxNumber: "", website: "",
    contactPersonName: "คุณสมศรี ใจดี", email: "somsri@charoenpuechpon.co.th", mobile: "081-234-5678",
    bank: "ธนาคารกสิกรไทย", accountName: "บริษัท ตลาดสดเจริญพืชผล จำกัด", accountNumber: "123-4-56789-0", branchCode: "0234", branchName: "สาขาเจริญกรุง",
    accountType: "current", qrPaymentImage: null,
    foreignBankInfo: false, swiftCode: "", bankAddress: "",
    attachmentName: "", note: "ผู้จำหน่ายผัก-ผลไม้หลักของร้าน",
  },
  {
    id: "vd2", contactType: "individual", isCustomer: false, isVendor: true, creditDays: "0",
    location: "thailand", contactCode: "V002", businessName: "", taxId: "1234567890123",
    officeType: "hq", address: "", zipcode: "", shippingInfo: "",
    officePhone: "", faxNumber: "", website: "",
    contactPersonName: "คุณสมชาย (แผงหมูป้านิด)", email: "", mobile: "089-111-2233",
    bank: "ธนาคารไทยพาณิชย์", accountName: "สมชาย มีสุข", accountNumber: "987-6-54321-0", branchCode: "", branchName: "สาขาตลาดสด",
    accountType: "savings", qrPaymentImage: null,
    foreignBankInfo: false, swiftCode: "", bankAddress: "",
    attachmentName: "", note: "จ่ายเงินสดหน้าร้านทุกครั้ง",
  },
];

/* =========================================================================
   PURCHASE ORDERS & GOODS RECEIPTS — seed data
   ========================================================================= */

function emptyPOLine() {
  return { id: "pol" + Date.now() + Math.random().toString(36).slice(2, 5), stockItemId: "", description: "", qty: "", unit: "", unitPrice: "", receivedQty: 0 };
}

function emptyPurchaseOrder() {
  return {
    id: null, poNumber: "", vendorId: "", address: "", zipcode: "", taxId: "", branchInfo: "",
    branchId: "",
    date: new Date().toISOString().slice(0, 10), creditDays: "0", purchaser: "", currency: "THB",
    reference: "", priceMode: "excl",
    lines: [emptyPOLine(), emptyPOLine(), emptyPOLine()],
    discountPercent: "0", vatEnabled: true, vatRate: 7,
    note: "", internalNote: "",
  };
}

function poDueDate(po) {
  const d = new Date(po.date);
  d.setDate(d.getDate() + (Number(po.creditDays) || 0));
  return d.toISOString().slice(0, 10);
}
function poLineTotal(line) {
  return (Number(line.qty) || 0) * (Number(line.unitPrice) || 0);
}
function poSubtotal(po) {
  return po.lines.reduce((s, l) => s + poLineTotal(l), 0);
}
function poComputeTotals(po) {
  const subtotal = poSubtotal(po);
  const discountAmt = Math.round(subtotal * (Number(po.discountPercent) || 0) / 100 * 100) / 100;
  const afterDiscount = subtotal - discountAmt;

  if (po.priceMode === "incl") {
    // Line prices already include VAT: extract the VAT portion from the total instead of adding it.
    const vatAmt = po.vatEnabled ? Math.round(afterDiscount * (po.vatRate / (100 + po.vatRate)) * 100) / 100 : 0;
    const priceExclVat = afterDiscount - vatAmt;
    const grand = afterDiscount;
    return { subtotal, discountAmt, afterDiscount, vatAmt, priceExclVat, grand };
  }

  // Line prices exclude VAT: add VAT on top of the discounted subtotal.
  const vatAmt = po.vatEnabled ? Math.round(afterDiscount * (po.vatRate / 100) * 100) / 100 : 0;
  const grand = afterDiscount + vatAmt;
  return { subtotal, discountAmt, afterDiscount, vatAmt, priceExclVat: afterDiscount, grand };
}
function poReceiveStatus(po) {
  const totalQty = po.lines.reduce((s, l) => s + (Number(l.qty) || 0), 0);
  const receivedQty = po.lines.reduce((s, l) => s + (Number(l.receivedQty) || 0), 0);
  if (totalQty === 0) return "draft";
  if (receivedQty <= 0) return "pending";
  if (receivedQty >= totalQty) return "received";
  return "partial";
}
const PO_STATUS_LABEL = { draft: "ฉบับร่าง", pending: "ยังไม่รับสินค้า", partial: "รับสินค้าบางส่วน", received: "รับครบแล้ว" };
const PO_STATUS_STYLE = {
  draft: "bg-stone-100 text-stone-500 border-stone-300",
  pending: "bg-amber-50 text-amber-700 border-amber-300",
  partial: "bg-sky-50 text-sky-700 border-sky-300",
  received: "bg-emerald-50 text-emerald-700 border-emerald-300",
};

const PURCHASE_ORDER_SEED = [
  {
    id: "po1", poNumber: "PO2026070001", vendorId: "vd2",
    address: "", zipcode: "", taxId: "", branchInfo: "",
    date: "2026-07-18", creditDays: "0", purchaser: "Kritthana Ch", currency: "THB",
    reference: "", priceMode: "excl",
    lines: [
      { id: "pol1", stockItemId: "st18", description: "ไข่ไก่", qty: 60, unit: "ฟอง", unitPrice: 4.5, receivedQty: 0 },
    ],
    discountPercent: "0", vatEnabled: true, vatRate: 7,
    note: "", internalNote: "",
  },
];

const GOODS_RECEIPT_SEED = [];

/* =========================================================================
   FINANCE ACCOUNTS (ช่องทางการเงิน) — seed data
   ========================================================================= */

const FINANCE_ACCOUNT_TYPE_LABEL = {
  pettyCash: "บัญชีเงินสดย่อย",
  bank: "บัญชีธนาคาร",
  check: "บัญชีเช็คจ่าย",
  creditCard: "บัตรเครดิตจ่าย",
  other: "ช่องทางอื่นๆ",
};
const OTHER_CHANNEL_TYPES = ["เครื่องรูดบัตรเครดิต (EDC)", "พร้อมเพย์", "QR Code ชำระเงิน", "วอลเล็ตอิเล็กทรอนิกส์"];
const BANK_ACCOUNT_TYPE_LABEL = { savings: "ออมทรัพย์", current: "กระแสรายวัน", fixed: "ฝากประจำ" };
const ACCOUNT_TYPE_ICON = { pettyCash: Banknote, bank: Building2, check: ReceiptText, creditCard: CreditCard, other: QrCode };
function financeAccountDisplayName(acc) {
  if (!acc) return "-";
  if (acc.type === "pettyCash") return acc.name;
  if (acc.type === "bank") return `${acc.bank} ${acc.accountNumber}`;
  if (acc.type === "check") return `${acc.bank} (เช็คจ่าย) ${acc.accountNumber}`;
  if (acc.type === "creditCard") return `${acc.bank} ${acc.cardName || "บัตรเครดิต"}`;
  if (acc.type === "other") return acc.channelType;
  return "-";
}
/* A customer-facing label for a finance account's payment channel — deliberately
   generic (no bank account numbers, card numbers, etc.) since this is shown on
   printed receipts and shift summaries that customers or auditors may see. */
function paymentChannelGroupLabel(acc) {
  if (!acc) return "ไม่ระบุ";
  if (acc.type === "pettyCash") return "เงินสด";
  if (acc.type === "bank") return "โอนเงินธนาคาร";
  if (acc.type === "creditCard") return "บัตรเครดิต/เดบิต";
  if (acc.type === "check") return "เช็ค";
  if (acc.type === "other") {
    if (acc.channelType?.includes("EDC")) return "บัตรเครดิต/เดบิต";
    if (acc.channelType?.includes("พร้อมเพย์") || acc.channelType?.includes("QR")) return "QR PromptPay";
    return acc.channelType || "อื่นๆ";
  }
  return "อื่นๆ";
}
/* Accounts eligible to appear as a customer-facing payment method: excludes the
   petty-cash float literally named "เงินสด" (that's spending cash, not a receipt channel). */
function payableFinanceAccounts(financeAccounts) {
  return financeAccounts.filter(a => !(a.type === "pettyCash" && a.name === "เงินสด"));
}

function emptyFinanceAccountForm(type, defaultBranchId) {
  return {
    id: null, type, status: "active",
    ourBranchId: defaultBranchId || null,
    // pettyCash
    name: "", limit: "", responsiblePerson: "", limitDetail: "",
    // bank / check
    bank: "", accountNumber: "", branch: "", accountName: "", accountType: "savings", checkDetail: "",
    // creditCard
    cardNumber: "", cardName: "", cardDetail: "",
    // other
    channelType: OTHER_CHANNEL_TYPES[0], deviceName: "", otherDetail: "", promptPayId: "",
    initialBalance: "0",
  };
}

const FINANCE_ACCOUNT_SEED = [
  {
    id: "fa1", type: "pettyCash", status: "active",
    name: "เงินสด", limit: 9067.32, responsiblePerson: "Kritthana Ch", limitDetail: "",
    initialBalance: 0, currentBalance: 0,
  },
  {
    id: "fa4", type: "pettyCash", status: "active",
    name: "เงินสดหน้าร้าน (รับชำระ)", limit: 5000, responsiblePerson: "Kritthana Ch", limitDetail: "ใช้สำหรับรับเงินสดจากลูกค้าหน้าร้าน แยกจากเงินสดย่อยที่ใช้จ่าย",
    initialBalance: 5000, currentBalance: 5000,
  },
  {
    id: "fa2", type: "bank", status: "active",
    bank: "ธนาคารไทยพาณิชย์", accountNumber: "027-2-68876-5", branch: "บางโพ", accountName: "บริษัท สยาม โฮริซอนน์ จำกัด", accountType: "savings",
    initialBalance: 50000, currentBalance: 50000,
  },
  {
    id: "fa3", type: "bank", status: "active",
    bank: "ธนาคารกสิกรไทย", accountNumber: "107-8-08359-6", branch: "บางโพ", accountName: "บจก. สยาม โฮริซอน", accountType: "savings",
    initialBalance: 30000, currentBalance: 30000,
  },
  {
    id: "fa5", type: "creditCard", status: "active",
    bank: "ธนาคารกสิกรไทย", cardName: "เครื่องรูดบัตรเครดิต/เดบิต", cardNumber: "", cardDetail: "เครื่อง EDC หน้าร้าน",
    initialBalance: 0, currentBalance: 0,
  },
  {
    id: "fa6", type: "other", status: "active",
    channelType: "พร้อมเพย์", bank: "ธนาคารไทยพาณิชย์", deviceName: "", otherDetail: "QR PromptPay หน้าร้าน",
    initialBalance: 0, currentBalance: 0,
  },
];

/* =========================================================================
   SALES SHIFTS (รอบการขาย) — seed data
   ========================================================================= */

const SALES_SHIFT_SEED = [
  {
    id: "sh1", status: "open", branchId: "br1",
    cashAccountId: "fa4",
    openedBy: "มะนาว", openedAt: "2026-07-18T22:39",
    openingCash: 2000,
    closedBy: "", closedAt: "", cashSales: "", actualCash: "", note: "",
  },
];

/* =========================================================================
   EXPENSES (ค่าใช้จ่าย) — seed data
   ========================================================================= */

const EXPENSE_CATEGORIES = [
  "เงินเดือนพนักงาน", "ค่าเช่า", "ค่าน้ำ", "ค่าไฟ", "ค่าอินเทอร์เน็ต/โทรศัพท์",
  "ค่าซ่อมบำรุง", "ค่าการตลาด/โฆษณา", "ค่าขนส่ง", "ค่าใช้จ่ายอื่นๆ",
];

const EXPENSE_SEED = [
  {
    id: "ex1", branchId: "br1", expenseNumber: "EXP2026070001",
    vendorId: "vd1", address: "", date: "2026-07-01", creditDays: "0",
    reference: "", reference2: "", priceMode: "excl",
    lines: [{ id: "exl1", description: "เงินเดือนประจำเดือนกรกฎาคม - สมชาย รักงาน", category: "เงินเดือนพนักงาน", qty: "1", unit: "เดือน", unitPrice: "22500" }],
    discountPercent: "0", vatEnabled: false, vatRate: 7,
    note: "", internalNote: "", paymentStatus: "pending", payment: null,
  },
  {
    id: "ex2", branchId: "br1", expenseNumber: "EXP2026070002",
    vendorId: "vd2", address: "", date: "2026-07-01", creditDays: "0",
    reference: "", reference2: "", priceMode: "excl",
    lines: [{ id: "exl2", description: "ค่าเช่าพื้นที่ร้านประจำเดือนกรกฎาคม", category: "ค่าเช่า", qty: "1", unit: "เดือน", unitPrice: "25000" }],
    discountPercent: "0", vatEnabled: false, vatRate: 7,
    note: "", internalNote: "", paymentStatus: "pending", payment: null,
  },
  {
    id: "ex3", branchId: "br2", expenseNumber: "EXP2026070003",
    vendorId: "", address: "", date: "2026-07-05", creditDays: "0",
    reference: "", reference2: "", priceMode: "excl",
    lines: [{ id: "exl3", description: "ค่าไฟฟ้าเดือนมิถุนายน", category: "ค่าไฟ", qty: "1", unit: "เดือน", unitPrice: "4820" }],
    discountPercent: "0", vatEnabled: false, vatRate: 7,
    note: "", internalNote: "", paymentStatus: "pending", payment: null,
  },
];

/* Thailand address reference data.
   Full list of 77 provinces; district/sub-district data is provided for a
   handful of provinces as a working sample (แขวง/ตำบล falls back to a free
   text field when no sample data exists for the selected district). */
const THAI_PROVINCES = [
  "กรุงเทพมหานคร", "กระบี่", "กาญจนบุรี", "กาฬสินธุ์", "กำแพงเพชร", "ขอนแก่น", "จันทบุรี", "ฉะเชิงเทรา",
  "ชลบุรี", "ชัยนาท", "ชัยภูมิ", "ชุมพร", "เชียงราย", "เชียงใหม่", "ตรัง", "ตราด", "ตาก", "นครนายก",
  "นครปฐม", "นครพนม", "นครราชสีมา", "นครศรีธรรมราช", "นครสวรรค์", "นนทบุรี", "นราธิวาส", "น่าน",
  "บึงกาฬ", "บุรีรัมย์", "ปทุมธานี", "ประจวบคีรีขันธ์", "ปราจีนบุรี", "ปัตตานี", "พระนครศรีอยุธยา", "พะเยา",
  "พังงา", "พัทลุง", "พิจิตร", "พิษณุโลก", "เพชรบุรี", "เพชรบูรณ์", "แพร่", "ภูเก็ต", "มหาสารคาม",
  "มุกดาหาร", "แม่ฮ่องสอน", "ยโสธร", "ยะลา", "ร้อยเอ็ด", "ระนอง", "ระยอง", "ราชบุรี", "ลพบุรี", "ลำปาง",
  "ลำพูน", "เลย", "ศรีสะเกษ", "สกลนคร", "สงขลา", "สตูล", "สมุทรปราการ", "สมุทรสงคราม", "สมุทรสาคร",
  "สระแก้ว", "สระบุรี", "สิงห์บุรี", "สุโขทัย", "สุพรรณบุรี", "สุราษฎร์ธานี", "สุรินทร์", "หนองคาย",
  "หนองบัวลำภู", "อ่างทอง", "อำนาจเจริญ", "อุดรธานี", "อุตรดิตถ์", "อุทัยธานี", "อุบลราชธานี",
];

const THAI_DISTRICTS = {
  "กรุงเทพมหานคร": ["เขตพระนคร", "เขตดุสิต", "เขตหนองจอก", "เขตบางรัก", "เขตบางเขน", "เขตบางกะปิ", "เขตปทุมวัน", "เขตป้อมปราบศัตรูพ่าย", "เขตพระโขนง", "เขตมีนบุรี", "เขตลาดกระบัง", "เขตยานนาวา", "เขตสัมพันธวงศ์", "เขตพญาไท", "เขตธนบุรี", "เขตบางกอกใหญ่", "เขตห้วยขวาง", "เขตคลองสาน", "เขตตลิ่งชัน", "เขตบางกอกน้อย", "เขตบางขุนเทียน", "เขตภาษีเจริญ", "เขตหนองแขม", "เขตราษฎร์บูรณะ", "เขตบางพลัด", "เขตดินแดง", "เขตบึงกุ่ม", "เขตสาทร", "เขตบางซื่อ", "เขตจตุจักร", "เขตบางคอแหลม", "เขตประเวศ", "เขตคลองเตย", "เขตสวนหลวง", "เขตจอมทอง", "เขตดอนเมือง", "เขตราชเทวี", "เขตลาดพร้าว", "เขตวัฒนา", "เขตบางแค", "เขตหลักสี่", "เขตสายไหม", "เขตคันนายาว", "เขตสะพานสูง", "เขตวังทองหลาง", "เขตคลองสามวา", "เขตบางนา", "เขตทวีวัฒนา", "เขตทุ่งครุ", "เขตบางบอน"],
  "กระบี่": ["อำเภอเมืองกระบี่", "อำเภอเขาพนม", "อำเภอเกาะลันตา", "อำเภอคลองท่อม", "อำเภออ่าวลึก", "อำเภอปลายพระยา", "อำเภอลำทับ", "อำเภอเหนือคลอง"],
  "กาญจนบุรี": ["อำเภอเมืองกาญจนบุรี", "อำเภอไทรโยค", "อำเภอบ่อพลอย", "อำเภอศรีสวัสดิ์", "อำเภอท่ามะกา", "อำเภอท่าม่วง", "อำเภอทองผาภูมิ", "อำเภอสังขละบุรี", "อำเภอพนมทวน", "อำเภอเลาขวัญ", "อำเภอด่านมะขามเตี้ย", "อำเภอหนองปรือ", "อำเภอห้วยกระเจา"],
  "กาฬสินธุ์": ["อำเภอเมืองกาฬสินธุ์", "อำเภอนามน", "อำเภอกมลาไสย", "อำเภอร่องคำ", "อำเภอกุฉินารายณ์", "อำเภอเขาวง", "อำเภอยางตลาด", "อำเภอห้วยเม็ก", "อำเภอสหัสขันธ์", "อำเภอคำม่วง", "อำเภอท่าคันโท", "อำเภอหนองกุงศรี", "อำเภอฆ้องชัย", "อำเภอดอนจาน", "อำเภอสมเด็จ", "อำเภอห้วยผึ้ง"],
  "กำแพงเพชร": ["อำเภอเมืองกำแพงเพชร", "อำเภอไทรงาม", "อำเภอคลองลาน", "อำเภอขาณุวรลักษบุรี", "อำเภอคลองขลุง", "อำเภอพรานกระต่าย", "อำเภอลานกระบือ", "อำเภอทรายทองวัฒนา", "อำเภอปางศิลาทอง", "อำเภอบึงสามัคคี", "อำเภอโกสัมพีนคร"],
  "ขอนแก่น": ["อำเภอเมืองขอนแก่น", "อำเภอบ้านฝาง", "อำเภอพระยืน", "อำเภอหนองเรือ", "อำเภอชุมแพ", "อำเภอสีชมพู", "อำเภอน้ำพอง", "อำเภออุบลรัตน์", "อำเภอกระนวน", "อำเภอบ้านไผ่", "อำเภอเปือยน้อย", "อำเภอพล", "อำเภอแวงใหญ่", "อำเภอแวงน้อย", "อำเภอหนองสองห้อง", "อำเภอภูเวียง", "อำเภอมัญจาคีรี", "อำเภอชนบท", "อำเภอเขาสวนกวาง", "อำเภอภูผาม่าน", "อำเภอซำสูง", "อำเภอโคกโพธิ์ไชย", "อำเภอหนองนาคำ", "อำเภอบ้านแฮด", "อำเภอโนนศิลา", "อำเภอเวียงเก่า"],
  "จันทบุรี": ["อำเภอเมืองจันทบุรี", "อำเภอขลุง", "อำเภอท่าใหม่", "อำเภอโป่งน้ำร้อน", "อำเภอมะขาม", "อำเภอแหลมสิงห์", "อำเภอสอยดาว", "อำเภอแก่งหางแมว", "อำเภอนายายอาม", "อำเภอเขาคิชฌกูฏ"],
  "ฉะเชิงเทรา": ["อำเภอเมืองฉะเชิงเทรา", "อำเภอบางคล้า", "อำเภอบางน้ำเปรี้ยว", "อำเภอบางปะกง", "อำเภอบ้านโพธิ์", "อำเภอพนมสารคาม", "อำเภอราชสาส์น", "อำเภอสนามชัยเขต", "อำเภอแปลงยาว", "อำเภอท่าตะเกียบ", "อำเภอคลองเขื่อน"],
  "ชลบุรี": ["อำเภอเมืองชลบุรี", "อำเภอบ้านบึง", "อำเภอหนองใหญ่", "อำเภอบางละมุง", "อำเภอพานทอง", "อำเภอพนัสนิคม", "อำเภอศรีราชา", "อำเภอเกาะสีชัง", "อำเภอสัตหีบ", "อำเภอบ่อทอง", "อำเภอเกาะจันทร์"],
  "ชัยนาท": ["อำเภอเมืองชัยนาท", "อำเภอมโนรมย์", "อำเภอวัดสิงห์", "อำเภอสรรพยา", "อำเภอสรรคบุรี", "อำเภอหันคา", "อำเภอหนองมะโมง", "อำเภอเนินขาม"],
  "ชัยภูมิ": ["อำเภอเมืองชัยภูมิ", "อำเภอบ้านเขว้า", "อำเภอคอนสวรรค์", "อำเภอเกษตรสมบูรณ์", "อำเภอหนองบัวแดง", "อำเภอจัตุรัส", "อำเภอบำเหน็จณรงค์", "อำเภอหนองบัวระเหว", "อำเภอเทพสถิต", "อำเภอภูเขียว", "อำเภอบ้านแท่น", "อำเภอแก้งคร้อ", "อำเภอคอนสาร", "อำเภอภักดีชุมพล", "อำเภอเนินสง่า", "อำเภอซับใหญ่"],
  "ชุมพร": ["อำเภอเมืองชุมพร", "อำเภอท่าแซะ", "อำเภอปะทิว", "อำเภอหลังสวน", "อำเภอละแม", "อำเภอพะโต๊ะ", "อำเภอสวี", "อำเภอทุ่งตะโก"],
  "เชียงราย": ["อำเภอเมืองเชียงราย", "อำเภอเวียงชัย", "อำเภอเชียงของ", "อำเภอเทิง", "อำเภอพาน", "อำเภอป่าแดด", "อำเภอแม่จัน", "อำเภอเชียงแสน", "อำเภอแม่สาย", "อำเภอแม่สรวย", "อำเภอเวียงป่าเป้า", "อำเภอพญาเม็งราย", "อำเภอเวียงแก่น", "อำเภอขุนตาล", "อำเภอแม่ฟ้าหลวง", "อำเภอแม่ลาว", "อำเภอเวียงเชียงรุ้ง", "อำเภอดอยหลวง"],
  "เชียงใหม่": ["อำเภอเมืองเชียงใหม่", "อำเภอจอมทอง", "อำเภอแม่แจ่ม", "อำเภอเชียงดาว", "อำเภอดอยสะเก็ด", "อำเภอแม่แตง", "อำเภอแม่ริม", "อำเภอสะเมิง", "อำเภอฝาง", "อำเภอแม่อาย", "อำเภอพร้าว", "อำเภอสันป่าตอง", "อำเภอสันกำแพง", "อำเภอสันทราย", "อำเภอหางดง", "อำเภอฮอด", "อำเภอดอยเต่า", "อำเภออมก๋อย", "อำเภอสารภี", "อำเภอเวียงแหง", "อำเภอไชยปราการ", "อำเภอแม่วาง", "อำเภอแม่ออน", "อำเภอดอยหล่อ", "อำเภอกัลยาณิวัฒนา"],
  "ตรัง": ["อำเภอเมืองตรัง", "อำเภอกันตัง", "อำเภอย่านตาขาว", "อำเภอปะเหลียน", "อำเภอสิเกา", "อำเภอห้วยยอด", "อำเภอวังวิเศษ", "อำเภอนาโยง", "อำเภอรัษฎา", "อำเภอหาดสำราญ"],
  "ตราด": ["อำเภอเมืองตราด", "อำเภอคลองใหญ่", "อำเภอเขาสมิง", "อำเภอบ่อไร่", "อำเภอแหลมงอบ", "อำเภอเกาะกูด", "อำเภอเกาะช้าง"],
  "ตาก": ["อำเภอเมืองตาก", "อำเภอบ้านตาก", "อำเภอสามเงา", "อำเภอแม่ระมาด", "อำเภอท่าสองยาง", "อำเภอแม่สอด", "อำเภอพบพระ", "อำเภออุ้มผาง", "อำเภอวังเจ้า"],
  "นครนายก": ["อำเภอเมืองนครนายก", "อำเภอปากพลี", "อำเภอบ้านนา", "อำเภอองครักษ์"],
  "นครปฐม": ["อำเภอเมืองนครปฐม", "อำเภอกำแพงแสน", "อำเภอนครชัยศรี", "อำเภอดอนตูม", "อำเภอบางเลน", "อำเภอสามพราน", "อำเภอพุทธมณฑล"],
  "นครพนม": ["อำเภอเมืองนครพนม", "อำเภอปลาปาก", "อำเภอท่าอุเทน", "อำเภอบ้านแพง", "อำเภอธาตุพนม", "อำเภอเรณูนคร", "อำเภอนาแก", "อำเภอศรีสงคราม", "อำเภอนาหว้า", "อำเภอโพนสวรรค์", "อำเภอนาทม", "อำเภอวังยาง"],
  "นครราชสีมา": ["อำเภอเมืองนครราชสีมา", "อำเภอครบุรี", "อำเภอเสิงสาง", "อำเภอคง", "อำเภอบ้านเหลื่อม", "อำเภอจักราช", "อำเภอโชคชัย", "อำเภอด่านขุนทด", "อำเภอโนนไทย", "อำเภอโนนสูง", "อำเภอขามสะแกแสง", "อำเภอบัวใหญ่", "อำเภอประทาย", "อำเภอปักธงชัย", "อำเภอพิมาย", "อำเภอห้วยแถลง", "อำเภอชุมพวง", "อำเภอสูงเนิน", "อำเภอขามทะเลสอ", "อำเภอสีคิ้ว", "อำเภอปากช่อง", "อำเภอหนองบุญมาก", "อำเภอแก้งสนามนาง", "อำเภอโนนแดง", "อำเภอวังน้ำเขียว", "อำเภอเทพารักษ์", "อำเภอเมืองยาง", "อำเภอพระทองคำ", "อำเภอลำทะเมนชัย", "อำเภอบัวลาย", "อำเภอสีดา", "อำเภอเฉลิมพระเกียรติ"],
  "นครศรีธรรมราช": ["อำเภอเมืองนครศรีธรรมราช", "อำเภอพรหมคีรี", "อำเภอลานสกา", "อำเภอฉวาง", "อำเภอพิปูน", "อำเภอเชียรใหญ่", "อำเภอชะอวด", "อำเภอท่าศาลา", "อำเภอทุ่งสง", "อำเภอนาบอน", "อำเภอทุ่งใหญ่", "อำเภอปากพนัง", "อำเภอร่อนพิบูลย์", "อำเภอสิชล", "อำเภอขนอม", "อำเภอหัวไทร", "อำเภอบางขัน", "อำเภอถ้ำพรรณรา", "อำเภอจุฬาภรณ์", "อำเภอพระพรหม", "อำเภอนบพิตำ", "อำเภอช้างกลาง", "อำเภอเฉลิมพระเกียรติ"],
  "นครสวรรค์": ["อำเภอเมืองนครสวรรค์", "อำเภอโกรกพระ", "อำเภอชุมแสง", "อำเภอหนองบัว", "อำเภอบรรพตพิสัย", "อำเภอเก้าเลี้ยว", "อำเภอตาคลี", "อำเภอท่าตะโก", "อำเภอไพศาลี", "อำเภอพยุหะคีรี", "อำเภอลาดยาว", "อำเภอตากฟ้า", "อำเภอแม่วงก์", "อำเภอแม่เปิน", "อำเภอชุมตาบง"],
  "นนทบุรี": ["อำเภอเมืองนนทบุรี", "อำเภอบางกรวย", "อำเภอบางใหญ่", "อำเภอบางบัวทอง", "อำเภอไทรน้อย", "อำเภอปากเกร็ด"],
  "นราธิวาส": ["อำเภอเมืองนราธิวาส", "อำเภอตากใบ", "อำเภอบาเจาะ", "อำเภอยี่งอ", "อำเภอระแงะ", "อำเภอรือเสาะ", "อำเภอศรีสาคร", "อำเภอแว้ง", "อำเภอสุคิริน", "อำเภอสุไหงโก-ลก", "อำเภอสุไหงปาดี", "อำเภอจะแนะ", "อำเภอเจาะไอร้อง"],
  "น่าน": ["อำเภอเมืองน่าน", "อำเภอแม่จริม", "อำเภอบ้านหลวง", "อำเภอนาน้อย", "อำเภอปัว", "อำเภอท่าวังผา", "อำเภอเวียงสา", "อำเภอทุ่งช้าง", "อำเภอเชียงกลาง", "อำเภอนาหมื่น", "อำเภอสันติสุข", "อำเภอบ่อเกลือ", "อำเภอสองแคว", "อำเภอภูเพียง", "อำเภอเฉลิมพระเกียรติ"],
  "บึงกาฬ": ["อำเภอเมืองบึงกาฬ", "อำเภอพรเจริญ", "อำเภอโซ่พิสัย", "อำเภอเซกา", "อำเภอปากคาด", "อำเภอบึงโขงหลง", "อำเภอศรีวิไล", "อำเภอบุ่งคล้า"],
  "บุรีรัมย์": ["อำเภอเมืองบุรีรัมย์", "อำเภอคูเมือง", "อำเภอกระสัง", "อำเภอนางรอง", "อำเภอหนองกี่", "อำเภอละหานทราย", "อำเภอประโคนชัย", "อำเภอบ้านกรวด", "อำเภอพุทไธสง", "อำเภอลำปลายมาศ", "อำเภอสตึก", "อำเภอปะคำ", "อำเภอนาโพธิ์", "อำเภอหนองหงส์", "อำเภอพลับพลาชัย", "อำเภอห้วยราช", "อำเภอโนนสุวรรณ", "อำเภอชำนิ", "อำเภอบ้านใหม่ไชยพจน์", "อำเภอโนนดินแดง", "อำเภอบ้านด่าน", "อำเภอแคนดง", "อำเภอเฉลิมพระเกียรติ"],
  "ปทุมธานี": ["อำเภอเมืองปทุมธานี", "อำเภอคลองหลวง", "อำเภอธัญบุรี", "อำเภอหนองเสือ", "อำเภอลาดหลุมแก้ว", "อำเภอลำลูกกา", "อำเภอสามโคก"],
  "ประจวบคีรีขันธ์": ["อำเภอเมืองประจวบคีรีขันธ์", "อำเภอกุยบุรี", "อำเภอทับสะแก", "อำเภอบางสะพาน", "อำเภอบางสะพานน้อย", "อำเภอปราณบุรี", "อำเภอหัวหิน", "อำเภอสามร้อยยอด"],
  "ปราจีนบุรี": ["อำเภอเมืองปราจีนบุรี", "อำเภอกบินทร์บุรี", "อำเภอนาดี", "อำเภอบ้านสร้าง", "อำเภอประจันตคาม", "อำเภอศรีมหาโพธิ", "อำเภอศรีมโหสถ"],
  "ปัตตานี": ["อำเภอเมืองปัตตานี", "อำเภอโคกโพธิ์", "อำเภอหนองจิก", "อำเภอปะนาเระ", "อำเภอมายอ", "อำเภอทุ่งยางแดง", "อำเภอสายบุรี", "อำเภอไม้แก่น", "อำเภอยะหริ่ง", "อำเภอยะรัง", "อำเภอกะพ้อ", "อำเภอแม่ลาน"],
  "พระนครศรีอยุธยา": ["อำเภอพระนครศรีอยุธยา", "อำเภอท่าเรือ", "อำเภอนครหลวง", "อำเภอบางไทร", "อำเภอบางบาล", "อำเภอบางปะอิน", "อำเภอบางปะหัน", "อำเภอผักไห่", "อำเภอภาชี", "อำเภอลาดบัวหลวง", "อำเภอวังน้อย", "อำเภอเสนา", "อำเภอบางซ้าย", "อำเภออุทัย", "อำเภอมหาราช", "อำเภอบ้านแพรก"],
  "พะเยา": ["อำเภอเมืองพะเยา", "อำเภอจุน", "อำเภอเชียงคำ", "อำเภอเชียงม่วน", "อำเภอดอกคำใต้", "อำเภอปง", "อำเภอแม่ใจ", "อำเภอภูซาง", "อำเภอภูกามยาว"],
  "พังงา": ["อำเภอเมืองพังงา", "อำเภอเกาะยาว", "อำเภอกะปง", "อำเภอตะกั่วทุ่ง", "อำเภอตะกั่วป่า", "อำเภอคุระบุรี", "อำเภอทับปุด", "อำเภอท้ายเหมือง"],
  "พัทลุง": ["อำเภอเมืองพัทลุง", "อำเภอกงหรา", "อำเภอเขาชัยสน", "อำเภอตะโหมด", "อำเภอควนขนุน", "อำเภอปากพะยูน", "อำเภอศรีบรรพต", "อำเภอป่าบอน", "อำเภอบางแก้ว", "อำเภอป่าพะยอม", "อำเภอศรีนครินทร์"],
  "พิจิตร": ["อำเภอเมืองพิจิตร", "อำเภอวังทรายพูน", "อำเภอโพธิ์ประทับช้าง", "อำเภอตะพานหิน", "อำเภอบางมูลนาก", "อำเภอโพทะเล", "อำเภอสามง่าม", "อำเภอทับคล้อ", "อำเภอสากเหล็ก", "อำเภอบึงนาราง", "อำเภอดงเจริญ", "อำเภอวชิรบารมี"],
  "พิษณุโลก": ["อำเภอเมืองพิษณุโลก", "อำเภอนครไทย", "อำเภอชาติตระการ", "อำเภอบางระกำ", "อำเภอบางกระทุ่ม", "อำเภอพรหมพิราม", "อำเภอวัดโบสถ์", "อำเภอวังทอง", "อำเภอเนินมะปราง"],
  "เพชรบุรี": ["อำเภอเมืองเพชรบุรี", "อำเภอเขาย้อย", "อำเภอหนองหญ้าปล้อง", "อำเภอชะอำ", "อำเภอท่ายาง", "อำเภอบ้านลาด", "อำเภอบ้านแหลม", "อำเภอแก่งกระจาน"],
  "เพชรบูรณ์": ["อำเภอเมืองเพชรบูรณ์", "อำเภอชนแดน", "อำเภอหล่มสัก", "อำเภอหล่มเก่า", "อำเภอวิเชียรบุรี", "อำเภอศรีเทพ", "อำเภอหนองไผ่", "อำเภอบึงสามพัน", "อำเภอน้ำหนาว", "อำเภอวังโป่ง", "อำเภอเขาค้อ"],
  "แพร่": ["อำเภอเมืองแพร่", "อำเภอร้องกวาง", "อำเภอลอง", "อำเภอสูงเม่น", "อำเภอเด่นชัย", "อำเภอสอง", "อำเภอวังชิ้น", "อำเภอหนองม่วงไข่"],
  "ภูเก็ต": ["อำเภอเมืองภูเก็ต", "อำเภอกะทู้", "อำเภอถลาง"],
  "มหาสารคาม": ["อำเภอเมืองมหาสารคาม", "อำเภอแกดำ", "อำเภอโกสุมพิสัย", "อำเภอกันทรวิชัย", "อำเภอเชียงยืน", "อำเภอบรบือ", "อำเภอนาเชือก", "อำเภอพยัคฆภูมิพิสัย", "อำเภอวาปีปทุม", "อำเภอนาดูน", "อำเภอยางสีสุราช", "อำเภอกุดรัง", "อำเภอชื่นชม"],
  "มุกดาหาร": ["อำเภอเมืองมุกดาหาร", "อำเภอนิคมคำสร้อย", "อำเภอดอนตาล", "อำเภอดงหลวง", "อำเภอคำชะอี", "อำเภอหว้านใหญ่", "อำเภอหนองสูง"],
  "แม่ฮ่องสอน": ["อำเภอเมืองแม่ฮ่องสอน", "อำเภอขุนยวม", "อำเภอปาย", "อำเภอแม่สะเรียง", "อำเภอแม่ลาน้อย", "อำเภอสบเมย", "อำเภอปางมะผ้า"],
  "ยโสธร": ["อำเภอเมืองยโสธร", "อำเภอทรายมูล", "อำเภอกุดชุม", "อำเภอคำเขื่อนแก้ว", "อำเภอป่าติ้ว", "อำเภอมหาชนะชัย", "อำเภอค้อวัง", "อำเภอเลิงนกทา"],
  "ยะลา": ["อำเภอเมืองยะลา", "อำเภอเบตง", "อำเภอบันนังสตา", "อำเภอธารโต", "อำเภอยะหา", "อำเภอรามัน", "อำเภอกาบัง", "อำเภอกรงปินัง"],
  "ร้อยเอ็ด": ["อำเภอเมืองร้อยเอ็ด", "อำเภอเกษตรวิสัย", "อำเภอปทุมรัตต์", "อำเภอจตุรพักตรพิมาน", "อำเภอธวัชบุรี", "อำเภอพนมไพร", "อำเภอโพนทอง", "อำเภอหนองพอก", "อำเภอเสลภูมิ", "อำเภอสุวรรณภูมิ", "อำเภอเมืองสรวง", "อำเภอโพธิ์ชัย", "อำเภอหนองฮี", "อำเภอเชียงขวัญ", "อำเภออาจสามารถ", "อำเภอเมยวดี", "อำเภอศรีสมเด็จ", "อำเภอจังหาร", "อำเภอทุ่งเขาหลวง", "อำเภอศรีอยุธยา"],
  "ระนอง": ["อำเภอเมืองระนอง", "อำเภอละอุ่น", "อำเภอกะเปอร์", "อำเภอกระบุรี", "อำเภอสุขสำราญ"],
  "ระยอง": ["อำเภอเมืองระยอง", "อำเภอบ้านฉาง", "อำเภอแกลง", "อำเภอวังจันทร์", "อำเภอบ้านค่าย", "อำเภอปลวกแดง", "อำเภอเขาชะเมา", "อำเภอนิคมพัฒนา"],
  "ราชบุรี": ["อำเภอเมืองราชบุรี", "อำเภอจอมบึง", "อำเภอสวนผึ้ง", "อำเภอดำเนินสะดวก", "อำเภอบ้านโป่ง", "อำเภอบางแพ", "อำเภอโพธาราม", "อำเภอปากท่อ", "อำเภอวัดเพลง", "อำเภอบ้านคา"],
  "ลพบุรี": ["อำเภอเมืองลพบุรี", "อำเภอพัฒนานิคม", "อำเภอโคกสำโรง", "อำเภอชัยบาดาล", "อำเภอท่าวุ้ง", "อำเภอบ้านหมี่", "อำเภอท่าหลวง", "อำเภอสระโบสถ์", "อำเภอโคกเจริญ", "อำเภอลำสนธิ", "อำเภอหนองม่วง"],
  "ลำปาง": ["อำเภอเมืองลำปาง", "อำเภอแม่เมาะ", "อำเภอเกาะคา", "อำเภอเสริมงาม", "อำเภองาว", "อำเภอแจ้ห่ม", "อำเภอวังเหนือ", "อำเภอเถิน", "อำเภอแม่พริก", "อำเภอแม่ทะ", "อำเภอสบปราบ", "อำเภอห้างฉัตร", "อำเภอเมืองปาน"],
  "ลำพูน": ["อำเภอเมืองลำพูน", "อำเภอแม่ทา", "อำเภอบ้านโฮ่ง", "อำเภอลี้", "อำเภอทุ่งหัวช้าง", "อำเภอป่าซาง", "อำเภอบ้านธิ", "อำเภอเวียงหนองล่อง"],
  "เลย": ["อำเภอเมืองเลย", "อำเภอนาด้วง", "อำเภอเชียงคาน", "อำเภอปากชม", "อำเภอด่านซ้าย", "อำเภอนาแห้ว", "อำเภอภูเรือ", "อำเภอท่าลี่", "อำเภอวังสะพุง", "อำเภอภูกระดึง", "อำเภอภูหลวง", "อำเภอผาขาว", "อำเภอเอราวัณ", "อำเภอหนองหิน"],
  "ศรีสะเกษ": ["อำเภอเมืองศรีสะเกษ", "อำเภอยางชุมน้อย", "อำเภอกันทรารมย์", "อำเภอกันทรลักษ์", "อำเภอขุขันธ์", "อำเภอไพรบึง", "อำเภอปรางค์กู่", "อำเภอขุนหาญ", "อำเภอราษีไศล", "อำเภออุทุมพรพิสัย", "อำเภอบึงบูรพ์", "อำเภอห้วยทับทัน", "อำเภอโนนคูณ", "อำเภอศรีรัตนะ", "อำเภอน้ำเกลี้ยง", "อำเภอวังหิน", "อำเภอภูสิงห์", "อำเภอเมืองจันทร์", "อำเภอเบญจลักษ์", "อำเภอพยุห์", "อำเภอโพธิ์ศรีสุวรรณ", "อำเภอศิลาลาด"],
  "สกลนคร": ["อำเภอเมืองสกลนคร", "อำเภอกุสุมาลย์", "อำเภอกุดบาก", "อำเภอพรรณานิคม", "อำเภอพังโคน", "อำเภอวาริชภูมิ", "อำเภอนิคมน้ำอูน", "อำเภอวานรนิวาส", "อำเภอคำตากล้า", "อำเภอบ้านม่วง", "อำเภออากาศอำนวย", "อำเภอสว่างแดนดิน", "อำเภอส่องดาว", "อำเภอเต่างอย", "อำเภอโคกศรีสุพรรณ", "อำเภอเจริญศิลป์", "อำเภอโพนนาแก้ว", "อำเภอภูพาน"],
  "สงขลา": ["อำเภอเมืองสงขลา", "อำเภอสทิงพระ", "อำเภอจะนะ", "อำเภอนาทวี", "อำเภอเทพา", "อำเภอสะบ้าย้อย", "อำเภอระโนด", "อำเภอกระแสสินธุ์", "อำเภอรัตภูมิ", "อำเภอสะเดา", "อำเภอหาดใหญ่", "อำเภอนาหม่อม", "อำเภอควนเนียง", "อำเภอบางกล่ำ", "อำเภอสิงหนคร", "อำเภอคลองหอยโข่ง"],
  "สตูล": ["อำเภอเมืองสตูล", "อำเภอควนโดน", "อำเภอควนกาหลง", "อำเภอท่าแพ", "อำเภอละงู", "อำเภอทุ่งหว้า", "อำเภอมะนัง"],
  "สมุทรปราการ": ["อำเภอเมืองสมุทรปราการ", "อำเภอบางบ่อ", "อำเภอบางพลี", "อำเภอพระประแดง", "อำเภอพระสมุทรเจดีย์", "อำเภอบางเสาธง"],
  "สมุทรสงคราม": ["อำเภอเมืองสมุทรสงคราม", "อำเภอบางคนที", "อำเภออัมพวา"],
  "สมุทรสาคร": ["อำเภอเมืองสมุทรสาคร", "อำเภอกระทุ่มแบน", "อำเภอบ้านแพ้ว"],
  "สระแก้ว": ["อำเภอเมืองสระแก้ว", "อำเภอคลองหาด", "อำเภอตาพระยา", "อำเภอวังน้ำเย็น", "อำเภอวัฒนานคร", "อำเภออรัญประเทศ", "อำเภอเขาฉกรรจ์", "อำเภอโคกสูง", "อำเภอวังสมบูรณ์"],
  "สระบุรี": ["อำเภอเมืองสระบุรี", "อำเภอแก่งคอย", "อำเภอหนองแค", "อำเภอวิหารแดง", "อำเภอหนองแซง", "อำเภอบ้านหมอ", "อำเภอดอนพุด", "อำเภอหนองโดน", "อำเภอพระพุทธบาท", "อำเภอเสาไห้", "อำเภอมวกเหล็ก", "อำเภอวังม่วง", "อำเภอเฉลิมพระเกียรติ"],
  "สิงห์บุรี": ["อำเภอเมืองสิงห์บุรี", "อำเภอบางระจัน", "อำเภอค่ายบางระจัน", "อำเภอพรหมบุรี", "อำเภอท่าช้าง", "อำเภออินทร์บุรี"],
  "สุโขทัย": ["อำเภอเมืองสุโขทัย", "อำเภอบ้านด่านลานหอย", "อำเภอคีรีมาศ", "อำเภอกงไกรลาศ", "อำเภอศรีสัชนาลัย", "อำเภอศรีสำโรง", "อำเภอสวรรคโลก", "อำเภอทุ่งเสลี่ยม", "อำเภอศรีนคร"],
  "สุพรรณบุรี": ["อำเภอเมืองสุพรรณบุรี", "อำเภอเดิมบางนางบวช", "อำเภอด่านช้าง", "อำเภอบางปลาม้า", "อำเภอศรีประจันต์", "อำเภอดอนเจดีย์", "อำเภอสองพี่น้อง", "อำเภอสามชุก", "อำเภออู่ทอง", "อำเภอหนองหญ้าไซ"],
  "สุราษฎร์ธานี": ["อำเภอเมืองสุราษฎร์ธานี", "อำเภอกาญจนดิษฐ์", "อำเภอดอนสัก", "อำเภอเกาะสมุย", "อำเภอเกาะพะงัน", "อำเภอไชยา", "อำเภอท่าชนะ", "อำเภอคีรีรัฐนิคม", "อำเภอบ้านตาขุน", "อำเภอพนม", "อำเภอท่าฉาง", "อำเภอบ้านนาสาร", "อำเภอบ้านนาเดิม", "อำเภอเคียนซา", "อำเภอเวียงสระ", "อำเภอพระแสง", "อำเภอพุนพิน", "อำเภอชัยบุรี", "อำเภอวิภาวดี"],
  "สุรินทร์": ["อำเภอเมืองสุรินทร์", "อำเภอชุมพลบุรี", "อำเภอท่าตูม", "อำเภอจอมพระ", "อำเภอปราสาท", "อำเภอกาบเชิง", "อำเภอรัตนบุรี", "อำเภอสนม", "อำเภอศีขรภูมิ", "อำเภอสังขะ", "อำเภอลำดวน", "อำเภอสำโรงทาบ", "อำเภอบัวเชด", "อำเภอพนมดงรัก", "อำเภอศรีณรงค์", "อำเภอเขวาสินรินทร์", "อำเภอโนนนารายณ์"],
  "หนองคาย": ["อำเภอเมืองหนองคาย", "อำเภอท่าบ่อ", "อำเภอโพนพิสัย", "อำเภอศรีเชียงใหม่", "อำเภอสังคม", "อำเภอสระใคร", "อำเภอเฝ้าไร่", "อำเภอรัตนวาปี", "อำเภอโพธิ์ตาก"],
  "หนองบัวลำภู": ["อำเภอเมืองหนองบัวลำภู", "อำเภอนากลาง", "อำเภอโนนสัง", "อำเภอศรีบุญเรือง", "อำเภอสุวรรณคูหา", "อำเภอนาวัง"],
  "อ่างทอง": ["อำเภอเมืองอ่างทอง", "อำเภอไชโย", "อำเภอป่าโมก", "อำเภอโพธิ์ทอง", "อำเภอแสวงหา", "อำเภอวิเศษชัยชาญ", "อำเภอสามโก้"],
  "อำนาจเจริญ": ["อำเภอเมืองอำนาจเจริญ", "อำเภอชานุมาน", "อำเภอปทุมราชวงศา", "อำเภอพนา", "อำเภอเสนางคนิคม", "อำเภอหัวตะพาน", "อำเภอลืออำนาจ"],
  "อุดรธานี": ["อำเภอเมืองอุดรธานี", "อำเภอกุดจับ", "อำเภอหนองวัวซอ", "อำเภอกุมภวาปี", "อำเภอโนนสะอาด", "อำเภอหนองหาน", "อำเภอทุ่งฝน", "อำเภอไชยวาน", "อำเภอศรีธาตุ", "อำเภอวังสามหมอ", "อำเภอบ้านดุง", "อำเภอบ้านผือ", "อำเภอน้ำโสม", "อำเภอเพ็ญ", "อำเภอสร้างคอม", "อำเภอหนองแสง", "อำเภอนายูง", "อำเภอพิบูลย์รักษ์", "อำเภอกู่แก้ว", "อำเภอประจักษ์ศิลปาคม"],
  "อุตรดิตถ์": ["อำเภอเมืองอุตรดิตถ์", "อำเภอตรอน", "อำเภอท่าปลา", "อำเภอน้ำปาด", "อำเภอฟากท่า", "อำเภอบ้านโคก", "อำเภอพิชัย", "อำเภอลับแล", "อำเภอทองแสนขัน"],
  "อุทัยธานี": ["อำเภอเมืองอุทัยธานี", "อำเภอทัพทัน", "อำเภอสว่างอารมณ์", "อำเภอหนองฉาง", "อำเภอหนองขาหย่าง", "อำเภอบ้านไร่", "อำเภอลานสัก", "อำเภอห้วยคต"],
  "อุบลราชธานี": ["อำเภอเมืองอุบลราชธานี", "อำเภอศรีเมืองใหม่", "อำเภอโขงเจียม", "อำเภอเขื่องใน", "อำเภอเขมราฐ", "อำเภอเดชอุดม", "อำเภอนาจะหลวย", "อำเภอน้ำยืน", "อำเภอบุณฑริก", "อำเภอตระการพืชผล", "อำเภอกุดข้าวปุ้น", "อำเภอม่วงสามสิบ", "อำเภอวารินชำราบ", "อำเภอพิบูลมังสาหาร", "อำเภอตาลสุม", "อำเภอโพธิ์ไทร", "อำเภอสำโรง", "อำเภอดอนมดแดง", "อำเภอสิรินธร", "อำเภอทุ่งศรีอุดม", "อำเภอนาเยีย", "อำเภอนาตาล", "อำเภอเหล่าเสือโก้ก", "อำเภอสว่างวีระวงศ์", "อำเภอน้ำขุ่น"],
};

const THAI_SUBDISTRICTS = {
  "เขตคลองเตย": ["คลองเตย", "คลองตัน", "พระโขนง"],
  "เขตวัฒนา": ["ลุมพินี", "คลองเตยเหนือ", "คลองตันเหนือ"],
  "เขตปทุมวัน": ["รองเมือง", "วังใหม่", "ปทุมวัน", "ลุมพินี"],
  "เขตบางรัก": ["มหาพฤฒาราม", "สีลม", "สุริยวงศ์", "บางรัก", "สี่พระยา"],
  "อำเภอเมืองเชียงใหม่": ["ศรีภูมิ", "พระสิงห์", "หายยา", "ช้างม่อย", "ช้างคลาน", "วัดเกต", "สุเทพ"],
  "อำเภอเมืองนนทบุรี": ["สวนใหญ่", "ตลาดขวัญ", "บางเขน", "บางกระสอ", "ท่าทราย"],
};

function PosOrderPage({ tables, setTables, categories, menu, channels, sessions, setSessions, paymentSettings, slipSettings, storeInfo, cancelHistory, setCancelHistory, staff, positions, ownerProfile, members, setMembers, tiers, pointRateSettings, history, setHistory, orderHistory, setOrderHistory, promotions, rewards, setRewards, stockItems, setStockItems, financeAccounts, setFinanceAccounts, setKitchenFood, setKitchenDrinks, currentBranchId, currentUser, branches, pendingRedemptions, setPendingRedemptions, printers, logActivity, emailReceiptSettings, jumpToTableId, onJumpToTableConsumed }) {
  const [view, setView] = useState("tables"); // "tables" | "order"
  const [currentTableId, setCurrentTableId] = useState(null);
  // Lets OpenTablesPage's "ตรวจสอบสลิป & ชำระเงิน" button drop staff straight
  // into this exact table's payment view (slip + verification banner +
  // confirm/reject + the rest of the checkout flow) instead of making them
  // find the table again in the grid below. Runs once per jumpToTableId
  // value, then tells the parent to clear it so it doesn't fire again on a
  // later, unrelated visit to this page.
  useEffect(() => {
    if (!jumpToTableId) return;
    if (!tables.some(t => t.id === jumpToTableId)) { onJumpToTableConsumed?.(); return; }
    setCurrentTableId(jumpToTableId);
    setView("order");
    setShowPayment(true);
    onJumpToTableConsumed?.();
  }, [jumpToTableId]);
  const [channelModal, setChannelModal] = useState(null); // { tableId, channelId, fulfillment, guestCount }
  const [filters, setFilters] = useState({ available: true, reserved: true, ordering: true, sentToKitchen: true });
  const [showHistory, setShowHistory] = useState(false);
  const [activeCat, setActiveCat] = useState(categories[0]?.id);
  const [picker, setPicker] = useState(null); // { item, selections, note, qty }
  const [sent, setSent] = useState(false);
  const [showPayment, setShowPayment] = useState(false);
  const [showQrPrint, setShowQrPrint] = useState(false);
  const [cartExpanded, setCartExpanded] = useState(false); // mobile-only: cart shown as a side tab that expands full-screen
  // Layout switch for the POS menu grid (and the table-picker grid below) is
  // driven from JS (actual window width) rather than a Tailwind breakpoint
  // alone — some embedded/preview viewports report a CSS width that doesn't
  // match what the responsive utility classes expect, so we measure directly
  // to keep every grid on this page in sync with each other.
  const [windowWidth, setWindowWidth] = useState(() => (typeof window !== "undefined" ? window.innerWidth : 1024));
  useEffect(() => {
    function handleResize() { setWindowWidth(window.innerWidth); }
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);
  const isWideScreen = windowWidth >= 768;
  const tableGridColsClass = windowWidth >= 768 ? "grid-cols-6" : windowWidth >= 640 ? "grid-cols-3" : "grid-cols-2";
  const [showMemberModal, setShowMemberModal] = useState(false);
  const [showPromoModal, setShowPromoModal] = useState(false);
  const [mixMatchPicker, setMixMatchPicker] = useState(null); // { promo, selectedIds }
  const [showRedeemModal, setShowRedeemModal] = useState(false);
  const [redemptionCodeInput, setRedemptionCodeInput] = useState("");
  const [autoPrintTickets, setAutoPrintTickets] = useState([]); // tickets to print right after "ส่งเข้าครัว"
  useEffect(() => {
    if (autoPrintTickets.length === 0) return;
    // Try the local print agent first (see print-agent/README.md) — it prints
    // straight to the kitchen printer's IP with no dialog. If it's not
    // running, fall back to window.print() on the hidden templates below
    // (give them a tick to render first).
    const timer = setTimeout(async () => {
      let anyFailed = false;
      for (const t of autoPrintTickets) {
        const toggleKey = t.kitchenLabel === "ครัวเครื่องดื่ม" ? "drinkEnabled" : "kitchenEnabled";
        const eligiblePrinter = (printers || []).find(p =>
          p.connected && p[toggleKey] && (!p.branchId || p.branchId === currentBranchId)
        );
        if (eligiblePrinter) {
          const ok = await printViaAgent("kitchen", buildKitchenTicketDoc(t));
          if (!ok) anyFailed = true;
        } else {
          anyFailed = true; // no eligible printer configured — fall back to the browser dialog
        }
      }
      if (anyFailed) printReceiptPage();
      setAutoPrintTickets([]);
    }, 150);
    return () => clearTimeout(timer);
  }, [autoPrintTickets]);
  const [redemptionCodeError, setRedemptionCodeError] = useState("");
  const [redemptionCodeSuccess, setRedemptionCodeSuccess] = useState("");
  const [voidApproval, setVoidApproval] = useState(null); // { itemName, execute, pin, reason, error }
  const [viewingMemberProfile, setViewingMemberProfile] = useState(false);
  const [memberPhoneInput, setMemberPhoneInput] = useState("");
  const [showEditOrder, setShowEditOrder] = useState(false);
  const [paymentMethodId, setPaymentMethodId] = useState(null);
  const [splitPayments, setSplitPayments] = useState([]); // [{id, methodId, amount}] — supports paying with more than one method
  const [isSplitMode, setIsSplitMode] = useState(false); // ติ๊ก "แบ่งชำระ" เพื่อเลือกได้หลายช่องทาง
  const [requestTaxInvoice, setRequestTaxInvoice] = useState(false);
  const [taxInvoiceType, setTaxInvoiceType] = useState("individual"); // "individual" | "corporate"
  const [taxInvoiceBuyer, setTaxInvoiceBuyer] = useState({ name: "", address: "", taxId: "", branch: "" });
  const [cashReceived, setCashReceived] = useState("");
  const [showEmailReceipt, setShowEmailReceipt] = useState(false);
  const [receiptEmail, setReceiptEmail] = useState("");
  const [quickRegisterOpen, setQuickRegisterOpen] = useState(false);
  const [quickRegisterName, setQuickRegisterName] = useState("");

  const session = currentTableId ? sessions[currentTableId] : null;
  const channel = session ? channels.find(c => c.id === session.channelId) : null;
  const currentTable = tables.find(t => t.id === currentTableId);
  const isDineIn = channel?.name === "หน้าร้าน";
  const cart = session?.cart || [];
  const items = menu
    .filter(m => m.catId === activeCat)
    .filter(m => !currentBranchId || !m.branchIds?.length || m.branchIds.includes(currentBranchId));
  const total = cart.reduce((s, c) => s + c.unitPrice * c.qty, 0);

  const linkedMember = session?.memberId ? members.find(m => m.id === session.memberId) : null;
  const linkedTier = linkedMember ? tiers.find(t => t.name === linkedMember.tier) : null;
  const allBillItems = [...(session?.sentItems || []), ...cart];
  const billSubtotal = (session?.billTotal || 0) + total;
  const qtyInCartById = {};
  allBillItems.forEach(it => { qtyInCartById[it.id] = (qtyInCartById[it.id] || 0) + it.qty; });

  const today = new Date();
  const isBirthdayToday = linkedMember?.birthday && (() => {
    const b = new Date(linkedMember.birthday);
    return b.getMonth() === today.getMonth() && b.getDate() === today.getDate();
  })();
  const birthdayDiscountActive = !!(linkedTier?.birthdayDiscount?.enabled && isBirthdayToday);
  const birthdayDiscountAmount = birthdayDiscountActive ? Math.round(
    allBillItems
      .filter(it => {
        const catIds = linkedTier.birthdayDiscount.categoryIds;
        if (!catIds.length) return true;
        return catIds.includes(it.catId);
      })
      .reduce((s, it) => s + it.unitPrice * it.qty, 0) * (linkedTier.birthdayDiscount.percent / 100)
  ) : 0;

  const activePromotions = (promotions || []).filter(p => p.active);
  const bundlePromotions = activePromotions.filter(p => p.type === "bundle");
  const mixMatchPromotions = activePromotions.filter(p => p.type === "mixMatch");
  const appliedPromoIds = session?.appliedPromoIds || [];
  const appliedPromos = appliedPromoIds.map(id => activePromotions.find(p => p.id === id)).filter(Boolean);
  // Business rule: promotion campaigns cannot be stacked with the member's birthday discount.
  const effectiveBirthdayDiscountAmount = appliedPromos.length > 0 ? 0 : birthdayDiscountAmount;

  // Reward redemptions are evaluated first since their discount counts toward
  // "other discounts already applied" when checking a ยอดเงินขั้นต่ำ threshold.
  const redeemedRewardIds = session?.redeemedRewardIds || [];
  const redeemedRewardEvaluations = redeemedRewardIds.map(id => {
    const reward = rewards.find(r => r.id === id);
    if (!reward) return null;
    let discountAmount = 0;
    if (reward.type === "discount") {
      discountAmount = reward.discount.mode === "percent" ? Math.round(billSubtotal * (reward.discount.value / 100)) : reward.discount.value;
    } else if (reward.type === "food") {
      const item = menu.find(m => m.id === reward.food.itemId);
      discountAmount = item ? priceForChannel(item) : 0;
    }
    return { reward, discountAmount };
  }).filter(Boolean);
  const rewardDiscountAmount = redeemedRewardEvaluations.reduce((s, e) => s + e.discountAmount, 0);

  function evaluatePromo(promo, netSubtotalForMinSpend) {
    let discountAmount = 0, conditionUnmet = false, pointsBonus = 0, pointsMultiplier = 1;
    if (promo.type === "minSpend") {
      // Eligibility is checked against the amount AFTER other discounts (birthday,
      // reward redemptions, and other applied promotions) have already been taken off.
      const eligible = allBillItems.filter(it => !promo.excludedCategoryIds?.includes(it.catId));
      const eligibleTotal = eligible.reduce((s, it) => s + it.unitPrice * it.qty, 0);
      if (netSubtotalForMinSpend >= promo.minSpend.amount) {
        discountAmount = promo.minSpend.discountType === "percent"
          ? Math.round(eligibleTotal * (promo.minSpend.value / 100))
          : promo.minSpend.value;
      } else conditionUnmet = true;
    } else if (promo.type === "happyHour") {
      const now = new Date();
      const nowStr = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
      if (nowStr >= promo.happyHour.startTime && nowStr <= promo.happyHour.endTime) {
        const eligible = allBillItems.filter(it => !promo.excludedCategoryIds?.includes(it.catId));
        const eligibleTotal = eligible.reduce((s, it) => s + it.unitPrice * it.qty, 0);
        discountAmount = promo.happyHour.discountType === "percent"
          ? Math.round(eligibleTotal * (promo.happyHour.value / 100))
          : promo.happyHour.value;
      } else conditionUnmet = true;
    } else if (promo.type === "bundle") {
      const required = [...promo.bundle.foodItemIds, ...promo.bundle.drinkItemIds];
      const priceById = {};
      allBillItems.forEach(it => { if (priceById[it.id] === undefined) priceById[it.id] = it.unitPrice; });
      const setsPossible = required.length > 0 ? Math.min(...required.map(id => Math.floor(qtyInCartById[id] || 0))) : 0;
      if (setsPossible > 0) {
        const normalSetPrice = required.reduce((s, id) => s + (priceById[id] || 0), 0);
        const promoSetPrice = promo.bundle.promoMode === "fixed"
          ? promo.bundle.promoPrice
          : Math.round(normalSetPrice * (1 - promo.bundle.promoPercent / 100));
        discountAmount = Math.max(0, (normalSetPrice - promoSetPrice) * setsPossible);
      } else conditionUnmet = true;
    } else if (promo.type === "mixMatch") {
      const eligibleIds = new Set(promo.mixMatch.itemIds);
      const units = [];
      allBillItems.forEach(it => { if (eligibleIds.has(it.id)) { for (let i = 0; i < it.qty; i++) units.push(it.unitPrice); } });
      units.sort((a, b) => b - a);
      const chooseCount = promo.mixMatch.chooseCount || 1;
      const numSets = Math.floor(units.length / chooseCount);
      if (numSets > 0) {
        const usedUnits = units.slice(0, numSets * chooseCount);
        const normalValue = usedUnits.reduce((s, v) => s + v, 0);
        discountAmount = Math.max(0, normalValue - numSets * promo.mixMatch.price);
      } else conditionUnmet = true;
    } else if (promo.type === "points") {
      if (!linkedMember) {
        conditionUnmet = true;
      } else {
        const conditionMet = promo.points.trigger === "birthdayMonth"
          ? !!(linkedMember.birthday && new Date(linkedMember.birthday).getMonth() === today.getMonth())
          : billSubtotal >= promo.points.thresholdAmount;
        if (conditionMet) {
          if (promo.points.rewardType === "multiplier") pointsMultiplier = promo.points.multiplier;
          else pointsBonus = promo.points.bonusPoints;
        } else conditionUnmet = true;
      }
    }
    return { discountAmount, conditionUnmet, pointsBonus, pointsMultiplier };
  }
  function getPromoEligibleItems(promo) {
    let ids = [];
    if (promo.type === "bundle") ids = [...promo.bundle.foodItemIds, ...promo.bundle.drinkItemIds];
    else if (promo.type === "mixMatch") ids = promo.mixMatch.itemIds;
    else return [];
    return ids.map(id => menu.find(m => m.id === id)).filter(Boolean).map(m => ({ ...m, inCart: (qtyInCartById[m.id] || 0) > 0 }));
  }

  // First pass: evaluate every non-"ยอดเงินขั้นต่ำ" promo so we know the total of
  // "other discounts" already applied before checking any minimum-spend threshold.
  const nonMinSpendEvaluations = appliedPromos
    .filter(p => p.type !== "minSpend")
    .map(promo => ({ promo, ...evaluatePromo(promo, null), eligibleItems: getPromoEligibleItems(promo) }));
  const otherDiscountsForMinSpend = effectiveBirthdayDiscountAmount + rewardDiscountAmount
    + nonMinSpendEvaluations.reduce((s, e) => s + e.discountAmount, 0);
  const netSubtotalForMinSpend = billSubtotal - otherDiscountsForMinSpend;

  const minSpendEvaluations = appliedPromos
    .filter(p => p.type === "minSpend")
    .map(promo => ({ promo, ...evaluatePromo(promo, netSubtotalForMinSpend), eligibleItems: [] }));

  // Recombine in the original selection order for consistent display.
  const promoEvaluations = appliedPromos.map(promo =>
    nonMinSpendEvaluations.find(e => e.promo.id === promo.id) || minSpendEvaluations.find(e => e.promo.id === promo.id)
  );
  const promoDiscountAmount = promoEvaluations.reduce((s, e) => s + e.discountAmount, 0);
  const promoPointsBonus = promoEvaluations.reduce((s, e) => s + e.pointsBonus, 0);
  const promoPointsMultiplier = promoEvaluations.reduce((m, e) => m * e.pointsMultiplier, 1);

  const todayStr = today.toISOString().slice(0, 10);
  const eligibleRewards = linkedMember ? rewards.filter(r => {
    if (r.startDate && r.startDate > todayStr) return false;
    if (r.endDate && r.endDate < todayStr) return false;
    const remaining = (r.quota === "" || r.quota == null) ? Infinity : Math.max(0, r.quota - (r.usedCount || 0));
    if (remaining <= 0) return false;
    if (r.limitPerMember !== "" && r.limitPerMember != null) {
      const memberCount = r.redemptionsByMember?.[linkedMember.id] || 0;
      if (memberCount >= r.limitPerMember) return false;
    }
    if (r.limitPerBill !== "" && r.limitPerBill != null) {
      const billCount = redeemedRewardIds.filter(id => id === r.id).length;
      if (billCount >= r.limitPerBill) return false;
    }
    return linkedMember.points >= r.points;
  }) : [];

  function redeemReward(reward) {
    if (!linkedMember || linkedMember.points < reward.points) return;
    setMembers(prev => prev.map(m => m.id === linkedMember.id ? { ...m, points: m.points - reward.points } : m));
    setRewards(prev => prev.map(r => r.id === reward.id
      ? { ...r, usedCount: (r.usedCount || 0) + 1, redemptionsByMember: { ...r.redemptionsByMember, [linkedMember.id]: (r.redemptionsByMember?.[linkedMember.id] || 0) + 1 } }
      : r));
    setSessions(prev => ({
      ...prev,
      [currentTableId]: {
        ...prev[currentTableId],
        redeemedRewardIds: [...(prev[currentTableId]?.redeemedRewardIds || []), reward.id],
        // Track that this entry was redeemed by staff directly in this bill (points
        // deducted just now), as opposed to via a customer self-service code —
        // needed so removing it later knows whether to refund points.
        redeemedViaCode: [...(prev[currentTableId]?.redeemedViaCode || []), null],
      },
    }));
    if (setHistory) {
      setHistory(prev => [{
        id: "h" + Date.now(), member: linkedMember.name, date: todayStr,
        action: `แลกของรางวัล: ${reward.name}`, amount: 0, pointChange: `-${reward.points}`,
      }, ...prev]);
    }
  }
  function removeRedeemedReward(index) {
    const id = redeemedRewardIds[index];
    const reward = rewards.find(r => r.id === id);
    const codeUsed = session?.redeemedViaCode?.[index] || null; // the code string, or null if staff-initiated
    // Only refund points/quota if this entry was redeemed by staff directly in
    // this bill — a code-based redemption already spent the customer's points
    // via the LINE self-service flow, so removing it here must not touch points.
    if (reward && linkedMember && !codeUsed) {
      setMembers(prev => prev.map(m => m.id === linkedMember.id ? { ...m, points: m.points + reward.points } : m));
      setRewards(prev => prev.map(r => r.id === id
        ? { ...r, usedCount: Math.max(0, (r.usedCount || 0) - 1), redemptionsByMember: { ...r.redemptionsByMember, [linkedMember.id]: Math.max(0, (r.redemptionsByMember?.[linkedMember.id] || 0) - 1) } }
        : r));
    }
    // If this was a customer's code, un-burn it (set used: false again) since it
    // was pulled out of the bill *before* payment — otherwise the customer would
    // lose the reward they already paid points for with no way to redeem it.
    if (codeUsed && setPendingRedemptions) {
      setPendingRedemptions(prev => prev.map(r => r.code === codeUsed ? { ...r, used: false } : r));
    }
    setSessions(prev => {
      const cur = [...(prev[currentTableId]?.redeemedRewardIds || [])];
      const viaCode = [...(prev[currentTableId]?.redeemedViaCode || [])];
      cur.splice(index, 1);
      viaCode.splice(index, 1);
      return { ...prev, [currentTableId]: { ...prev[currentTableId], redeemedRewardIds: cur, redeemedViaCode: viaCode } };
    });
  }
  function applyRedemptionCode(code) {
    const trimmed = code.trim().toUpperCase();
    if (!trimmed) return { ok: false, error: "กรุณากรอกรหัส" };
    const record = (pendingRedemptions || []).find(r => r.code.toUpperCase() === trimmed);
    if (!record) return { ok: false, error: "ไม่พบรหัสนี้ — ตรวจสอบรหัสอีกครั้ง" };
    if (record.used) return { ok: false, error: "รหัสนี้ถูกใช้ไปแล้ว" };
    if (record.revealedAt && Date.now() - record.revealedAt > 90 * 60 * 1000) {
      return { ok: false, error: "รหัสนี้หมดเวลาแล้ว (เกิน 90 นาทีหลังกดใช้รหัส) กรุณาให้ลูกค้ากดใช้รหัสใหม่" };
    }
    if (linkedMember && record.memberId !== linkedMember.id) return { ok: false, error: `รหัสนี้เป็นของสมาชิก "${record.memberName}" ไม่ตรงกับสมาชิกที่ผูกบิลนี้` };
    const reward = rewards.find(r => r.id === record.rewardId);
    if (!reward) return { ok: false, error: "ไม่พบของรางวัลนี้ในระบบแล้ว" };
    // Points were already deducted when the customer redeemed via self-service —
    // here we only mark the code used and apply the discount/free item to this
    // bill, reusing the same evaluation logic as staff-initiated redemptions.
    setSessions(prev => ({
      ...prev,
      [currentTableId]: {
        ...prev[currentTableId],
        redeemedRewardIds: [...(prev[currentTableId]?.redeemedRewardIds || []), reward.id],
        redeemedViaCode: [...(prev[currentTableId]?.redeemedViaCode || []), record.code],
      },
    }));
    setPendingRedemptions(prev => prev.map(r => r.code === record.code ? { ...r, used: true } : r));
    return { ok: true, rewardName: reward.name };
  }

  const pointsMultiplier = (linkedTier?.pointsMultiplier?.enabled ? linkedTier.pointsMultiplier.multiplier : 1) * promoPointsMultiplier;
  const pointsEarned = linkedMember
    ? Math.floor(((billSubtotal - effectiveBirthdayDiscountAmount - promoDiscountAmount - rewardDiscountAmount) / (pointRateSettings.baht || 10)) * pointsMultiplier) + promoPointsBonus
    : 0;

  function addMixMatchToCart(promo, selectedIds) {
    const newLines = selectedIds.map(id => {
      const item = menu.find(m => m.id === id);
      if (!item) return null;
      return {
        cartLineId: "cl" + Date.now() + Math.random().toString(36).slice(2, 6),
        id: item.id, catId: item.catId, name: item.name, unitPrice: priceForChannel(item), qty: 1,
        optionSummary: [], note: "",
      };
    }).filter(Boolean);
    updateCart(prev => [...prev, ...newLines]);
    setSessions(prev => {
      const cur = prev[currentTableId]?.appliedPromoIds || [];
      const next = cur.includes(promo.id) ? cur : [...cur, promo.id];
      return { ...prev, [currentTableId]: { ...prev[currentTableId], appliedPromoIds: next } };
    });
  }

  function addBundleToCart(promo) {
    const requiredIds = [...promo.bundle.foodItemIds, ...promo.bundle.drinkItemIds];
    const newLines = requiredIds.map(id => {
      const item = menu.find(m => m.id === id);
      if (!item) return null;
      return {
        cartLineId: "cl" + Date.now() + Math.random().toString(36).slice(2, 6),
        id: item.id, catId: item.catId, name: item.name, unitPrice: priceForChannel(item), qty: 1,
        optionSummary: [], note: "",
      };
    }).filter(Boolean);
    updateCart(prev => [...prev, ...newLines]);
    setSessions(prev => {
      const cur = prev[currentTableId]?.appliedPromoIds || [];
      const next = cur.includes(promo.id) ? cur : [...cur, promo.id];
      return { ...prev, [currentTableId]: { ...prev[currentTableId], appliedPromoIds: next } };
    });
  }

  function togglePromo(id) {
    setSessions(prev => {
      const cur = prev[currentTableId]?.appliedPromoIds || [];
      const next = cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id];
      return { ...prev, [currentTableId]: { ...prev[currentTableId], appliedPromoIds: next } };
    });
  }
  function removePromoId(id) {
    setSessions(prev => {
      const cur = prev[currentTableId]?.appliedPromoIds || [];
      return { ...prev, [currentTableId]: { ...prev[currentTableId], appliedPromoIds: cur.filter(x => x !== id) } };
    });
  }

  function linkMember() {
    const found = members.find(m => m.phone.replace(/-/g, "") === memberPhoneInput.replace(/-/g, "") && memberPhoneInput.trim() !== "");
    if (!found || !currentTableId) return;
    setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], memberId: found.id } }));
    setShowMemberModal(false);
    setMemberPhoneInput("");
  }
  function unlinkMember() {
    setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], memberId: null } }));
  }

  function computeStockUsage(items) {
    const usage = {};
    function addUsage(recipe, multiplier) {
      (recipe || []).forEach(r => {
        const stockItem = stockItems.find(s => s.id === r.stockItemId);
        const sub = UNIT_SUBDIVISION[stockItem?.unit];
        const qtyInBaseUnit = sub ? Number(r.qty) / sub.factor : Number(r.qty);
        usage[r.stockItemId] = (usage[r.stockItemId] || 0) + qtyInBaseUnit * multiplier;
      });
    }
    items.forEach(it => {
      const menuItem = menu.find(m => m.id === it.id);
      if (!menuItem) return;
      addUsage(menuItem.recipe, it.qty);
      // Also account for ingredients tied to any selected options on this line.
      (menuItem.optionGroups || []).forEach(g => {
        const sel = it.selections?.[g.id];
        const choiceIds = g.type === "single" ? (sel ? [sel] : []) : (sel || []);
        choiceIds.forEach(cid => {
          const choice = g.choices.find(c => c.id === cid);
          if (choice?.recipe?.length) addUsage(choice.recipe, it.qty);
        });
      });
    });
    return usage;
  }
  function applyStockUsage(usage, sign) {
    if (!setStockItems) return;
    setStockItems(prev => prev.map(s => {
      if (usage[s.id] === undefined) return s;
      const delta = sign * usage[s.id];
      if (!currentBranchId) {
        const next = s.currentStock + delta;
        return { ...s, currentStock: Math.max(0, Math.round(next * 1000) / 1000) };
      }
      const existing = s.branchStock?.[currentBranchId] || { currentStock: s.currentStock, minStock: s.minStock };
      const nextQty = Math.max(0, Math.round((existing.currentStock + delta) * 1000) / 1000);
      return { ...s, branchStock: { ...s.branchStock, [currentBranchId]: { ...existing, currentStock: nextQty } } };
    }));
  }

  function editSentItemQty(cartLineId, delta) {
    const editingItem = session?.sentItems.find(x => x.cartLineId === cartLineId);
    setSessions(prev => {
      const s = prev[currentTableId];
      const nextItems = s.sentItems.flatMap(it => {
        if (it.cartLineId !== cartLineId) return [it];
        const q = it.qty + delta;
        return q <= 0 ? [] : [{ ...it, qty: q }];
      });
      const billTotal = nextItems.reduce((sum, it) => sum + it.unitPrice * it.qty, 0);
      return { ...prev, [currentTableId]: { ...s, sentItems: nextItems, billTotal } };
    });
    if (editingItem) {
      const usage = computeStockUsage([{ id: editingItem.id, qty: Math.abs(delta) }]);
      applyStockUsage(usage, delta > 0 ? -1 : 1); // more units ordered -> deduct more; fewer -> restore
    }
  }
  function removeSentItem(cartLineId) {
    const removingItem = session?.sentItems.find(x => x.cartLineId === cartLineId);
    setSessions(prev => {
      const s = prev[currentTableId];
      const nextItems = s.sentItems.filter(it => it.cartLineId !== cartLineId);
      const billTotal = nextItems.reduce((sum, it) => sum + it.unitPrice * it.qty, 0);
      return { ...prev, [currentTableId]: { ...s, sentItems: nextItems, billTotal } };
    });
    if (removingItem) {
      const usage = computeStockUsage([{ id: removingItem.id, qty: removingItem.qty }]);
      applyStockUsage(usage, 1); // fully removed -> restore all its stock usage
    }
  }

  function requestVoidApproval(itemName, execute) {
    setVoidApproval({ itemName, execute, pin: "", reason: "", error: "" });
  }
  function confirmVoidApproval() {
    const manager = (staff || []).find(s => s.pin === voidApproval.pin && s.active);
    const isOwner = isOwnerPin(ownerProfile, voidApproval.pin);
    if (!manager && !isOwner) {
      setVoidApproval(prev => ({ ...prev, error: "PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่" }));
      return;
    }
    if (manager && !isOwner) {
      const position = (positions || []).find(p => p.id === manager.positionId);
      if (!position?.pinPermissions?.includes("posVoidApproval")) {
        setVoidApproval(prev => ({ ...prev, error: `ตำแหน่ง "${position?.name || "-"}" ไม่มีสิทธิ์อนุมัติรายการนี้` }));
        return;
      }
    }
    const approverName = manager ? manager.name : `${ownerProfile.name} (เจ้าของร้าน)`;
    voidApproval.execute();
    if (setCancelHistory) {
      setCancelHistory(prev => [{
        id: "cx" + Date.now(),
        branchId: currentBranchId || null,
        billNo: nextReceiptNumber(history, slipSettings?.receipt?.billPrefixStore, currentBranchId, branches),
        table: currentTableId.replace(/^T/, ""),
        item: voidApproval.itemName,
        reason: voidApproval.reason.trim() || "-",
        time: "เมื่อสักครู่",
        by: approverName,
        approvedBy: approverName,
      }, ...prev]);
    }
    setVoidApproval(null);
  }

  function updateSession(tableId, patch) {
    setSessions(prev => ({ ...prev, [tableId]: { ...prev[tableId], ...patch } }));
  }
  function updateCart(fn) {
    setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], cart: fn(prev[currentTableId].cart) } }));
  }

  function priceForChannel(item) {
    if (!channel) return item.price;
    const override = item.channelPrices && item.channelPrices[channel.id];
    if (override !== undefined && override !== null && override !== "") return Number(override);
    if (channel.adjustType === "percent") return Math.round(item.price * (1 + channel.value / 100));
    if (channel.adjustType === "fixed") return item.price + channel.value;
    return item.price;
  }

  function openTable(t) {
    if (t.status === "available") {
      setChannelModal({ tableId: t.id, channelId: null, fulfillment: null, guestCount: "" });
      return;
    }
    // Not available: go straight to the order screen. Build a session from the
    // table's stored channel info if one doesn't exist in memory yet.
    if (!sessions[t.id]) {
      const ch = channels.find(c => c.name === t.channelName);
      if (ch) {
        setSessions(prev => ({ ...prev, [t.id]: { channelId: ch.id, fulfillment: t.fulfillment || null, guestCount: t.guestCount || null, cart: [], billTotal: 0, sentItems: [], qrToken: generateQrToken(), callStaffRequested: false, callStaffReason: null, callStaffAt: null, paymentSlipDataUrl: null, paymentStatus: "unpaid" } }));
      } else {
        // No channel info to recover from — fall back to asking.
        setChannelModal({ tableId: t.id, channelId: null, fulfillment: null, guestCount: "" });
        return;
      }
    }
    setCurrentTableId(t.id);
    setActiveCat(categories[0]?.id);
    setCartExpanded(false);
    setView("order");
  }

  function channelModalReady() {
    if (!channelModal || !channelModal.channelId) return false;
    const ch = channels.find(c => c.id === channelModal.channelId);
    if (!ch) return false;
    if (ch.name === "หน้าร้าน") return !!channelModal.fulfillment && Number(channelModal.guestCount) > 0;
    if ((ch.fulfillmentOptions || []).length > 0) return !!channelModal.fulfillment;
    return true;
  }

  function confirmChannel() {
    if (!channelModalReady()) return;
    const { tableId, channelId, fulfillment, guestCount } = channelModal;
    const ch = channels.find(c => c.id === channelId);
    const dineIn = ch.name === "หน้าร้าน";
    setSessions(prev => ({ ...prev, [tableId]: { channelId, fulfillment, guestCount: dineIn ? guestCount : null, cart: [], billTotal: 0, sentItems: [], qrToken: generateQrToken(), callStaffRequested: false, callStaffReason: null, callStaffAt: null, paymentSlipDataUrl: null, paymentStatus: "unpaid" } }));
    setTables(prev => prev.map(t => t.id === tableId ? { ...t, status: "ordering", channelName: ch.name, guestCount: dineIn ? guestCount : null, fulfillment } : t));
    setCurrentTableId(tableId);
    setActiveCat(categories[0]?.id);
    setChannelModal(null);
    setView("order");
  }

  function openPicker(item) {
    setSent(false);
    const selections = {};
    (item.optionGroups || []).forEach(g => { selections[g.id] = g.type === "single" ? "" : []; });
    setPicker({ item, selections, note: "", qty: 1, editingCartLineId: null });
  }

  function editCartLine(line) {
    const item = menu.find(m => m.id === line.id);
    if (!item) return;
    const selections = {};
    (item.optionGroups || []).forEach(g => { selections[g.id] = line.selections?.[g.id] ?? (g.type === "single" ? "" : []); });
    setPicker({ item, selections, note: line.note || "", qty: line.qty, editingCartLineId: line.cartLineId });
  }

  function toggleChoice(group, choiceId) {
    setPicker(prev => {
      const selections = { ...prev.selections };
      if (group.type === "single") {
        selections[group.id] = selections[group.id] === choiceId ? "" : choiceId;
      } else {
        const cur = selections[group.id] || [];
        if (cur.includes(choiceId)) {
          selections[group.id] = cur.filter(id => id !== choiceId);
        } else if (cur.length < (group.max || 99)) {
          selections[group.id] = [...cur, choiceId];
        }
      }
      return { ...prev, selections };
    });
  }

  function pickerAddonTotal() {
    if (!picker) return 0;
    return (picker.item.optionGroups || []).reduce((sum, g) => {
      const sel = picker.selections[g.id];
      if (g.type === "single") {
        const c = g.choices.find(ch => ch.id === sel);
        return sum + (c ? c.price : 0);
      }
      return sum + (sel || []).reduce((s2, id) => {
        const c = g.choices.find(ch => ch.id === id);
        return s2 + (c ? c.price : 0);
      }, 0);
    }, 0);
  }

  function pickerMissingRequired() {
    if (!picker) return false;
    return (picker.item.optionGroups || []).some(g => g.type === "single" && g.required && !picker.selections[g.id]);
  }

  function confirmAdd() {
    if (pickerMissingRequired()) return;
    const { item, selections, note, qty, editingCartLineId } = picker;
    const optionSummary = [];
    (item.optionGroups || []).forEach(g => {
      const sel = selections[g.id];
      const names = g.type === "single"
        ? (sel ? [g.choices.find(c => c.id === sel)?.name] : [])
        : (sel || []).map(id => g.choices.find(c => c.id === id)?.name);
      names.filter(Boolean).forEach(n => optionSummary.push(n));
    });
    const unitPrice = priceForChannel(item) + pickerAddonTotal();
    if (editingCartLineId) {
      updateCart(prev => prev.map(c => c.cartLineId === editingCartLineId
        ? { ...c, unitPrice, qty, optionSummary, note: note.trim(), selections }
        : c));
    } else {
      updateCart(prev => [...prev, {
        cartLineId: "cl" + Date.now() + Math.random().toString(36).slice(2, 5),
        id: item.id, catId: item.catId, name: item.name, unitPrice, qty,
        optionSummary, note: note.trim(), selections,
      }]);
    }
    setPicker(null);
  }

  function changeQty(cartLineId, delta) {
    updateCart(prev => prev.flatMap(c => {
      if (c.cartLineId !== cartLineId) return [c];
      const q = c.qty + delta;
      return q <= 0 ? [] : [{ ...c, qty: q }];
    }));
  }

  function sendToKitchen() {
    const foodItems = cart.filter(c => categories.find(cat => cat.id === c.catId)?.kind !== "drink");
    const drinkItems = cart.filter(c => categories.find(cat => cat.id === c.catId)?.kind === "drink");
    const ticketId = Math.floor(Math.random() * 900) + 100;
    const fmt = i => ({ name: i.name, qty: i.qty, options: i.optionSummary, note: i.note });
    const newTickets = [];
    if (foodItems.length) {
      const t = { id: ticketId, branchId: currentBranchId || null, table: currentTableId, items: foodItems.map(fmt), status: "queued", time: "เมื่อสักครู่", kitchenLabel: "ครัวอาหาร" };
      setKitchenFood(prev => [...prev, t]);
      newTickets.push(t);
    }
    if (drinkItems.length) {
      const t = { id: ticketId + 1, branchId: currentBranchId || null, table: currentTableId, items: drinkItems.map(fmt), status: "queued", time: "เมื่อสักครู่", kitchenLabel: "ครัวเครื่องดื่ม" };
      setKitchenDrinks(prev => [...prev, t]);
      newTickets.push(t);
    }
    if (newTickets.length) setAutoPrintTickets(newTickets);
    setTables(prev => prev.map(t => t.id === currentTableId ? { ...t, status: "sentToKitchen" } : t));
    setSessions(prev => ({
      ...prev,
      [currentTableId]: {
        ...prev[currentTableId],
        cart: [],
        billTotal: (prev[currentTableId].billTotal || 0) + total,
        sentItems: [...(prev[currentTableId].sentItems || []), ...cart],
      },
    }));
    applyStockUsage(computeStockUsage(cart), -1);
    setSent(true);
  }

  function computeBill(subtotal) {
    const sc = paymentSettings.serviceCharge;
    const vat = paymentSettings.vat;
    const serviceChargeAmt = sc.enabled ? Math.round(subtotal * sc.rate / 100) : 0;
    let vatAmt = 0;
    let grand;
    if (vat.enabled && vat.mode === "added") {
      vatAmt = Math.round((subtotal + serviceChargeAmt) * vat.rate / 100);
      grand = subtotal + serviceChargeAmt + vatAmt;
    } else if (vat.enabled && vat.mode === "included") {
      vatAmt = Math.round(subtotal * vat.rate / (100 + vat.rate));
      grand = subtotal + serviceChargeAmt;
    } else {
      grand = subtotal + serviceChargeAmt;
    }
    if (paymentSettings.rounding === "toBaht") grand = Math.round(grand);
    if (paymentSettings.rounding === "to5Baht") grand = Math.round(grand / 5) * 5;
    return { serviceChargeAmt, vatAmt, grand };
  }

  function closeTable() {
    const discountedSubtotalForPayment = Math.max(0, (session?.billTotal || 0) - (linkedMember ? effectiveBirthdayDiscountAmount : 0) - promoDiscountAmount - rewardDiscountAmount);
    const billForPayment = computeBill(discountedSubtotalForPayment);
    const paidSplits = isSplitMode
      ? splitPayments.filter(p => Number(p.amount) > 0).map(p => ({ methodId: p.methodId, amount: Math.round(Number(p.amount) * 100) / 100 }))
      : (paymentMethodId ? [{ methodId: paymentMethodId, amount: billForPayment.grand }] : []);
    if (setFinanceAccounts && paidSplits.length > 0) {
      setFinanceAccounts(prev => prev.map(a => {
        const paid = paidSplits.filter(p => p.methodId === a.id).reduce((s, p) => s + p.amount, 0);
        return paid > 0 ? { ...a, currentBalance: a.currentBalance + paid } : a;
      }));
    }
    if (linkedMember && pointsEarned > 0) {
      setMembers(prev => prev.map(m => m.id === linkedMember.id ? { ...m, points: m.points + pointsEarned } : m));
    }
    if (setHistory && (session?.billTotal || 0) > 0) {
      const now = new Date();
      setHistory(prev => [{
        id: "h" + Date.now(),
        receiptNumber: nextReceiptNumber(history, slipSettings?.receipt?.billPrefixStore, currentBranchId, branches),
        branchId: currentBranchId || null,
        member: linkedMember ? linkedMember.name : "ลูกค้าทั่วไป",
        date: now.toISOString().slice(0, 10),
        time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
        action: `รับประทานอาหาร · โต๊ะ ${currentTableId}`,
        amount: billForPayment.grand,
        financeAccountId: paidSplits.length === 1 ? paidSplits[0].methodId : null,
        splitPayments: paidSplits.length > 1 ? paidSplits : null, // multiple methods used for this one bill
        pointChange: linkedMember && pointsEarned > 0 ? `+${pointsEarned}` : "-",
        taxInvoice: requestTaxInvoice ? { ...taxInvoiceBuyer, type: taxInvoiceType } : null,
        items: (session?.sentItems || []).map(it => ({ name: it.name, qty: it.qty, unitPrice: it.unitPrice })),
        channelName: channels.find(c => c.id === session?.channelId)?.name || "-",
        receiptCompanyInfo: (() => {
          const branch = branches?.find(b => b.id === currentBranchId);
          return branch?.companyName ? {
            name: branch.companyName, address: branch.companyAddress, taxId: branch.taxId,
            phone: branch.phone, officeType: branch.officeType,
          } : null;
        })(),
        staffDisplayName: currentUser?.type === "staff"
          ? (staff.find(s => s.id === currentUser.staffId)?.displayName || currentUser.name)
          : currentUser?.type === "owner" ? (ownerProfile?.name || "เจ้าของร้าน") : null,
      }, ...prev]);
    }
    if (setOrderHistory && (session?.sentItems || []).length > 0) {
      const now = new Date();
      const itemMap = {};
      (session.sentItems || []).forEach(it => {
        const key = it.name;
        if (!itemMap[key]) itemMap[key] = { name: it.name, catId: it.catId, qty: 0 };
        itemMap[key].qty += it.qty;
      });
      setOrderHistory(prev => [{
        id: "oh" + Date.now(),
        branchId: currentBranchId || null,
        memberId: linkedMember ? linkedMember.id : null,
        date: now.toISOString().slice(0, 10),
        time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
        channel: channel?.name || "",
        amount: session?.billTotal || 0,
        items: Object.values(itemMap),
      }, ...prev]);
    }
    setTables(prev => prev.map(t => t.id === currentTableId
      ? { id: t.id, zone: t.zone, seats: t.seats, status: "available" }
      : t));
    setSessions(prev => {
      const next = { ...prev };
      delete next[currentTableId];
      return next;
    });
    setShowPayment(false);
    setPaymentMethodId(null);
    setSplitPayments([]);
    setIsSplitMode(false);
    setCashReceived("");
    setRequestTaxInvoice(false);
    setTaxInvoiceType("individual");
    setTaxInvoiceBuyer({ name: "", address: "", taxId: "", branch: "" });
    setView("tables");
  }

  function quickRegisterAndLink() {
    if (!quickRegisterName.trim() || !memberPhoneInput.trim() || !currentTableId) return;
    const nextNum = members.length + 1;
    const id = "MB" + String(nextNum).padStart(3, "0");
    const today = new Date().toISOString().slice(0, 10);
    const newMember = { id, name: quickRegisterName.trim(), phone: memberPhoneInput.trim(), birthday: "", tier: "Silver", points: 0, joined: today };
    setMembers(prev => [...prev, newMember]);
    setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], memberId: id } }));
    setQuickRegisterOpen(false);
    setQuickRegisterName("");
    setMemberPhoneInput("");
  }

  /* ===================== TABLE GRID VIEW ===================== */
  if (view === "tables") {
    const zones = [...new Set(tables.map(t => t.zone))];
    const visibleTables = t => filters[t.status];

    return (
      <div>
        <PageHeader eyebrow="หน้าร้าน" title="POS Order" subtitle="เลือกโต๊ะเพื่อเริ่มออเดอร์ใหม่ หรือกลับเข้าไปทำออเดอร์ที่ค้างอยู่"
          right={<Btn variant="ghost" onClick={() => setShowHistory(true)}><History size={14} /> ดูประวัติการยกเลิก</Btn>} />

        <div className="flex flex-wrap items-center gap-5 mb-5">
          {Object.entries(STATUS_STYLE).map(([k, v]) => (
            <label key={k} className="flex items-center gap-1.5 text-sm text-stone-600 cursor-pointer select-none">
              <input type="checkbox" checked={filters[k]} onChange={e => setFilters(prev => ({ ...prev, [k]: e.target.checked }))}
                style={{ accentColor: v.dot.includes("stone") ? "#a8a29e" : v.dot.includes("sky") ? "#0ea5e9" : v.dot.includes("amber") ? "#d97706" : "#10b981" }}
                className="w-4 h-4 rounded" />
              {v.label}
            </label>
          ))}
        </div>

        {zones.map(zone => (
          <Card key={zone} className="p-5 mb-5">
            <div className="flex items-center gap-2 mb-4">
              <span className="w-8 h-8 rounded-lg bg-stone-900 text-white flex items-center justify-center flex-shrink-0"><Armchair size={16} /></span>
              <span className="font-semibold text-stone-800">{zone}</span>
            </div>
            <div className={`grid ${tableGridColsClass} gap-3`}>
              {tables.filter(t => t.zone === zone && visibleTables(t)).map(t => {
                const s = STATUS_STYLE[t.status];
                return (
                  <button key={t.id} onClick={() => openTable(t)}
                    className={`p-4 rounded-lg border text-left transition-shadow hover:shadow-sm ${s.bg} ${s.border}`}>
                    <div className="font-semibold text-stone-800">โต๊ะ {t.id.replace(/^T/, "")}</div>
                    <div className={`text-xs font-medium mt-1 ${s.text}`}>{s.label}</div>
                    {t.status === "ordering" && t.guestCount && <div className="text-xs text-stone-500 mt-0.5">{t.guestCount} ท่าน</div>}
                    {t.status === "ordering" && !t.guestCount && t.channelName && <div className="text-xs text-stone-500 mt-0.5">{t.channelName}{t.fulfillment ? ` · ${t.fulfillment}` : ""}</div>}
                  </button>
                );
              })}
            </div>
          </Card>
        ))}

        {/* Channel selection popup */}
        {channelModal && (() => {
          const selectedCh = channelModal.channelId ? channels.find(c => c.id === channelModal.channelId) : null;

          function pressDigit(d) {
            setChannelModal(prev => ({ ...prev, guestCount: (prev.guestCount || "").length >= 3 ? prev.guestCount : (prev.guestCount || "") + d }));
          }
          function pressClear() {
            setChannelModal(prev => ({ ...prev, guestCount: "" }));
          }
          function pressBackspace() {
            setChannelModal(prev => ({ ...prev, guestCount: (prev.guestCount || "").slice(0, -1) }));
          }

          return (
            <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setChannelModal(null)}>
              <div className="bg-white rounded-xl w-full max-w-sm p-6" onClick={e => e.stopPropagation()}>
                {!selectedCh ? (
                  <>
                    <div className="flex items-center justify-between mb-1">
                      <div className="font-semibold text-stone-800 text-lg">เปิดออเดอร์ · โต๊ะ {channelModal.tableId.replace(/^T/, "")}</div>
                      <button onClick={() => setChannelModal(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
                    </div>
                    <div className="text-sm text-stone-500 text-center mb-4">เลือกช่องทางขาย</div>
                    <div className="space-y-3">
                      {channels.map(ch => (
                        <button key={ch.id} onClick={() => setChannelModal(prev => ({ ...prev, channelId: ch.id, fulfillment: null, guestCount: "" }))}
                          className={`w-full py-3.5 rounded-lg text-base font-semibold transition-all ${CHANNEL_SOLID_COLOR[ch.color] || CHANNEL_SOLID_COLOR.stone}`}>
                          {ch.name}
                        </button>
                      ))}
                    </div>
                  </>
                ) : (
                  <>
                    <div className="flex items-center justify-between mb-4">
                      <button onClick={() => setChannelModal(prev => ({ ...prev, channelId: null, fulfillment: null, guestCount: "" }))} className="text-stone-400 hover:text-stone-600 flex items-center gap-1 text-sm">
                        <ChevronLeft size={16} /> ย้อนกลับ
                      </button>
                      <button onClick={() => setChannelModal(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
                    </div>
                    <div className="font-semibold text-stone-800 text-lg text-center mb-4">{selectedCh.name}</div>

                    {(selectedCh.fulfillmentOptions || []).length > 0 && (
                      <div className={`grid gap-2 mb-4 ${selectedCh.fulfillmentOptions.length === 2 ? "grid-cols-2" : "grid-cols-1"}`}>
                        {selectedCh.fulfillmentOptions.map(opt => (
                          <button key={opt} onClick={() => setChannelModal(prev => ({ ...prev, fulfillment: opt }))}
                            className={`py-3 rounded-lg text-sm font-semibold border transition-colors
                            ${channelModal.fulfillment === opt ? "bg-blue-950 text-white border-blue-950" : "bg-white border-stone-300 text-stone-600 hover:border-stone-400"}`}>
                            {opt}
                          </button>
                        ))}
                      </div>
                    )}

                    {selectedCh.name === "หน้าร้าน" && (
                      <>
                        <div className="flex items-center justify-between mb-3">
                          <div className="text-sm font-medium text-stone-700">ระบุจำนวนคน</div>
                          <input
                            className="w-24 py-2 rounded-lg border border-stone-300 bg-stone-50 text-center font-mono text-lg text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400"
                            value={channelModal.guestCount}
                            onChange={e => setChannelModal(prev => ({ ...prev, guestCount: e.target.value.replace(/\D/g, "").slice(0, 3) }))}
                            placeholder="เช่น 2"
                            inputMode="numeric"
                          />
                        </div>
                        <div className="grid grid-cols-3 gap-2 mb-4">
                          {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map(d => (
                            <button key={d} onClick={() => pressDigit(d)}
                              className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-xl font-semibold text-stone-800 transition-colors">
                              {d}
                            </button>
                          ))}
                          <button onClick={pressClear} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-lg font-semibold text-stone-500 transition-colors">C</button>
                          <button onClick={() => pressDigit("0")} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-xl font-semibold text-stone-800 transition-colors">0</button>
                          <button onClick={pressBackspace} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-stone-500 flex items-center justify-center transition-colors">
                            <ChevronLeft size={20} />
                          </button>
                        </div>
                      </>
                    )}

                    <Btn className="w-full justify-center" disabled={!channelModalReady()} onClick={confirmChannel}>เริ่มออเดอร์</Btn>
                  </>
                )}
              </div>
            </div>
          );
        })()}

        {/* Cancellation history popup */}
        {showHistory && (
          <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowHistory(false)}>
            <div className="min-h-full flex items-start justify-center py-8">
            <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800">ประวัติการยกเลิก</div>
                <button onClick={() => setShowHistory(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>
              <div className="space-y-2">
                {cancelHistory.filter(h => !h.branchId || h.branchId === currentBranchId).map(h => (
                  <div key={h.id} className="p-3 rounded-lg border border-stone-200">
                    <div className="flex justify-between text-sm">
                      <span className="font-medium text-stone-800">โต๊ะ {h.table} · {h.item}</span>
                      <span className="text-xs text-stone-400">{h.time}</span>
                    </div>
                    <div className="text-xs text-stone-500 mt-1">เหตุผล: {h.reason} · โดย {h.by}{h.approvedBy && <span> · อนุมัติโดย {h.approvedBy}</span>}{h.billNo && <span> · เลขที่บิล {h.billNo}</span>}</div>
                  </div>
                ))}
              </div>
            </div>
            </div>
          </div>
        )}
      </div>
    );
  }

  /* ===================== ORDER / MENU VIEW ===================== */
  return (
    <div>
      <div className="flex items-center gap-3 mb-1">
        <button onClick={() => setView("tables")} className="text-stone-400 hover:text-stone-600 flex items-center gap-1 text-sm">
          <ChevronLeft size={16} /> กลับไปเลือกโต๊ะ
        </button>
      </div>
      <PageHeader eyebrow="หน้าร้าน" title={`POS Order · โต๊ะ ${currentTableId?.replace(/^T/, "")}${currentTable ? ` (นั่งได้ ${currentTable.seats} ที่นั่ง)` : ""}`}
        subtitle={`${channel?.name || ""}${session?.fulfillment ? ` · ${session.fulfillment}` : ""}${isDineIn && session?.guestCount ? ` · ${session.guestCount} ท่าน` : ""}`}
        right={<Btn variant="ghost" onClick={() => setShowQrPrint(true)}><QrCode size={14} /> พิมพ์ QR Code</Btn>} />
      <div className={`grid ${isWideScreen ? "grid-cols-12" : "grid-cols-1"} gap-5`}>
        <div className={isWideScreen ? "col-span-8" : ""}>
          <div className="flex gap-2 mb-4 overflow-x-auto pb-1">
            {(bundlePromotions.length > 0 || mixMatchPromotions.length > 0) && (
              <button onClick={() => setActiveCat("__promo__")}
                className={`px-4 py-2 rounded-full text-sm font-medium whitespace-nowrap flex-shrink-0 transition-colors flex items-center gap-1.5
                ${activeCat === "__promo__" ? "bg-amber-600 text-white" : "bg-amber-50 border border-amber-200 text-amber-700 hover:border-amber-300"}`}>
                <Sparkles size={13} /> โปรโมชั่น
              </button>
            )}
            {categories.map(c => (
              <button key={c.id} onClick={() => setActiveCat(c.id)}
                className={`px-4 py-2 rounded-full text-sm font-medium whitespace-nowrap flex-shrink-0 transition-colors
                ${activeCat === c.id ? "bg-stone-900 text-white" : "bg-white border border-stone-200 text-stone-600 hover:border-stone-300"}`}>
                {c.name}
              </button>
            ))}
          </div>

          {activeCat === "__promo__" ? (
            <div className="grid grid-cols-2 lg:grid-cols-3 gap-3">
              {bundlePromotions.map(promo => {
                const requiredIds = [...promo.bundle.foodItemIds, ...promo.bundle.drinkItemIds];
                const requiredNames = requiredIds.map(id => menu.find(m => m.id === id)?.name).filter(Boolean);
                const setPrice = promo.bundle.promoMode === "fixed" ? promo.bundle.promoPrice : Math.round(promo.bundle.fullPrice * (1 - promo.bundle.promoPercent / 100));
                return (
                  <button key={promo.id} onClick={() => addBundleToCart(promo)}
                    className="text-left p-3.5 rounded-lg border border-amber-200 bg-amber-50 hover:border-amber-400 hover:shadow-sm transition-all">
                    <div className="flex items-center gap-1.5 text-amber-700 mb-1"><Gift size={15} /><span className="font-semibold text-sm">{promo.name}</span></div>
                    <div className="text-xs text-stone-500 space-y-0.5 mb-2">
                      {requiredNames.map((n, i) => <div key={i}>• {n}</div>)}
                    </div>
                    <div className="flex items-center gap-2">
                      <span className="font-mono text-amber-700 font-semibold">฿{fmtMoney(setPrice)}</span>
                      <span className="text-xs text-stone-400 line-through">฿{fmtMoney(promo.bundle.fullPrice)}</span>
                    </div>
                  </button>
                );
              })}
              {mixMatchPromotions.map(promo => {
                const eligibleNames = promo.mixMatch.itemIds.map(id => menu.find(m => m.id === id)?.name).filter(Boolean);
                return (
                  <button key={promo.id} onClick={() => setMixMatchPicker({ promo, selectedIds: [] })}
                    className="text-left p-3.5 rounded-lg border border-sky-200 bg-sky-50 hover:border-sky-400 hover:shadow-sm transition-all">
                    <div className="flex items-center gap-1.5 text-sky-700 mb-1"><LayoutGrid size={15} /><span className="font-semibold text-sm">{promo.name}</span></div>
                    <div className="text-xs text-stone-500 mb-2">เลือก {promo.mixMatch.chooseCount} จาก {eligibleNames.length} เมนู</div>
                    <div className="flex flex-wrap gap-1 mb-2">
                      {eligibleNames.map((n, i) => <span key={i} className="text-[10px] px-1.5 py-0.5 rounded bg-white text-stone-500 border border-stone-200">{n}</span>)}
                    </div>
                    <span className="font-mono text-sky-700 font-semibold">฿{fmtMoney(promo.mixMatch.price)}</span>
                    <span className="text-xs text-stone-400"> ต่อชุด</span>
                  </button>
                );
              })}
            </div>
          ) : (
            <div className={`grid ${isWideScreen ? "grid-cols-5" : "grid-cols-2"} gap-3`}>
              {items.map(item => (
                <button key={item.id} onClick={() => openPicker(item)}
                  className="text-left rounded-lg border border-stone-200 bg-white hover:border-amber-400 hover:shadow-sm transition-all overflow-hidden">
                  <div className="aspect-square w-full bg-stone-100 flex items-center justify-center overflow-hidden">
                    {item.imageDataUrl ? (
                      <img src={item.imageDataUrl} alt={item.name} className="w-full h-full object-cover" />
                    ) : (
                      <UtensilsCrossed size={24} className="text-stone-300" />
                    )}
                  </div>
                  <div className="p-2.5">
                    <div className="font-medium text-stone-800 text-sm truncate">{item.name}</div>
                    <div className="flex items-center justify-between mt-1">
                      <span className="font-mono text-amber-700 font-semibold text-sm">฿{fmtMoney(priceForChannel(item))}</span>
                      {(item.optionGroups || []).length > 0 && <span className="text-[9px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200 flex-shrink-0">ตัวเลือก</span>}
                    </div>
                  </div>
                </button>
              ))}
            </div>
          )}
        </div>

        {/* Cart / receipt ticket — inline side panel on wide screens; a
            full-screen overlay toggled from a floating side tab on mobile
            (see the tab button below) */}
        <div className={isWideScreen ? "col-span-4" : (cartExpanded ? "fixed inset-0 z-50 bg-white p-4 overflow-y-auto" : "hidden")}>
          {!isWideScreen && (
            <div className="flex items-center justify-between mb-3">
              <div className="font-semibold text-stone-800">ตะกร้า</div>
              <button onClick={() => setCartExpanded(false)} className="w-8 h-8 flex items-center justify-center rounded-lg text-stone-400 hover:bg-stone-100 hover:text-stone-600"><X size={18} /></button>
            </div>
          )}
          <Card className="p-4">
            <div className="flex items-center justify-between border-b border-stone-200 pb-3 mb-3">
              <div className="min-w-0">
                <div className="font-semibold text-stone-800 truncate">โต๊ะ {currentTableId?.replace(/^T/, "")}{currentTable && <span className="text-stone-400 font-normal text-xs"> (นั่งได้ {currentTable.seats} ที่นั่ง)</span>}</div>
                <div className="text-xs text-stone-400 truncate">{channel?.name}{session?.fulfillment ? ` · ${session.fulfillment}` : ""}{isDineIn && session?.guestCount ? ` · ${session.guestCount} ท่าน` : ""}</div>
              </div>
              <span className="text-xs text-stone-400 flex-shrink-0">{cart.length} รายการ</span>
            </div>

            {cart.length === 0 ? (
              <div className="text-center text-stone-400 text-sm py-10">ยังไม่มีรายการ — แตะเมนูเพื่อเพิ่ม</div>
            ) : (
              <div className="space-y-3 max-h-72 overflow-y-auto pr-1">
                {cart.map(c => (
                  <div key={c.cartLineId} className="flex items-start justify-between text-sm gap-2">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-baseline justify-between gap-2">
                        <span className="text-stone-800 font-medium truncate">{c.name} <span className="text-stone-400 font-normal">x{c.qty}</span></span>
                        <span className="font-mono text-stone-800 font-medium flex-shrink-0">฿{fmtMoney(c.unitPrice * c.qty)}</span>
                      </div>
                      {c.optionSummary.map((opt, oi) => (
                        <div key={oi} className="text-[11px] text-stone-400">• {opt}</div>
                      ))}
                      {c.note && <div className="text-[11px] text-rose-500 italic truncate">หมายเหตุ: {c.note}</div>}
                    </div>
                    <div className="flex items-center gap-1 flex-shrink-0">
                      <button onClick={() => editCartLine(c)} className="w-6 h-6 flex items-center justify-center rounded border border-stone-300 text-stone-500 hover:bg-stone-50"><Pencil size={12} /></button>
                      <button onClick={() => changeQty(c.cartLineId, -1)} className="w-6 h-6 flex items-center justify-center rounded border border-stone-300 text-stone-500 hover:bg-stone-50"><Minus size={12} /></button>
                      <button onClick={() => changeQty(c.cartLineId, 1)} className="w-6 h-6 flex items-center justify-center rounded border border-stone-300 text-stone-500 hover:bg-stone-50"><Plus size={12} /></button>
                    </div>
                  </div>
                ))}
              </div>
            )}

            {(() => {
              const liveSubtotal = (session?.billTotal || 0) + total;
              const afterDiscountSubtotal = Math.max(0, liveSubtotal - (linkedMember ? effectiveBirthdayDiscountAmount : 0) - promoDiscountAmount - rewardDiscountAmount);
              const preview = computeBill(afterDiscountSubtotal);
              const totalDiscount = liveSubtotal - afterDiscountSubtotal;
              return (
                <div className="border-t border-dashed border-stone-300 mt-3 pt-3 space-y-1 text-sm">
                  <div className="flex items-center justify-between">
                    <span className="text-stone-500">รวมรอบนี้</span>
                    <span className="font-mono text-stone-700">฿{fmtMoney(total)}</span>
                  </div>
                  {session?.billTotal > 0 && (
                    <div className="flex items-center justify-between text-xs text-stone-400">
                      <span>ยอดที่ส่งครัวไปแล้ว</span>
                      <span className="font-mono">฿{fmtMoney(session.billTotal)}</span>
                    </div>
                  )}
                  {linkedMember && birthdayDiscountActive && appliedPromos.length === 0 && (
                    <div className="flex items-center justify-between text-xs text-rose-500">
                      <span>🎂 ส่วนลดวันเกิด</span>
                      <span className="font-mono">-฿{fmtMoney(birthdayDiscountAmount)}</span>
                    </div>
                  )}
                  {linkedMember && birthdayDiscountActive && appliedPromos.length > 0 && (
                    <div className="text-[11px] text-stone-400">🎂 ส่วนลดวันเกิด ใช้ร่วมกับโปรโมชั่นไม่ได้ (ยังไม่ถูกใช้)</div>
                  )}
                  {promoEvaluations.filter(e => e.discountAmount > 0).map(e => (
                    <div key={e.promo.id} className="flex items-center justify-between text-xs text-rose-500">
                      <span>🏷️ {e.promo.name}</span>
                      <span className="font-mono">-฿{fmtMoney(e.discountAmount)}</span>
                    </div>
                  ))}
                  {redeemedRewardEvaluations.map((e, i) => (
                    <div key={i} className="flex items-center justify-between text-xs text-rose-500">
                      <span>🎁 {e.reward.name}</span>
                      <span className="font-mono">-฿{fmtMoney(e.discountAmount)}</span>
                    </div>
                  ))}
                  {totalDiscount > 0 && (
                    <div className="flex items-center justify-between font-medium">
                      <span className="text-stone-600">ราคาหลังหักส่วนลด</span>
                      <span className="font-mono text-stone-800">฿{fmtMoney(afterDiscountSubtotal)}</span>
                    </div>
                  )}
                  {paymentSettings.serviceCharge.enabled && (
                    <div className="flex items-center justify-between text-xs text-stone-400">
                      <span>ค่าบริการ ({paymentSettings.serviceCharge.rate}%)</span>
                      <span className="font-mono">฿{fmtMoney(preview.serviceChargeAmt)}</span>
                    </div>
                  )}
                  {paymentSettings.vat.enabled && (
                    <div className="flex items-center justify-between text-xs text-stone-400">
                      <span>VAT ({paymentSettings.vat.rate}%)</span>
                      <span className="font-mono">฿{fmtMoney(preview.vatAmt)}</span>
                    </div>
                  )}
                </div>
              );
            })()}

            <Btn className="w-full justify-center mt-3" disabled={cart.length === 0} onClick={sendToKitchen}>
              <Flame size={15} /> ส่งออเดอร์เข้าครัว
            </Btn>
            {sent && <div className="text-center text-emerald-600 text-xs mt-2">ส่งออเดอร์ไปยังครัวเรียบร้อย ✓</div>}

            {appliedPromos.length > 0 && (
              <div className="mt-2 space-y-2">
                {promoEvaluations.map(e => (
                  <div key={e.promo.id} className="p-2.5 rounded-lg bg-stone-100 border border-stone-200">
                    <div className="flex items-center justify-between">
                      <div className="text-xs font-medium text-stone-700 truncate">🏷️ {e.promo.name}</div>
                      <button onClick={() => removePromoId(e.promo.id)} className="text-stone-400 hover:text-rose-500 flex-shrink-0"><X size={13} /></button>
                    </div>
                    {e.conditionUnmet && (
                      <div className="mt-1">
                        <div className="text-[11px] text-amber-600">ยังไม่ครบเงื่อนไขของโปรโมชั่นนี้ — ยังไม่ได้รับส่วนลด/สิทธิ์</div>
                        {e.eligibleItems.length > 0 && (
                          <div className="mt-1.5 flex flex-wrap gap-1">
                            {e.eligibleItems.map(m => (
                              <span key={m.id} className={`text-[10px] px-1.5 py-0.5 rounded border ${m.inCart ? "bg-emerald-50 text-emerald-700 border-emerald-200" : "bg-white text-stone-500 border-stone-200"}`}>
                                {m.inCart && "✓ "}{m.name}
                              </span>
                            ))}
                          </div>
                        )}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}
            <Btn variant={appliedPromos.length > 0 ? "ghost" : "primary"} className="w-full justify-center mt-2" onClick={() => setShowPromoModal(true)}>
              <Sparkles size={14} /> {appliedPromos.length > 0 ? "เพิ่ม/แก้ไขโปรโมชั่น" : "โปรโมชั่น"}
            </Btn>

            {linkedMember ? (
              <div className="mt-2 p-2.5 rounded-lg bg-amber-50 border border-amber-200">
                <div className="flex items-center justify-between">
                  <div className="text-xs font-medium text-stone-700">{linkedMember.name} <span className="text-stone-400 font-normal">· {linkedMember.tier}</span></div>
                  <div className="flex items-center gap-2 flex-shrink-0">
                    <button onClick={() => setViewingMemberProfile(true)} className="text-stone-400 hover:text-amber-700" title="ดูข้อมูลสมาชิก"><Eye size={13} /></button>
                    <button onClick={unlinkMember} className="text-stone-400 hover:text-rose-500"><X size={13} /></button>
                  </div>
                </div>
                {birthdayDiscountActive && appliedPromos.length === 0 && (
                  <div className="flex items-center justify-between text-xs text-rose-500 mt-1">
                    <span>🎂 ส่วนลดวันเกิด {linkedTier.birthdayDiscount.percent}%</span>
                    <span className="font-mono">-฿{fmtMoney(birthdayDiscountAmount)}</span>
                  </div>
                )}
                {birthdayDiscountActive && appliedPromos.length > 0 && (
                  <div className="text-[11px] text-stone-400 mt-1">🎂 ส่วนลดวันเกิดใช้ร่วมกับโปรโมชั่นไม่ได้</div>
                )}
                <div className="flex items-center justify-between text-xs text-emerald-600 mt-1">
                  <span>แต้มที่จะได้รับ{pointsMultiplier > 1 ? ` (x${pointsMultiplier.toFixed(2).replace(/\.00$/, "")})` : ""}</span>
                  <span className="font-mono">+{pointsEarned} แต้ม</span>
                </div>
                {redeemedRewardEvaluations.map((e, i) => (
                  <div key={i} className="flex items-center justify-between text-xs text-rose-500 mt-1">
                    <span className="truncate">🎁 {e.reward.name}{session?.redeemedViaCode?.[i] && <span className="text-stone-400"> (จากรหัสลูกค้า)</span>}</span>
                    <span className="flex items-center gap-1.5 flex-shrink-0">
                      <span className="font-mono">-฿{fmtMoney(e.discountAmount)}</span>
                      <button onClick={() => removeRedeemedReward(i)} className="text-stone-400 hover:text-rose-500"><X size={12} /></button>
                    </span>
                  </div>
                ))}
              </div>
            ) : (
              <Btn variant="ghost" className="w-full justify-center mt-2" onClick={() => setShowMemberModal(true)}>
                <Users size={14} /> สมาชิก
              </Btn>
            )}
            {linkedMember && (
              <Btn variant="ghost" className="w-full justify-center mt-2" onClick={() => setShowRedeemModal(true)}>
                <Gift size={14} /> แลกรางวัล
              </Btn>
            )}

            {session?.sentItems?.length > 0 && (
              <Btn variant="ghost" className="w-full justify-center mt-2" onClick={() => setShowEditOrder(true)}>
                <Pencil size={14} /> แก้ไขออเดอร์
              </Btn>
            )}

            {(() => {
              const liveSubtotal = (session?.billTotal || 0) + total;
              const preview = computeBill(Math.max(0, liveSubtotal - (linkedMember ? effectiveBirthdayDiscountAmount : 0) - promoDiscountAmount - rewardDiscountAmount));
              const canPay = cart.length === 0 && session?.billTotal > 0;
              return (
                <>
                  <button
                    disabled={!canPay}
                    onClick={() => { setPaymentMethodId(null); setSplitPayments([]); setIsSplitMode(false); setCashReceived(""); setShowPayment(true); }}
                    className="w-full flex items-center justify-between mt-3 px-4 py-3.5 rounded-xl bg-amber-600 hover:bg-amber-700 disabled:bg-stone-300 disabled:cursor-not-allowed text-white font-semibold transition-colors">
                    <span className="flex items-center gap-2"><CreditCard size={17} /> ชำระเงิน</span>
                    <span className="font-mono text-lg">฿{fmtMoney(preview.grand)}</span>
                  </button>
                  {cart.length > 0 && <div className="text-center text-stone-400 text-[11px] mt-1.5">ส่งออเดอร์ที่ค้างอยู่เข้าครัวก่อน จึงจะปิดโต๊ะได้</div>}
                </>
              );
            })()}
          </Card>
        </div>

        {/* Mobile-only floating cart tab — tap to expand the cart full-screen (hidden once expanded, and never shown on wide screens where the cart sits inline) */}
        {!isWideScreen && !cartExpanded && (
          <button onClick={() => setCartExpanded(true)}
            className="fixed right-0 top-1/2 -translate-y-1/2 z-40 flex flex-col items-center gap-1 bg-stone-900 hover:bg-stone-800 text-white px-2.5 py-4 rounded-l-xl shadow-lg">
            <ShoppingCart size={18} />
            <span className="text-xs font-semibold">{cart.length}</span>
            <span className="text-[10px] font-mono">฿{fmtMoney((session?.billTotal || 0) + total)}</span>
          </button>
        )}
      </div>

      {/* Link member modal */}
      {showMemberModal && (() => {
        function pressDigit(d) {
          setMemberPhoneInput(prev => prev.length >= 10 ? prev : prev + d);
        }
        function pressClear() {
          setMemberPhoneInput("");
        }
        function pressBackspace() {
          setMemberPhoneInput(prev => prev.slice(0, -1));
        }
        const found = memberPhoneInput.trim() !== "" ? members.find(m => m.phone.replace(/-/g, "") === memberPhoneInput.replace(/-/g, "")) : null;

        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowMemberModal(false)}>
            <div className="bg-white rounded-xl w-full max-w-sm p-6" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-1">
                <div className="font-semibold text-stone-800 text-lg">ผูกบิลกับสมาชิก</div>
                <button onClick={() => setShowMemberModal(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>
              <div className="text-sm text-stone-500 text-center mb-3">ระบุเบอร์โทรสมาชิก</div>

              <input
                className="w-full py-2.5 rounded-lg border border-stone-300 bg-stone-50 text-center font-mono text-lg text-stone-800 mb-3 focus:outline-none focus:ring-2 focus:ring-amber-400"
                value={memberPhoneInput}
                onChange={e => setMemberPhoneInput(e.target.value.replace(/\D/g, "").slice(0, 10))}
                placeholder="08x-xxx-xxxx"
                inputMode="numeric"
                autoFocus
              />

              {memberPhoneInput.trim() !== "" && (
                found ? (
                  <div className="mb-3 p-3 rounded-lg border border-emerald-200 bg-emerald-50 text-sm">
                    <div className="font-medium text-stone-800">{found.name}</div>
                    <div className="text-xs text-stone-500 mt-0.5">{found.tier} · แต้มสะสม {found.points.toLocaleString()}</div>
                  </div>
                ) : (
                  <div className="mb-3 p-3 rounded-lg border border-stone-200 bg-stone-50 text-sm text-stone-400">ไม่พบสมาชิกด้วยเบอร์นี้</div>
                )
              )}

              <div className="grid grid-cols-3 gap-2 mb-4">
                {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map(d => (
                  <button key={d} onClick={() => pressDigit(d)}
                    className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-xl font-semibold text-stone-800 transition-colors">
                    {d}
                  </button>
                ))}
                <button onClick={pressClear} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-lg font-semibold text-stone-500 transition-colors">C</button>
                <button onClick={() => pressDigit("0")} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-xl font-semibold text-stone-800 transition-colors">0</button>
                <button onClick={pressBackspace} className="py-4 rounded-lg bg-stone-100 hover:bg-stone-200 text-stone-500 flex items-center justify-center transition-colors">
                  <ChevronLeft size={20} />
                </button>
              </div>

              <Btn className="w-full justify-center" disabled={!found} onClick={linkMember}>ยืนยัน</Btn>
            </div>
          </div>
        );
      })()}

      {/* Promotion selection modal */}
      {showPromoModal && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowPromoModal(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เลือกโปรโมชั่น (เลือกได้หลายรายการ)</div>
              <button onClick={() => setShowPromoModal(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            {activePromotions.filter(p => p.type !== "bundle" && p.type !== "mixMatch").length === 0 ? (
              <div className="text-sm text-stone-400 text-center py-8">ไม่มีโปรโมชั่นที่เปิดใช้งานอยู่ตอนนี้</div>
            ) : (
              <div className="space-y-2">
                {activePromotions.filter(p => p.type !== "bundle" && p.type !== "mixMatch").map(p => {
                  const selected = appliedPromoIds.includes(p.id);
                  return (
                    <button key={p.id} onClick={() => togglePromo(p.id)}
                      className={`w-full text-left p-3 rounded-lg border transition-all flex items-start gap-2.5 ${selected ? "border-amber-400 bg-amber-50" : "border-stone-200 hover:border-amber-300 hover:shadow-sm"}`}>
                      <span className={`w-4 h-4 rounded border flex-shrink-0 mt-0.5 flex items-center justify-center ${selected ? "bg-amber-600 border-amber-600" : "border-stone-300"}`}>
                        {selected && <Check size={11} className="text-white" />}
                      </span>
                      <div className="min-w-0">
                        <div className="font-medium text-stone-800 text-sm">{p.name}</div>
                        <div className="text-xs text-stone-400 mt-0.5">{promoSummary(p)}</div>
                      </div>
                    </button>
                  );
                })}
              </div>
            )}
            <p className="text-[11px] text-stone-400 mt-3">
              ระบบคำนวณส่วนลด/สิทธิ์ให้อัตโนมัติตามเงื่อนไขของแต่ละโปรโมชั่น (ยอดเงินขั้นต่ำ, Happy Hour, สะสมแต้ม) หากตะกร้ายังไม่ตรงเงื่อนไข ระบบจะไม่หักส่วนลดให้จนกว่าจะครบตามที่กำหนด — ส่วนโปรโมชั่น Meal Bundle และ Mix and Match ให้เลือกจากแท็บ "โปรโมชั่น" ในเมนูอาหารแทน
            </p>
            <Btn className="w-full justify-center mt-3" onClick={() => setShowPromoModal(false)}>เสร็จสิ้น</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Member profile modal */}
      {viewingMemberProfile && linkedMember && (
        <MemberProfileModal member={linkedMember} members={members} setMembers={setMembers} tiers={tiers} history={history} orderHistory={orderHistory} onClose={() => setViewingMemberProfile(false)} logActivity={logActivity} />
      )}

      {/* Redeem reward modal */}
      {showRedeemModal && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowRedeemModal(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">แลกรางวัล</div>
              <button onClick={() => setShowRedeemModal(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            {linkedMember && <div className="text-xs text-stone-400 mb-3">{linkedMember.name} · แต้มคงเหลือ {linkedMember.points.toLocaleString()} แต้ม</div>}

            <div className="p-3 rounded-lg bg-amber-50 border border-amber-200 mb-3">
              <div className="text-xs font-medium text-amber-800 mb-1.5">มีรหัสแลกของรางวัลจากลูกค้า? (แลกเองผ่าน LINE)</div>
              <div className="flex gap-2">
                <input className={`${inputCls} flex-1 font-mono uppercase`} value={redemptionCodeInput}
                  onChange={e => { setRedemptionCodeInput(e.target.value.toUpperCase()); setRedemptionCodeError(""); setRedemptionCodeSuccess(""); }}
                  placeholder="เช่น RD123456" maxLength={10} />
                <Btn variant="ghost" onClick={() => {
                  const result = applyRedemptionCode(redemptionCodeInput);
                  if (result.ok) { setRedemptionCodeSuccess(`ใช้รหัสสำเร็จ! เพิ่ม "${result.rewardName}" ในบิลแล้ว`); setRedemptionCodeInput(""); }
                  else setRedemptionCodeError(result.error);
                }}>ใช้รหัส</Btn>
              </div>
              {redemptionCodeError && <div className="text-xs text-rose-600 mt-1.5">{redemptionCodeError}</div>}
              {redemptionCodeSuccess && <div className="text-xs text-emerald-600 mt-1.5">{redemptionCodeSuccess}</div>}
            </div>

            {eligibleRewards.length === 0 ? (
              <div className="text-sm text-stone-400 text-center py-8">ยังไม่มีของรางวัลที่แลกได้ตอนนี้ (แต้มไม่พอ หรือหมดสิทธิ์แล้ว)</div>
            ) : (
              <div className="space-y-2">
                {eligibleRewards.map(r => {
                  const typeInfo = REWARD_TYPES.find(t => t.key === r.type) || REWARD_TYPES[0];
                  const detail = r.type === "food" ? `แลกได้: ${menu.find(m => m.id === r.food.itemId)?.name || "-"}`
                    : r.type === "discount" ? (r.discount.mode === "percent" ? `รับส่วนลด ${r.discount.value}%` : `รับส่วนลด ฿${r.discount.value}`)
                    : `ของรางวัล: ${r.prize.itemName || "-"}`;
                  return (
                    <div key={r.id} className="flex items-center justify-between gap-3 p-3 rounded-lg border border-stone-200">
                      <div className="min-w-0 flex items-start gap-2">
                        <typeInfo.icon size={16} className="text-amber-600 flex-shrink-0 mt-0.5" />
                        <div className="min-w-0">
                          <div className="font-medium text-stone-800 text-sm truncate">{r.name}</div>
                          <div className="text-xs text-stone-400">{detail}</div>
                          <div className="text-xs font-mono text-amber-700 mt-0.5">{r.points} แต้ม</div>
                        </div>
                      </div>
                      <Btn variant="subtle" onClick={() => redeemReward(r)}>แลก</Btn>
                    </div>
                  );
                })}
              </div>
            )}
            <Btn className="w-full justify-center mt-4" onClick={() => setShowRedeemModal(false)}>เสร็จสิ้น</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Mix and Match item picker modal */}
      {mixMatchPicker && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setMixMatchPicker(null)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">{mixMatchPicker.promo.name}</div>
              <button onClick={() => setMixMatchPicker(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-3">
              เลือก {mixMatchPicker.promo.mixMatch.chooseCount} เมนู ในราคา ฿{fmtMoney(mixMatchPicker.promo.mixMatch.price)} ({mixMatchPicker.selectedIds.length}/{mixMatchPicker.promo.mixMatch.chooseCount})
            </div>
            <div className="space-y-1.5 max-h-72 overflow-y-auto pr-1">
              {mixMatchPicker.promo.mixMatch.itemIds.map(id => {
                const item = menu.find(m => m.id === id);
                if (!item) return null;
                const selected = mixMatchPicker.selectedIds.includes(id);
                const atLimit = mixMatchPicker.selectedIds.length >= mixMatchPicker.promo.mixMatch.chooseCount;
                return (
                  <button key={id} disabled={!selected && atLimit}
                    onClick={() => setMixMatchPicker(prev => ({
                      ...prev,
                      selectedIds: selected ? prev.selectedIds.filter(x => x !== id) : [...prev.selectedIds, id],
                    }))}
                    className={`w-full flex items-center justify-between px-3 py-2 rounded-lg border text-sm transition-colors
                    ${selected ? "border-sky-400 bg-sky-50" : "border-stone-200 hover:border-stone-300 disabled:opacity-40 disabled:hover:border-stone-200"}`}>
                    <span className="flex items-center gap-2">
                      <span className={`w-4 h-4 rounded border flex-shrink-0 flex items-center justify-center ${selected ? "bg-sky-600 border-sky-600" : "border-stone-300"}`}>
                        {selected && <Check size={11} className="text-white" />}
                      </span>
                      {item.name}
                    </span>
                    <span className="text-xs text-stone-400 font-mono">฿{fmtMoney(priceForChannel(item))}</span>
                  </button>
                );
              })}
            </div>
            <Btn className="w-full justify-center mt-4"
              disabled={mixMatchPicker.selectedIds.length !== mixMatchPicker.promo.mixMatch.chooseCount}
              onClick={() => { addMixMatchToCart(mixMatchPicker.promo, mixMatchPicker.selectedIds); setMixMatchPicker(null); }}>
              <Plus size={14} /> เพิ่มลงตะกร้า
            </Btn>
          </div>
          </div>
        </div>
      )}

      {/* Edit sent order modal */}
      {showEditOrder && session && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowEditOrder(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขออเดอร์ที่ส่งครัวแล้ว</div>
              <button onClick={() => setShowEditOrder(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <p className="text-xs text-stone-400 mb-3">ใช้สำหรับแก้ไขกรณีสั่งผิดหรือลูกค้าขอเปลี่ยนแปลง รายการที่ลบจะไม่ถูกส่งเข้าครัวซ้ำ</p>
            <div className="space-y-2">
              {session.sentItems.length === 0 && <div className="text-sm text-stone-400 text-center py-6">ไม่มีรายการที่ส่งครัวแล้ว</div>}
              {session.sentItems.map(it => (
                <div key={it.cartLineId} className="flex items-center justify-between text-sm p-2.5 rounded-lg border border-stone-200">
                  <div className="flex-1 min-w-0">
                    <div className="text-stone-700">{it.name}</div>
                    {it.optionSummary?.length > 0 && <div className="text-[11px] text-sky-700 truncate">{it.optionSummary.join(", ")}</div>}
                    <div className="text-xs text-stone-400 font-mono">฿{fmtMoney(it.unitPrice)} x {it.qty}</div>
                  </div>
                  <div className="flex items-center gap-1 flex-shrink-0">
                    <button onClick={() => requestVoidApproval(`${it.name} x1`, () => editSentItemQty(it.cartLineId, -1))} className="w-6 h-6 flex items-center justify-center rounded border border-stone-300 text-stone-500 hover:bg-stone-50"><Minus size={12} /></button>
                    <span className="w-5 text-center font-mono">{it.qty}</span>
                    <button onClick={() => editSentItemQty(it.cartLineId, 1)} className="w-6 h-6 flex items-center justify-center rounded border border-stone-300 text-stone-500 hover:bg-stone-50"><Plus size={12} /></button>
                    <button onClick={() => requestVoidApproval(`${it.name} (ทั้งรายการ x${it.qty})`, () => removeSentItem(it.cartLineId))} className="text-stone-300 hover:text-rose-500 ml-1"><Trash2 size={14} /></button>
                  </div>
                </div>
              ))}
            </div>
            <div className="flex items-center justify-between mt-3 pt-3 border-t border-stone-200">
              <span className="text-sm text-stone-500">ยอดที่ส่งครัวไปแล้ว</span>
              <span className="font-mono font-semibold text-stone-900">฿{fmtMoney(session.billTotal)}</span>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={() => setShowEditOrder(false)}>เสร็จสิ้น</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Void / cancel approval modal (requires a manager PIN) */}
      {voidApproval && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setVoidApproval(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 flex items-center gap-2"><ShieldCheck size={17} className="text-amber-600" /> ขออนุมัติยกเลิกรายการ</div>
              <button onClick={() => setVoidApproval(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-500 mt-2 mb-4">{voidApproval.itemName}</div>

            <Field label="เหตุผลที่ยกเลิก">
              <input className={inputCls} value={voidApproval.reason} onChange={e => setVoidApproval(prev => ({ ...prev, reason: e.target.value }))} placeholder="เช่น ลูกค้าสั่งผิด, ครัวทำผิด" autoFocus />
            </Field>
            <div className="mt-3">
              <Field label="PIN ผู้จัดการ (6 หลัก)">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls} value={voidApproval.pin}
                  onChange={e => setVoidApproval(prev => ({ ...prev, pin: e.target.value.replace(/\D/g, "").slice(0, 6), error: "" }))}
                  placeholder="••••••" />
              </Field>
              {voidApproval.error && <div className="text-xs text-rose-500 mt-1.5">{voidApproval.error}</div>}
            </div>

            <Btn className="w-full justify-center mt-4" disabled={voidApproval.pin.length !== 6} onClick={confirmVoidApproval}>ยืนยันการยกเลิก</Btn>
          </div>
        </div>
      )}

      {/* Hidden print templates for tickets just sent to the kitchen (auto-print) */}
      {autoPrintTickets.map(t => (
        <div key={t.id} className="print-receipt font-mono text-xs text-black">
          <div style={{ textAlign: "center", fontWeight: 700, fontSize: 14 }}>#{t.id} · โต๊ะ {t.table?.replace(/^T/, "")}</div>
          <div style={{ textAlign: "center", fontSize: 10, color: "#666" }}>{t.kitchenLabel} · {t.time}</div>
          <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
          {t.items.map((it, i) => (
            <div key={i} style={{ marginBottom: 4 }}>
              <div style={{ fontWeight: 700 }}>· {it.name} x{it.qty}</div>
              {it.options && it.options.length > 0 && it.options.map((opt, oi) => (
                <div key={oi} style={{ paddingLeft: 10 }}>— {opt}</div>
              ))}
              {it.note && <div style={{ paddingLeft: 10, fontStyle: "italic" }}>หมายเหตุ: {it.note}</div>}
            </div>
          ))}
        </div>
      ))}

      {/* Payment / close table modal */}
      {showPayment && session && (() => {
        const discountedSubtotal = Math.max(0, (session.billTotal || 0) - (linkedMember ? effectiveBirthdayDiscountAmount : 0) - promoDiscountAmount - rewardDiscountAmount);
        const bill = computeBill(discountedSubtotal);
        const enabledMethods = payableFinanceAccounts(financeAccounts)
          .filter(a => (paymentSettings.enabledFinanceAccountIds || []).includes(a.id))
          .filter(a => !a.ourBranchId || a.ourBranchId === currentBranchId);
        const selectedMethod = enabledMethods.find(m => m.id === paymentMethodId) || null;
        const received = Number(cashReceived) || 0;
        const change = received - bill.grand;
        const phoneMatch = memberPhoneInput.trim() !== "" ? members.find(m => m.phone.replace(/-/g, "") === memberPhoneInput.replace(/-/g, "")) : null;

        // Split payment (pay one bill using more than one method, e.g. ครึ่งเงินสด/ครึ่งพร้อมเพย์).
        const splitTotal = Math.round(splitPayments.reduce((s, p) => s + (Number(p.amount) || 0), 0) * 100) / 100;
        const splitRemaining = Math.round((bill.grand - splitTotal) * 100) / 100;
        const canConfirm = isSplitMode
          ? splitPayments.length > 0 && splitRemaining <= 0
          : !!selectedMethod && (selectedMethod.type !== "pettyCash" || received >= bill.grand);
        function addSplitMethod(methodId) {
          const already = splitPayments.find(p => p.methodId === methodId);
          if (already) return; // one line per method — adjust the amount instead of duplicating
          const remaining = Math.max(0, Math.round((bill.grand - splitTotal) * 100) / 100);
          setSplitPayments(prev => [...prev, { id: "sp" + Date.now(), methodId, amount: remaining > 0 ? String(remaining) : "" }]);
        }
        function updateSplitAmount(id, value) {
          setSplitPayments(prev => prev.map(p => p.id === id ? { ...p, amount: value } : p));
        }
        function removeSplitMethod(id) {
          setSplitPayments(prev => prev.filter(p => p.id !== id));
        }

        // Mirrors the printed .print-receipt template above (same content,
        // rendered as ESC/POS blocks instead of HTML) — used by the print
        // agent, which can't render arbitrary HTML/images, only these blocks.
        function buildReceiptDoc() {
          const branch = branches?.find(b => b.id === currentBranchId);
          const receiptName = branch?.companyName || storeInfo.companyName || storeInfo.name;
          const receiptAddress = branch?.companyAddress || storeInfo.address;
          const receiptTaxId = branch?.taxId || storeInfo.taxId;
          const receiptPhone = branch?.phone || storeInfo.phone;
          const receiptOfficeType = branch?.officeType || storeInfo.officeType;
          const blocks = [];
          blocks.push({ type: "text", value: receiptName, align: "center", bold: true, size: "wide" });
          if (slipSettings.receipt.headerText) blocks.push({ type: "text", value: slipSettings.receipt.headerText, align: "center" });
          if (receiptAddress) blocks.push({ type: "text", value: receiptAddress, align: "center" });
          if (receiptTaxId) blocks.push({ type: "text", value: `TAX ID: ${receiptTaxId}${receiptOfficeType ? ` (${receiptOfficeType})` : ""}`, align: "center" });
          blocks.push({ type: "text", value: `Tel: ${receiptPhone}`, align: "center" });
          blocks.push({ type: "text", value: !paymentSettings.vat.enabled ? "ใบเสร็จรับเงิน" : requestTaxInvoice ? "ใบเสร็จรับเงิน/ใบกำกับภาษี" : "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ", align: "center", bold: true });
          if (paymentSettings.vat.enabled) blocks.push({ type: "text", value: "รวมภาษีมูลค่าเพิ่ม", align: "center" });
          blocks.push({ type: "rule" });
          blocks.push({ type: "row", left: `Table: ${currentTableId?.replace(/^T/, "")}`, right: `ID: ${nextReceiptNumber(history, slipSettings.receipt.billPrefixStore, currentBranchId, branches)}` });
          const staffDisplay = currentUser?.type === "staff"
            ? (staff.find(s => s.id === currentUser.staffId)?.displayName || currentUser.name)
            : currentUser?.type === "owner" ? (ownerProfile?.name || "เจ้าของร้าน") : null;
          if (session.guestCount || staffDisplay) {
            blocks.push({ type: "row", left: session.guestCount ? `Guests: ${session.guestCount}` : "", right: staffDisplay ? `Staff: ${staffDisplay}` : "" });
          }
          const nowD = new Date();
          blocks.push({ type: "row", left: `Date: ${String(nowD.getDate()).padStart(2, "0")}/${String(nowD.getMonth() + 1).padStart(2, "0")}/${nowD.getFullYear()}`, right: `Time: ${nowD.toLocaleTimeString("th-TH", { hour: "2-digit", minute: "2-digit" })}` });
          if (slipSettings.receipt.posNumberEnabled && slipSettings.receipt.posNumber) blocks.push({ type: "text", value: `POS: ${slipSettings.receipt.posNumber}` });
          blocks.push({ type: "rule" });
          (session.sentItems || []).forEach(it => blocks.push({ type: "row", left: `${it.qty} ${it.name}`, right: fmtMoney(it.unitPrice * it.qty) }));
          blocks.push({ type: "rule" });
          blocks.push({ type: "text", value: `Items: ${(session.sentItems || []).reduce((s, it) => s + it.qty, 0)}` });
          blocks.push({ type: "row", left: "Subtotal:", right: fmtMoney(session.billTotal) });
          if (linkedMember && birthdayDiscountActive && appliedPromos.length === 0) {
            blocks.push({ type: "row", left: `ส่วนลดวันเกิด (${linkedTier.birthdayDiscount.percent}%):`, right: `-${fmtMoney(birthdayDiscountAmount)}` });
          }
          promoEvaluations.filter(e => e.discountAmount > 0).forEach(e => blocks.push({ type: "row", left: `${e.promo.name}:`, right: `-${fmtMoney(e.discountAmount)}` }));
          redeemedRewardEvaluations.forEach(e => blocks.push({ type: "row", left: `${e.reward.name}:`, right: `-${fmtMoney(e.discountAmount)}` }));
          if (paymentSettings.serviceCharge.enabled) blocks.push({ type: "row", left: `SVC(${paymentSettings.serviceCharge.rate.toFixed(1)}%):`, right: fmtMoney(bill.serviceChargeAmt) });
          blocks.push({ type: "row", left: "Before Tax:", right: fmtMoney(discountedSubtotal + bill.serviceChargeAmt) });
          if (paymentSettings.vat.enabled) blocks.push({ type: "row", left: `TAX(${paymentSettings.vat.rate}%):`, right: fmtMoney(bill.vatAmt) });
          if (paymentSettings.rounding !== "none") {
            const preRound = discountedSubtotal + bill.serviceChargeAmt + (paymentSettings.vat.enabled && paymentSettings.vat.mode === "added" ? bill.vatAmt : 0);
            const roundingAdj = Math.round((bill.grand - preRound) * 100) / 100;
            if (roundingAdj !== 0) blocks.push({ type: "row", left: "Rounding:", right: `${roundingAdj > 0 ? "+" : ""}${fmtMoney(roundingAdj)}` });
          }
          blocks.push({ type: "rule" });
          blocks.push({ type: "row", left: "Total:", right: fmtMoney(bill.grand), bold: true });
          blocks.push({ type: "rule" });
          if (splitPayments.length > 0) {
            splitPayments.filter(p => Number(p.amount) > 0).forEach(p => {
              const acc = financeAccounts.find(a => a.id === p.methodId);
              blocks.push({ type: "row", left: `${acc ? paymentChannelGroupLabel(acc) : "-"}:`, right: fmtMoney(Number(p.amount)) });
            });
          } else {
            blocks.push({ type: "row", left: `${paymentChannelGroupLabel(financeAccounts.find(a => a.id === paymentMethodId))}:`, right: fmtMoney(bill.grand) });
          }
          if (requestTaxInvoice) {
            blocks.push({ type: "rule" });
            blocks.push({ type: "text", value: `Customer Name: ${taxInvoiceBuyer.name || "-"}` });
            blocks.push({ type: "text", value: `Address: ${taxInvoiceBuyer.address || "-"}` });
            blocks.push({ type: "text", value: `TAX ID: ${taxInvoiceBuyer.taxId || "-"}` });
            if (taxInvoiceType === "corporate") blocks.push({ type: "text", value: `Branch: ${taxInvoiceBuyer.branch || "-"}` });
            blocks.push({ type: "feed", n: 2 });
            blocks.push({ type: "text", value: "Signature Cashier: ..............................", align: "center" });
          }
          blocks.push({ type: "rule" });
          if (slipSettings.receipt.footerText) blocks.push({ type: "text", value: slipSettings.receipt.footerText, align: "center" });
          // Note: the LINE QR image can't be printed via the agent (it only
          // supports native ESC/POS blocks, not arbitrary bitmaps) — it will
          // still appear on the browser/download version of this receipt.
          return { charsPerLine: 32, cut: true, blocks };
        }

        async function sendReceiptEmail() {
          const tpl = emailReceiptSettings || { subject: "ใบเสร็จจาก {ชื่อร้าน}", body: "" };
          const vars = {
            "{ชื่อร้าน}": storeInfo.name,
            "{ชื่อลูกค้า}": linkedMember?.name || "ลูกค้า",
            "{เลขที่ใบเสร็จ}": nextReceiptNumber(history, slipSettings.receipt.billPrefixStore, currentBranchId, branches),
            "{ยอดรวม}": fmtMoney(bill.grand),
          };
          function fill(text) {
            return Object.entries(vars).reduce((t, [k, v]) => t.split(k).join(v), text || "");
          }
          const subject = fill(tpl.subject);
          const body = fill(tpl.body);
          // Try the real SMTP-sending endpoint on the print agent first (see
          // print-agent "/send-email" brief) — falls back to opening the
          // device's own email app via mailto: if that endpoint isn't there
          // or isn't reachable, so this still works even before the backend
          // email feature exists.
          const sentForReal = await sendEmailViaAgent(receiptEmail, subject, body);
          if (!sentForReal) {
            window.location.href = `mailto:${receiptEmail}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
          }
          setShowEmailReceipt(false);
        }

        // Non-fiscal bill summary for the customer to review before paying —
        // same content as the #precheckBillCard template below, as ESC/POS blocks.
        function buildPrecheckDoc() {
          const pc = slipSettings?.precheckBill || {};
          const pcBlocks = [
            { type: "text", value: storeInfo.name, align: "center", bold: true },
          ];
          if (pc.headerText) pcBlocks.push({ type: "text", value: pc.headerText, align: "center" });
          pcBlocks.push({ type: "text", value: "ใบสรุปยอด (ยังไม่ใช่ใบเสร็จ)", align: "center", bold: true });
          pcBlocks.push({ type: "text", value: `โต๊ะ ${currentTableId?.replace(/^T/, "")} · ${new Date().toLocaleString("th-TH")}`, align: "center" });
          pcBlocks.push({ type: "rule" });
          allBillItems.forEach(it => pcBlocks.push({ type: "row", left: `${it.name} x${it.qty}`, right: fmtMoney(it.unitPrice * it.qty) }));
          pcBlocks.push({ type: "rule" });
          pcBlocks.push({ type: "row", left: "ยอดรวมอาหาร", right: fmtMoney(session.billTotal) });
          if ((session.billTotal || 0) - discountedSubtotal > 0) {
            pcBlocks.push({ type: "row", left: "ส่วนลดรวม", right: `-${fmtMoney((session.billTotal || 0) - discountedSubtotal)}` });
          }
          if (paymentSettings.serviceCharge.enabled) pcBlocks.push({ type: "row", left: `ค่าบริการ (${paymentSettings.serviceCharge.rate}%)`, right: fmtMoney(bill.serviceChargeAmt) });
          if (paymentSettings.vat.enabled) pcBlocks.push({ type: "row", left: `VAT (${paymentSettings.vat.rate}%)`, right: fmtMoney(bill.vatAmt) });
          pcBlocks.push({ type: "rule" });
          pcBlocks.push({ type: "row", left: "ยอดรวมทั้งสิ้น", right: fmtMoney(bill.grand), bold: true });
          if (pc.footerText) {
            pc.footerText.split("\n").forEach(line => { if (line.trim()) pcBlocks.push({ type: "text", value: line, align: "center" }); });
          } else {
            pcBlocks.push({ type: "text", value: "เอกสารนี้เป็นใบสรุปยอดก่อนชำระเงินเท่านั้น ไม่ใช่ใบเสร็จ", align: "center" });
          }
          return { charsPerLine: 32, cut: true, blocks: pcBlocks };
        }
        async function handlePrecheckPrint() {
          // Same fallback chain as every other "print" button in the app
          // (reprint receipt, kitchen tickets, etc.): try a connected print
          // agent first, and if there isn't one, open the browser's print
          // dialog — NOT downloadPrintTemplate(), which silently saves an
          // .html file instead of printing. Uses printOnlyTemplate() rather
          // than plain printReceiptPage() because this modal also keeps the
          // final receipt template (#mainReceiptCard) mounted at the same
          // time — printing "as-is" would show both stacked on top of each
          // other.
          const eligiblePrinter = (printers || []).find(p => p.connected && p.precheckEnabled && (!p.branchId || p.branchId === currentBranchId));
          const ok = eligiblePrinter ? await printViaAgent("receipt", buildPrecheckDoc()) : false;
          if (!ok) printOnlyTemplate("precheckBillCard", "80mm auto");
        }

        return (
          <>
          <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowPayment(false)}>
            <div className="min-h-full flex items-start justify-center py-8">
            <div className="bg-white rounded-xl w-full max-w-3xl p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800">ชำระเงิน · โต๊ะ {currentTableId?.replace(/^T/, "")}</div>
                <div className="flex items-center gap-2">
                  <Btn variant="ghost" onClick={handlePrecheckPrint}>
                    <Printer size={14} /> พิมพ์ใบสรุปยอด
                  </Btn>
                  <button onClick={() => setShowPayment(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
                </div>
              </div>

              {session?.callStaffRequested && (
                <div className="mb-4 p-3 rounded-lg bg-amber-50 border border-amber-200 flex items-center justify-between gap-3">
                  <div className="flex items-center gap-2 text-sm text-amber-800">
                    <MessageCircle size={15} className="flex-shrink-0" />
                    <span>ลูกค้าเรียกพนักงาน: "{session.callStaffReason}"</span>
                  </div>
                  <Btn variant="ghost" onClick={() => setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], callStaffRequested: false, callStaffReason: null } }))}>
                    รับทราบ
                  </Btn>
                </div>
              )}

              {session?.paymentStatus === "pending_verification" && (
                <div className="mb-4 p-4 rounded-lg bg-sky-50 border border-sky-200">
                  <div className="text-sm font-medium text-sky-800 mb-2">ลูกค้าแนบสลิปโอนเงินมาแล้ว — กรุณาตรวจสอบก่อนปิดโต๊ะ</div>
                  <img src={session.paymentSlipDataUrl} alt="สลิปโอนเงิน" className="max-w-[240px] rounded-lg border border-sky-200 mb-3" />
                  {session.slipVerification && session.slipVerification.checked && session.slipVerification.ok ? (
                    <div className="mb-3 p-2.5 rounded-lg bg-emerald-50 border border-emerald-200 text-xs text-emerald-800 space-y-0.5">
                      <div className="font-semibold">✅ ระบบตรวจสอบกับธนาคารแล้ว — เป็นรายการโอนจริง</div>
                      {session.slipVerification.amount != null && <div>ยอดโอน: ฿{fmtMoney(session.slipVerification.amount)}</div>}
                      {session.slipVerification.bankName && <div>ธนาคารผู้โอน: {session.slipVerification.bankName}</div>}
                      {session.slipVerification.senderName && <div>ชื่อผู้โอน: {session.slipVerification.senderName}</div>}
                      {session.slipVerification.transRef && <div className="text-emerald-600">เลขอ้างอิง: {session.slipVerification.transRef}</div>}
                    </div>
                  ) : session.slipVerification && session.slipVerification.checked ? (
                    <div className="mb-3 p-2.5 rounded-lg bg-rose-50 border border-rose-200 text-xs text-rose-700">
                      ⚠️ ระบบตรวจสอบกับธนาคารไม่ผ่าน — {session.slipVerification.message || "ไม่สามารถยืนยันได้ว่าเป็นรายการจริง"} กรุณาตรวจสอบด้วยตนเองก่อนกดยืนยัน
                    </div>
                  ) : (
                    <div className="mb-3 p-2 rounded-lg bg-stone-50 border border-stone-200 text-xs text-stone-500">
                      ยังไม่ได้เปิดใช้งานระบบตรวจสอบสลิปอัตโนมัติ — กรุณาตรวจสอบสลิปด้วยตนเอง
                    </div>
                  )}
                  <div className="flex items-center gap-2">
                    <Btn onClick={() => {
                      setFinanceAccounts(prev => prev.map(a => (a.type === "other" && a.channelType === "พร้อมเพย์") ? { ...a, currentBalance: a.currentBalance + (session.billTotal || 0) } : a));
                      setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], paymentStatus: "verified" } }));
                    }}>
                      <CheckCircle2 size={14} /> ยืนยันสลิปถูกต้อง
                    </Btn>
                    <Btn variant="ghost" onClick={() => setSessions(prev => ({ ...prev, [currentTableId]: { ...prev[currentTableId], paymentSlipDataUrl: null, paymentStatus: "unpaid", slipVerification: null } }))}>
                      สลิปไม่ถูกต้อง / ปฏิเสธ
                    </Btn>
                  </div>
                </div>
              )}

              {/* Hidden non-fiscal bill summary — for the customer to review before paying; not a receipt/tax invoice */}
              <div id="precheckBillCard" className="print-receipt font-mono text-xs text-black">
                <div style={{ textAlign: "center", fontWeight: 700, fontSize: 13 }}>{storeInfo.name}</div>
                {slipSettings?.precheckBill?.headerText && (
                  <div style={{ textAlign: "center", fontSize: 10, color: "#666" }}>{slipSettings.precheckBill.headerText}</div>
                )}
                <div style={{ textAlign: "center", fontSize: 11, margin: "4px 0", fontWeight: 700 }}>ใบสรุปยอด (ยังไม่ใช่ใบเสร็จ)</div>
                <div style={{ textAlign: "center", fontSize: 10, color: "#666" }}>โต๊ะ {currentTableId?.replace(/^T/, "")} · {new Date().toLocaleString("th-TH")}</div>
                <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                {allBillItems.map((it, i) => (
                  <div key={i} style={{ display: "flex", justifyContent: "space-between" }}>
                    <span>{it.name} x{it.qty}</span>
                    <span>{fmtMoney(it.unitPrice * it.qty)}</span>
                  </div>
                ))}
                <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                <div style={{ display: "flex", justifyContent: "space-between" }}><span>ยอดรวมอาหาร</span><span>{fmtMoney(session.billTotal)}</span></div>
                {(session.billTotal || 0) - discountedSubtotal > 0 && (
                  <div style={{ display: "flex", justifyContent: "space-between" }}><span>ส่วนลดรวม</span><span>-{fmtMoney((session.billTotal || 0) - discountedSubtotal)}</span></div>
                )}
                {paymentSettings.serviceCharge.enabled && (
                  <div style={{ display: "flex", justifyContent: "space-between" }}><span>ค่าบริการ ({paymentSettings.serviceCharge.rate}%)</span><span>{fmtMoney(bill.serviceChargeAmt)}</span></div>
                )}
                {paymentSettings.vat.enabled && (
                  <div style={{ display: "flex", justifyContent: "space-between" }}><span>VAT ({paymentSettings.vat.rate}%)</span><span>{fmtMoney(bill.vatAmt)}</span></div>
                )}
                <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                <div style={{ display: "flex", justifyContent: "space-between", fontWeight: 700, fontSize: 13 }}><span>ยอดรวมทั้งสิ้น</span><span>฿{fmtMoney(bill.grand)}</span></div>
                {slipSettings?.precheckBill?.footerText && (
                  <div style={{ textAlign: "center", fontSize: 10, color: "#666", marginTop: 8, whiteSpace: "pre-line" }}>{slipSettings.precheckBill.footerText}</div>
                )}
                {(() => {
                  const currentBranch = branches?.find(b => b.id === currentBranchId);
                  let qrUrl = null;
                  if (currentBranch?.promptPayEnabled && currentBranch.promptPayId) {
                    qrUrl = promptPayQrImageUrl(currentBranch.promptPayId, bill.grand, 200);
                  } else {
                    const enabledIds = paymentSettings.enabledFinanceAccountIds || [];
                    const promptPayAccounts = (financeAccounts || []).filter(a =>
                      a.type === "other" && a.channelType === "พร้อมเพย์" && a.promptPayId && enabledIds.includes(a.id)
                    );
                    const acc = promptPayAccounts.find(a => a.ourBranchId === currentBranchId) || promptPayAccounts.find(a => !a.ourBranchId);
                    if (acc) qrUrl = promptPayQrImageUrl(acc.promptPayId, bill.grand, 200);
                  }
                  if (!qrUrl) return null;
                  return (
                    <>
                      <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                      <img src={qrUrl} alt="QR PromptPay" style={{ width: 160, height: 160, margin: "0 auto", display: "block" }} />
                      <div style={{ textAlign: "center", fontSize: 10, marginTop: 4 }}>สแกนจ่ายผ่าน PromptPay ฿{fmtMoney(bill.grand)}</div>
                    </>
                  );
                })()}
                <div style={{ textAlign: "center", fontSize: 9, color: "#999", marginTop: 8 }}>เอกสารนี้เป็นใบสรุปยอดสำหรับตรวจสอบก่อนชำระเงินเท่านั้น ไม่ใช่ใบเสร็จรับเงินหรือใบกำกับภาษี</div>
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
                {/* Left: bill details */}
                <div>
                  <div className="font-mono text-xs text-stone-600 space-y-1.5 border-b border-dashed border-stone-300 pb-3 mb-3">
                    {(session.sentItems || []).map(it => (
                      <div key={it.cartLineId} className="flex justify-between">
                        <span>{it.name} x{it.qty}</span>
                        <span>฿{fmtMoney(it.unitPrice * it.qty)}</span>
                      </div>
                    ))}
                  </div>

                  <div className="space-y-1.5 text-sm">
                    <div className="flex justify-between text-stone-500"><span>ยอดรวมอาหาร</span><span className="font-mono">฿{fmtMoney(session.billTotal)}</span></div>
                    {linkedMember && birthdayDiscountActive && appliedPromos.length === 0 && (
                      <div className="flex justify-between text-rose-500"><span>🎂 ส่วนลดวันเกิด ({linkedTier.birthdayDiscount.percent}%)</span><span className="font-mono">-฿{fmtMoney(birthdayDiscountAmount)}</span></div>
                    )}
                    {linkedMember && birthdayDiscountActive && appliedPromos.length > 0 && (
                      <div className="text-[11px] text-stone-400">🎂 ส่วนลดวันเกิด ใช้ร่วมกับโปรโมชั่นไม่ได้ (ยังไม่ถูกใช้)</div>
                    )}
                    {promoEvaluations.filter(e => e.discountAmount > 0).map(e => (
                      <div key={e.promo.id} className="flex justify-between text-rose-500"><span>🏷️ {e.promo.name}</span><span className="font-mono">-฿{fmtMoney(e.discountAmount)}</span></div>
                    ))}
                    {redeemedRewardEvaluations.map((e, i) => (
                      <div key={i} className="flex justify-between text-rose-500"><span>🎁 {e.reward.name}</span><span className="font-mono">-฿{fmtMoney(e.discountAmount)}</span></div>
                    ))}
                    {(session.billTotal || 0) - discountedSubtotal > 0 && (
                      <div className="flex justify-between font-medium">
                        <span className="text-stone-600">ราคาหลังหักส่วนลด</span>
                        <span className="font-mono text-stone-800">฿{fmtMoney(discountedSubtotal)}</span>
                      </div>
                    )}
                    {paymentSettings.serviceCharge.enabled && (
                      <div className="flex justify-between text-stone-500"><span>ค่าบริการ ({paymentSettings.serviceCharge.rate}%)</span><span className="font-mono">฿{fmtMoney(bill.serviceChargeAmt)}</span></div>
                    )}
                    {paymentSettings.vat.enabled && (
                      <div className="flex justify-between text-stone-500">
                        <span>VAT ({paymentSettings.vat.rate}%{paymentSettings.vat.mode === "included" ? " รวมแล้ว" : ""})</span>
                        <span className="font-mono">฿{fmtMoney(bill.vatAmt)}</span>
                      </div>
                    )}
                  </div>

                  <div className="border-t border-stone-200 mt-3 pt-3 flex items-center justify-between">
                    <span className="font-semibold text-stone-800">ยอดชำระทั้งหมด</span>
                    <span className="text-xl font-semibold text-amber-700 font-mono">฿{fmtMoney(bill.grand)}</span>
                  </div>

                  {selectedMethod?.type === "other" && (selectedMethod.channelType === "QR Code ชำระเงิน" || selectedMethod.channelType === "พร้อมเพย์") && (
                    <div className="text-center mt-4 p-4 rounded-lg border border-stone-200">
                      {/* "พร้อมเพย์" accounts carry a real promptPayId, so a real
                          scannable QR can be generated for the exact bill amount
                          — same helper used everywhere else in the app. The
                          generic "QR Code ชำระเงิน" channel type has no ID field
                          at all (see the account form), so there's nothing to
                          encode into a QR for that one; it keeps the icon. */}
                      {selectedMethod.channelType === "พร้อมเพย์" && selectedMethod.promptPayId ? (
                        <img src={promptPayQrImageUrl(selectedMethod.promptPayId, bill.grand, 200)} alt="PromptPay QR" className="w-32 h-32 mx-auto rounded-lg border border-stone-100" />
                      ) : (
                        <div className="w-32 h-32 bg-stone-100 mx-auto flex items-center justify-center text-stone-300"><QrCode size={48} /></div>
                      )}
                      <div className="text-xs text-stone-500 mt-2">สแกนชำระผ่าน {financeAccountDisplayName(selectedMethod)}</div>
                    </div>
                  )}

                  <div className="mt-4 p-3 rounded-lg border border-stone-200">
                    <label className="flex items-center gap-2 text-sm text-stone-700 cursor-pointer">
                      <input type="checkbox" checked={requestTaxInvoice} onChange={e => {
                        setRequestTaxInvoice(e.target.checked);
                        if (e.target.checked && linkedMember) {
                          if (taxInvoiceType === "corporate" && linkedMember.taxInvoiceInfo?.name) {
                            setTaxInvoiceBuyer({ ...linkedMember.taxInvoiceInfo });
                          } else if (taxInvoiceType === "individual" && linkedMember.name) {
                            setTaxInvoiceBuyer({ name: linkedMember.name, address: linkedMember.address || "", taxId: linkedMember.nationalId || "" });
                          }
                        }
                      }} />
                      ขอใบกำกับภาษีเต็มรูปแบบ
                    </label>
                    {requestTaxInvoice && (
                      <div className="space-y-2 mt-3">
                        <div className="flex gap-2">
                          <button onClick={() => {
                            setTaxInvoiceType("individual");
                            if (linkedMember?.name) setTaxInvoiceBuyer({ name: linkedMember.name, address: linkedMember.address || "", taxId: linkedMember.nationalId || "" });
                            else setTaxInvoiceBuyer({ name: "", address: "", taxId: "", branch: "" });
                          }} className={`flex-1 py-2 rounded-md text-sm border ${taxInvoiceType === "individual" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>บุคคลธรรมดา</button>
                          <button onClick={() => {
                            setTaxInvoiceType("corporate");
                            if (linkedMember?.taxInvoiceInfo?.name) setTaxInvoiceBuyer({ ...linkedMember.taxInvoiceInfo });
                            else setTaxInvoiceBuyer({ name: "", address: "", taxId: "", branch: "" });
                          }} className={`flex-1 py-2 rounded-md text-sm border ${taxInvoiceType === "corporate" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>นิติบุคคล</button>
                        </div>
                        {linkedMember && (
                          <div className="text-[11px] text-emerald-600">ดึงข้อมูลจากสมาชิก "{linkedMember.name}" ให้อัตโนมัติแล้ว (แก้ไขเพิ่มเติมได้)</div>
                        )}
                        <Field label={taxInvoiceType === "corporate" ? "ชื่อบริษัท/หน่วยงาน" : "ชื่อ-นามสกุล"}>
                          <input className={inputCls} value={taxInvoiceBuyer.name} onChange={e => setTaxInvoiceBuyer(prev => ({ ...prev, name: e.target.value }))} />
                        </Field>
                        <Field label="ที่อยู่"><textarea rows={2} className={inputCls} value={taxInvoiceBuyer.address} onChange={e => setTaxInvoiceBuyer(prev => ({ ...prev, address: e.target.value }))} /></Field>
                        <Field label={taxInvoiceType === "corporate" ? "เลขประจำตัวผู้เสียภาษี (13 หลัก)" : "เลขบัตรประชาชน (13 หลัก)"}>
                          <input className={inputCls} value={taxInvoiceBuyer.taxId} onChange={e => setTaxInvoiceBuyer(prev => ({ ...prev, taxId: e.target.value.replace(/\D/g, "").slice(0, 13) }))} placeholder="เลข 13 หลัก" />
                        </Field>
                        {taxInvoiceType === "corporate" && (
                          <Field label="สำนักงานใหญ่/สาขา">
                            <input className={inputCls} value={taxInvoiceBuyer.branch || ""} onChange={e => setTaxInvoiceBuyer(prev => ({ ...prev, branch: e.target.value }))} placeholder="เช่น สำนักงานใหญ่ หรือ สาขาที่ 001" />
                          </Field>
                        )}
                      </div>
                    )}
                  </div>

                  <div className="flex gap-2 mt-4">
                    <Btn variant="ghost" className="flex-1 justify-center" onClick={async () => { const ok = await printViaAgent("receipt", buildReceiptDoc()); if (!ok) printOnlyTemplate("mainReceiptCard", "80mm auto"); }}>
                      <ReceiptText size={15} /> {requestTaxInvoice ? "พิมพ์ใบกำกับภาษี" : "พิมพ์ใบเสร็จ"}
                    </Btn>
                    <Btn variant="ghost" className="flex-1 justify-center" onClick={() => { setReceiptEmail(linkedMember?.email || ""); setShowEmailReceipt(true); }}>
                      <Mail size={15} /> ส่งอีเมล
                    </Btn>
                  </div>

                  {/* Hidden receipt-only template used for printing (see @media print rules) */}
                  {(() => {
                    const branch = branches?.find(b => b.id === currentBranchId);
                    const receiptName = branch?.companyName || storeInfo.companyName || storeInfo.name;
                    const receiptAddress = branch?.companyAddress || storeInfo.address;
                    const receiptTaxId = branch?.taxId || storeInfo.taxId;
                    const receiptPhone = branch?.phone || storeInfo.phone;
                    const receiptOfficeType = branch?.officeType || storeInfo.officeType;
                    const receiptQr = branch?.lineQrDataUrl || storeInfo.lineQrDataUrl;
                    return (
                  <div id="mainReceiptCard" className="print-receipt font-mono text-xs text-black">
                    <img src={storeInfo.logoDataUrl || LOGO_DATA_URI} alt="logo" style={{ width: 44, height: 44, borderRadius: "50%", objectFit: "cover", margin: "0 auto 6px", display: "block" }} />
                    <div style={{ textAlign: "center", fontWeight: 700, fontSize: 13 }}>{receiptName}</div>
                    {slipSettings.receipt.headerText && <div style={{ textAlign: "center", fontSize: 10 }}>{slipSettings.receipt.headerText}</div>}
                    {receiptAddress && <div style={{ textAlign: "center", fontSize: 10 }}>{receiptAddress}</div>}
                    {receiptTaxId && <div style={{ textAlign: "center", fontSize: 10 }}>TAX ID: {receiptTaxId}{receiptOfficeType ? ` (${receiptOfficeType})` : ""}</div>}
                    <div style={{ textAlign: "center", fontSize: 10 }}>Tel: {receiptPhone}</div>

                    <div style={{ textAlign: "center", fontWeight: 700, fontSize: 12, marginTop: 6 }}>{!paymentSettings.vat.enabled ? "ใบเสร็จรับเงิน" : requestTaxInvoice ? "ใบเสร็จรับเงิน/ใบกำกับภาษี" : "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ"}</div>
                    {paymentSettings.vat.enabled && <div style={{ textAlign: "center", fontSize: 10 }}>รวมภาษีมูลค่าเพิ่ม</div>}

                    <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                    <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10 }}>
                      <span>Table: {currentTableId?.replace(/^T/, "")}</span>
                      <span>ID: {nextReceiptNumber(history, slipSettings.receipt.billPrefixStore, currentBranchId, branches)}</span>
                    </div>
                    {(() => {
                      const staffDisplay = currentUser?.type === "staff"
                        ? (staff.find(s => s.id === currentUser.staffId)?.displayName || currentUser.name)
                        : currentUser?.type === "owner" ? (ownerProfile?.name || "เจ้าของร้าน") : null;
                      return (session.guestCount || staffDisplay) ? (
                        <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10 }}>
                          <span>{session.guestCount ? `Guests: ${session.guestCount}` : ""}</span>
                          <span>{staffDisplay ? `Staff: ${staffDisplay}` : ""}</span>
                        </div>
                      ) : null;
                    })()}
                    <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10 }}>
                      <span>Date: {(() => { const n = new Date(); return `${String(n.getDate()).padStart(2, "0")}/${String(n.getMonth() + 1).padStart(2, "0")}/${n.getFullYear()}`; })()}</span>
                      <span>Time: {new Date().toLocaleTimeString("th-TH", { hour: "2-digit", minute: "2-digit" })}</span>
                    </div>
                    {slipSettings.receipt.posNumberEnabled && slipSettings.receipt.posNumber && (
                      <div style={{ fontSize: 10 }}>POS: {slipSettings.receipt.posNumber}</div>
                    )}
                    <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />

                    {(session.sentItems || []).map(it => (
                      <div key={it.cartLineId} style={{ display: "flex", justifyContent: "space-between" }}>
                        <span>{it.qty} {it.name}</span>
                        <span>{fmtMoney(it.unitPrice * it.qty)}</span>
                      </div>
                    ))}
                    <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                    <div style={{ fontSize: 10 }}>Items: {(session.sentItems || []).reduce((s, it) => s + it.qty, 0)}</div>

                    <div style={{ marginTop: 4 }}>
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span>Subtotal:</span><span>{fmtMoney(session.billTotal)}</span></div>
                      {linkedMember && birthdayDiscountActive && appliedPromos.length === 0 && (
                        <div style={{ display: "flex", justifyContent: "space-between" }}><span>ส่วนลดวันเกิด ({linkedTier.birthdayDiscount.percent}%):</span><span>-{fmtMoney(birthdayDiscountAmount)}</span></div>
                      )}
                      {promoEvaluations.filter(e => e.discountAmount > 0).map(e => (
                        <div key={e.promo.id} style={{ display: "flex", justifyContent: "space-between" }}><span>{e.promo.name}:</span><span>-{fmtMoney(e.discountAmount)}</span></div>
                      ))}
                      {redeemedRewardEvaluations.map((e, i) => (
                        <div key={i} style={{ display: "flex", justifyContent: "space-between" }}><span>{e.reward.name}:</span><span>-{fmtMoney(e.discountAmount)}</span></div>
                      ))}
                      {paymentSettings.serviceCharge.enabled && (
                        <div style={{ display: "flex", justifyContent: "space-between" }}><span>SVC({paymentSettings.serviceCharge.rate.toFixed(1)}%):</span><span>{fmtMoney(bill.serviceChargeAmt)}</span></div>
                      )}
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span>Before Tax:</span><span>{fmtMoney(discountedSubtotal + bill.serviceChargeAmt)}</span></div>
                      {paymentSettings.vat.enabled && (
                        <div style={{ display: "flex", justifyContent: "space-between" }}><span>TAX({paymentSettings.vat.rate}%):</span><span>{fmtMoney(bill.vatAmt)}</span></div>
                      )}
                      {paymentSettings.rounding !== "none" && (() => {
                        const preRound = discountedSubtotal + bill.serviceChargeAmt + (paymentSettings.vat.enabled && paymentSettings.vat.mode === "added" ? bill.vatAmt : 0);
                        const roundingAdj = Math.round((bill.grand - preRound) * 100) / 100;
                        return roundingAdj !== 0 ? (
                          <div style={{ display: "flex", justifyContent: "space-between" }}><span>Rounding:</span><span>{roundingAdj > 0 ? "+" : ""}{fmtMoney(roundingAdj)}</span></div>
                        ) : null;
                      })()}
                    </div>
                    <div style={{ borderTop: "2px double #000", margin: "4px 0" }} />
                    <div style={{ display: "flex", justifyContent: "space-between", fontWeight: 700, fontSize: 13 }}><span>Total:</span><span>{fmtMoney(bill.grand)}</span></div>
                    <div style={{ borderTop: "2px double #000", margin: "4px 0" }} />

                    {splitPayments.length > 0 ? (
                      splitPayments.filter(p => Number(p.amount) > 0).map(p => {
                        const acc = financeAccounts.find(a => a.id === p.methodId);
                        return (
                          <div key={p.id} style={{ display: "flex", justifyContent: "space-between" }}><span>{acc ? paymentChannelGroupLabel(acc) : "-"}:</span><span>{fmtMoney(Number(p.amount))}</span></div>
                        );
                      })
                    ) : (
                      <div style={{ display: "flex", justifyContent: "space-between" }}><span>{paymentChannelGroupLabel(financeAccounts.find(a => a.id === paymentMethodId))}:</span><span>{fmtMoney(bill.grand)}</span></div>
                    )}

                    {requestTaxInvoice && (
                      <>
                        <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                        <div style={{ fontSize: 10 }}>Customer Name: {taxInvoiceBuyer.name || "-"}</div>
                        <div style={{ fontSize: 10 }}>Address: {taxInvoiceBuyer.address || "-"}</div>
                        <div style={{ fontSize: 10 }}>TAX ID: {taxInvoiceBuyer.taxId || "-"}</div>
                        {taxInvoiceType === "corporate" && <div style={{ fontSize: 10 }}>Branch: {taxInvoiceBuyer.branch || "-"}</div>}
                        <div style={{ marginTop: 24, textAlign: "center", fontSize: 10 }}>
                          ..............................................<br />
                          Signature Cashier
                        </div>
                      </>
                    )}

                    <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                    {slipSettings.receipt.footerText && <div style={{ textAlign: "center", fontSize: 10 }}>{slipSettings.receipt.footerText}</div>}
                    {receiptQr && storeInfo.lineQrShowOnReceipt &&
                      (requestTaxInvoice ? storeInfo.lineQrOnFullTaxInvoice !== false : storeInfo.lineQrOnPlainReceipt !== false) && (
                      <>
                        <img src={receiptQr} alt="LINE QR" style={{ width: 60, height: 60, margin: "6px auto 2px", display: "block" }} />
                        <div style={{ textAlign: "center", fontSize: 10 }}>แอดไลน์ร้านเพื่อรับโปรโมชั่น</div>
                      </>
                    )}
                  </div>
                    );
                  })()}
                </div>

                {/* Right: member + payment method */}
                <div>
                  {linkedMember ? (
                    <div className="p-3 rounded-lg border border-amber-200 bg-amber-50 mb-4">
                      <div className="flex items-center justify-between">
                        <div className="text-sm font-medium text-stone-800">{linkedMember.name} <span className="text-stone-400 font-normal text-xs">· {linkedMember.tier}</span></div>
                        <button onClick={unlinkMember} className="text-stone-400 hover:text-rose-500"><X size={13} /></button>
                      </div>
                      <div className="text-xs text-stone-500 mt-1">แต้มสะสมปัจจุบัน {linkedMember.points.toLocaleString()}</div>
                      <div className="flex items-center justify-between text-xs text-emerald-600 mt-1">
                        <span>แต้มที่จะได้รับ{pointsMultiplier > 1 ? ` (x${pointsMultiplier})` : ""}</span>
                        <span className="font-mono">+{pointsEarned} แต้ม</span>
                      </div>
                    </div>
                  ) : (
                    <div className="p-3 rounded-lg border border-stone-200 mb-4">
                      <div className="text-sm font-medium text-stone-700 mb-2">ผูกสมาชิก (ถ้ามี)</div>
                      <input className={inputCls} value={memberPhoneInput} onChange={e => setMemberPhoneInput(e.target.value)} placeholder="ใส่เบอร์โทรสมาชิก" />
                      {memberPhoneInput.trim() !== "" && !phoneMatch && !quickRegisterOpen && (
                        <div className="text-xs text-stone-400 mt-1.5">ไม่พบสมาชิกด้วยเบอร์นี้</div>
                      )}
                      {phoneMatch && (
                        <div className="mt-2 p-2 rounded-lg bg-emerald-50 border border-emerald-200 text-xs">
                          <div className="font-medium text-stone-800">{phoneMatch.name}</div>
                          <div className="text-stone-500">{phoneMatch.tier} · แต้มสะสม {phoneMatch.points.toLocaleString()}</div>
                        </div>
                      )}
                      {quickRegisterOpen && (
                        <div className="mt-2 space-y-2">
                          <input className={inputCls} value={quickRegisterName} onChange={e => setQuickRegisterName(e.target.value)} placeholder="ชื่อสมาชิกใหม่" autoFocus />
                          <Btn className="w-full justify-center" onClick={quickRegisterAndLink}>สมัครและผูกสมาชิก</Btn>
                        </div>
                      )}
                      {!quickRegisterOpen && (
                        <div className="flex gap-2 mt-2">
                          <Btn variant="subtle" disabled={!phoneMatch} onClick={linkMember}>ผูกสมาชิก</Btn>
                          <Btn variant="ghost" disabled={!memberPhoneInput.trim()} onClick={() => setQuickRegisterOpen(true)}>สมัครสมาชิกใหม่</Btn>
                        </div>
                      )}
                    </div>
                  )}

                  <label className="flex items-center gap-2 text-sm text-stone-600 mb-3 cursor-pointer select-none">
                    <input type="checkbox" checked={isSplitMode} onChange={e => {
                      setIsSplitMode(e.target.checked);
                      setPaymentMethodId(null); setCashReceived("");
                      setSplitPayments([]);
                    }} />
                    แบ่งชำระ (เลือกได้มากกว่า 1 ช่องทาง)
                  </label>

                  <div className="text-sm font-medium text-stone-700 mb-2">ช่องทางชำระเงิน</div>

                  {!isSplitMode ? (
                    <>
                      <div className="flex flex-wrap gap-2 mb-3">
                        {enabledMethods.map(m => (
                          <button key={m.id} onClick={() => setPaymentMethodId(m.id)}
                            className={`px-3 py-1.5 rounded-md border text-sm font-medium ${paymentMethodId === m.id ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-600 hover:border-stone-400"}`}>
                            {financeAccountDisplayName(m)}
                          </button>
                        ))}
                        {enabledMethods.length === 0 && (
                          <div className="text-xs text-stone-400">ยังไม่มีช่องทางชำระที่เปิดใช้งาน — ไปเปิดใช้ที่หน้า "การตั้งค่าการชำระเงิน" ก่อน</div>
                        )}
                      </div>

                      {selectedMethod?.type === "pettyCash" && (
                        <div className="p-3 rounded-lg border border-stone-200 mb-3 space-y-2">
                          <Field label="จำนวนเงินที่ได้รับ">
                            <input type="number" className={inputCls} value={cashReceived} onChange={e => setCashReceived(e.target.value)} placeholder="เช่น 500" />
                          </Field>
                          <div className="grid grid-cols-3 gap-1.5">
                            {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map(d => (
                              <button key={d} onClick={() => setCashReceived(prev => (prev === "0" ? "" : prev) + d)}
                                className="aspect-square rounded-lg bg-stone-50 border border-stone-200 text-lg font-medium text-stone-800 hover:bg-stone-100 active:bg-stone-200 transition-colors">
                                {d}
                              </button>
                            ))}
                            <button onClick={() => setCashReceived("")}
                              className="aspect-square rounded-lg bg-stone-50 border border-stone-200 text-xs font-medium text-stone-500 hover:bg-stone-100 active:bg-stone-200 transition-colors">
                              ล้าง
                            </button>
                            <button onClick={() => setCashReceived(prev => (prev === "0" ? "" : prev) + "0")}
                              className="aspect-square rounded-lg bg-stone-50 border border-stone-200 text-lg font-medium text-stone-800 hover:bg-stone-100 active:bg-stone-200 transition-colors">
                              0
                            </button>
                            <button onClick={() => setCashReceived(prev => prev.slice(0, -1))}
                              className="aspect-square rounded-lg bg-stone-50 border border-stone-200 flex items-center justify-center text-stone-500 text-lg hover:bg-stone-100 active:bg-stone-200 transition-colors">
                              ⌫
                            </button>
                          </div>
                          <div className="flex items-center justify-between text-sm">
                            <span className="text-stone-500">เงินทอน</span>
                            <span className={`font-mono font-semibold ${change < 0 ? "text-rose-500" : "text-emerald-600"}`}>฿{fmtMoney(change < 0 ? 0 : change)}</span>
                          </div>
                          {change < 0 && <div className="text-xs text-rose-500">รับเงินไม่พอสำหรับยอดชำระ</div>}
                        </div>
                      )}
                    </>
                  ) : (
                    <>
                      <div className="flex flex-wrap gap-2 mb-3">
                        {enabledMethods.map(m => {
                          const already = splitPayments.some(p => p.methodId === m.id);
                          return (
                            <button key={m.id} onClick={() => addSplitMethod(m.id)} disabled={already}
                              className={`px-3 py-1.5 rounded-md border text-sm font-medium ${already ? "bg-stone-100 text-stone-400 border-stone-200 cursor-not-allowed" : "border-stone-300 text-stone-600 hover:border-stone-400"}`}>
                              {already ? "✓ " : "+ "}{financeAccountDisplayName(m)}
                            </button>
                          );
                        })}
                        {enabledMethods.length === 0 && (
                          <div className="text-xs text-stone-400">ยังไม่มีช่องทางชำระที่เปิดใช้งาน — ไปเปิดใช้ที่หน้า "การตั้งค่าการชำระเงิน" ก่อน</div>
                        )}
                      </div>

                      {splitPayments.length > 0 && (
                        <div className="p-3 rounded-lg border border-stone-200 mb-3 space-y-2">
                          {splitPayments.map(p => {
                            const m = enabledMethods.find(x => x.id === p.methodId);
                            return (
                              <div key={p.id} className="flex items-center gap-2">
                                <span className="text-sm text-stone-600 flex-1 truncate">{m ? financeAccountDisplayName(m) : "-"}</span>
                                <div className="relative w-28 flex-shrink-0">
                                  <span className="absolute left-2.5 top-1/2 -translate-y-1/2 text-stone-400 text-sm">฿</span>
                                  <input type="number" className={`${inputCls} pl-5 text-right`} value={p.amount} onChange={e => updateSplitAmount(p.id, e.target.value)} placeholder="0" />
                                </div>
                                <button onClick={() => removeSplitMethod(p.id)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                              </div>
                            );
                          })}
                          <div className="flex items-center justify-between text-sm pt-2 border-t border-stone-100">
                            <span className="text-stone-500">ยอดที่ต้องชำระ</span>
                            <span className="font-mono text-stone-700">฿{fmtMoney(bill.grand)}</span>
                          </div>
                          <div className="flex items-center justify-between text-sm">
                            <span className="text-stone-500">{splitRemaining > 0 ? "ยังขาดอีก" : "เงินทอน"}</span>
                            <span className={`font-mono font-semibold ${splitRemaining > 0 ? "text-rose-500" : "text-emerald-600"}`}>
                              ฿{fmtMoney(Math.abs(splitRemaining))}
                            </span>
                          </div>
                          {splitRemaining > 0 && <div className="text-xs text-rose-500">ยอดที่กรอกรวมกันยังไม่ครบยอดที่ต้องชำระ</div>}
                        </div>
                      )}
                    </>
                  )}

                  <Btn className="w-full justify-center mt-2" disabled={!canConfirm} onClick={closeTable}>
                    <CheckCircle2 size={15} /> ยืนยันการชำระเงินและปิดโต๊ะ
                  </Btn>
                </div>
              </div>
            </div>
            </div>
          </div>

          {showEmailReceipt && (
            <div className="fixed inset-0 bg-stone-900/50 flex items-center justify-center z-[60] p-4" onClick={() => setShowEmailReceipt(false)}>
              <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
                <div className="flex items-center justify-between mb-4">
                  <div className="font-semibold text-stone-800">ส่งใบเสร็จทางอีเมล</div>
                  <button onClick={() => setShowEmailReceipt(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
                </div>
                <Field label="อีเมลลูกค้า">
                  <input type="email" className={inputCls} value={receiptEmail} onChange={e => setReceiptEmail(e.target.value)} placeholder="name@email.com" autoFocus />
                </Field>
                {linkedMember?.email && receiptEmail === linkedMember.email && (
                  <p className="text-[11px] text-emerald-600 mt-1.5">ดึงจากโปรไฟล์สมาชิกให้อัตโนมัติ</p>
                )}
                <Btn className="w-full justify-center mt-4" disabled={!receiptEmail.trim()} onClick={sendReceiptEmail}>
                  <Mail size={14} /> ส่งใบเสร็จ
                </Btn>
                <p className="text-[11px] text-stone-400 text-center mt-3">ระบบจะลองส่งจริงผ่านอีเมลของร้านก่อน ถ้าส่งไม่ได้จะเปิดโปรแกรมอีเมลของเครื่องนี้ให้กดส่งเองแทน</p>
              </div>
            </div>
          )}
          </>
        );
      })()}

      {/* QR order code print modal */}
      {showQrPrint && (() => {
        const s = slipSettings.orderQr;
        const orderLink = session?.qrToken ? `https://thenuar.com/order?table=${currentTableId}&token=${session.qrToken}` : "";
        function buildQrOrderDoc() {
          const blocks = [
            { type: "text", value: storeInfo.name, align: "center", bold: true },
          ];
          if (s.showTableName) blocks.push({ type: "text", value: `โต๊ะ ${currentTableId?.replace(/^T/, "")}`, align: "center" });
          blocks.push({ type: "text", value: s.headline, align: "center", bold: true });
          if (orderLink) blocks.push({ type: "qr", value: orderLink });
          blocks.push({ type: "text", value: s.message, align: "center" });
          return { charsPerLine: 32, cut: true, blocks };
        }
        async function handleQrPrint() {
          // Only route through the print agent if at least one connected
          // printer relevant to this branch has "พิมพ์ใบ QR Code สั่งอาหาร"
          // turned on (Section 4 of ตั้งค่าเครื่องพิมพ์) — otherwise this
          // document type is intentionally left to window.print()/download.
          const eligiblePrinter = (printers || []).find(p =>
            p.connected && p.qrOrderEnabled && (!p.branchId || p.branchId === currentBranchId)
          );
          if (eligiblePrinter) {
            const ok = await printViaAgent("receipt", buildQrOrderDoc());
            if (!ok) { await preloadImage(qrImageUrl(orderLink, 300)); printReceiptPage(); }
          } else {
            await preloadImage(qrImageUrl(orderLink, 300));
            printReceiptPage();
          }
        }
        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowQrPrint(false)}>
            <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800">QR Code สั่งอาหาร</div>
                <button onClick={() => setShowQrPrint(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>

              <div className="border border-stone-200 rounded-lg p-5 text-center">
                <div className="font-semibold text-stone-800">{storeInfo.name}</div>
                {s.showTableName && <div className="inline-block mt-2 text-xs px-2 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">โต๊ะ {currentTableId?.replace(/^T/, "")}</div>}
                <div className="text-sm font-medium text-stone-700 mt-3">{s.headline}</div>
                <div className={`bg-stone-100 mx-auto my-3 flex items-center justify-center text-stone-300 rounded overflow-hidden
                  ${s.qrSize === "small" ? "w-16 h-16" : s.qrSize === "large" ? "w-32 h-32" : "w-24 h-24"}`}>
                  {orderLink
                    ? <img src={qrImageUrl(orderLink, 300)} alt="QR สั่งอาหาร" className="w-full h-full object-contain" />
                    : <QrCode size={s.qrSize === "small" ? 24 : s.qrSize === "large" ? 56 : 40} />}
                </div>
                <div className="text-xs text-stone-400">{s.message}</div>
              </div>

              <div className="mt-3 p-2.5 rounded-lg bg-stone-50 border border-stone-200">
                <div className="text-[11px] text-stone-400 mb-1">ลิงก์เฉพาะรอบโต๊ะนี้ (ข้อมูลที่จะเข้ารหัสเป็น QR จริง)</div>
                <div className="text-[11px] font-mono text-stone-600 break-all">{orderLink || "ยังไม่มีรอบเปิดอยู่"}</div>
              </div>
              <p className="text-[11px] text-stone-400 mt-2">
                ลิงก์นี้จะใช้ได้เฉพาะช่วงที่โต๊ะนี้เปิดอยู่เท่านั้น — พอ<strong>ชำระเงินปิดโต๊ะแล้ว ลิงก์เดิมจะสแกนสั่งอาหารต่อไม่ได้อีก</strong> และจะได้ลิงก์/QR ใหม่ทุกครั้งที่เปิดโต๊ะรอบถัดไป
              </p>

              <div className="flex gap-2 mt-4">
                <Btn className="flex-1 justify-center" onClick={handleQrPrint}>
                  <ReceiptText size={15} /> พิมพ์
                </Btn>
                <Btn variant="ghost" className="flex-1 justify-center" onClick={() => downloadPrintTemplate(".print-receipt", `qr-order-${currentTableId}.html`)}>
                  <Download size={15} /> ดาวน์โหลด
                </Btn>
              </div>
              <div className="text-center text-[11px] text-stone-400 mt-2">ปรับรูปแบบได้ที่ ตั้งค่าระบบ · ออกแบบสลิป · ใบสั่งอาหาร</div>

              {/* Hidden print-only version of the table tent */}
              <div className="print-receipt" style={{ width: "70mm", padding: "4mm", textAlign: "center", fontFamily: "sans-serif" }}>
                <div style={{ fontWeight: 700, fontSize: 14 }}>{storeInfo.name}</div>
                {s.showTableName && <div style={{ fontSize: 11, marginTop: 6 }}>โต๊ะ {currentTableId?.replace(/^T/, "")}</div>}
                <div style={{ fontSize: 13, fontWeight: 600, marginTop: 8 }}>{s.headline}</div>
                {orderLink
                  ? <img src={qrImageUrl(orderLink, 300)} alt="QR สั่งอาหาร" style={{ margin: "10px auto", width: 100, height: 100, display: "block" }} />
                  : <div style={{ margin: "10px auto", width: 100, height: 100, border: "1px solid #ccc" }} />}
                <div style={{ fontSize: 10, color: "#666" }}>{s.message}</div>
              </div>
            </div>
          </div>
        );
      })()}

      {/* Option / note picker modal */}
      {picker && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setPicker(null)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-start justify-between mb-1">
              <div>
                {picker.editingCartLineId && <div className="text-[10px] font-semibold text-amber-600 uppercase tracking-wide mb-0.5">แก้ไขรายการ</div>}
                <div className="font-semibold text-stone-800">{picker.item.name}</div>
                <div className="text-xs text-stone-400 mt-0.5">{picker.item.desc}</div>
              </div>
              <button onClick={() => setPicker(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="font-mono text-amber-700 font-semibold mt-1 mb-3">฿{fmtMoney(priceForChannel(picker.item))}</div>

            {(picker.item.optionGroups || []).map(g => (
              <div key={g.id} className="border-t border-stone-100 pt-3 mt-3 first:border-0 first:mt-0 first:pt-0">
                <div className="flex items-center justify-between mb-1">
                  <span className="text-sm font-semibold text-stone-700">{g.name}</span>
                  {g.type === "single" && g.required && <span className="text-[10px] px-2 py-0.5 rounded-full bg-stone-100 text-stone-500">ต้องระบุ</span>}
                </div>
                <div className="text-xs text-stone-400 mb-2">{g.type === "single" ? "กรุณาเลือก 1 ข้อ" : `เลือกสูงสุด ${g.max} ข้อ`}</div>
                <div className="space-y-1.5">
                  {g.choices.map(c => {
                    const selected = g.type === "single" ? picker.selections[g.id] === c.id : (picker.selections[g.id] || []).includes(c.id);
                    return (
                      <button key={c.id} onClick={() => toggleChoice(g, c.id)}
                        className="w-full flex items-center justify-between px-1 py-1.5 rounded-md hover:bg-stone-50">
                        <span className="flex items-center gap-2.5 text-sm text-stone-700">
                          {g.type === "single"
                            ? <span className={`w-4 h-4 rounded-full border flex-shrink-0 ${selected ? "border-amber-600 bg-amber-600 ring-2 ring-amber-100" : "border-stone-300"}`} />
                            : <span className={`w-4 h-4 rounded border flex-shrink-0 flex items-center justify-center ${selected ? "border-amber-600 bg-amber-600" : "border-stone-300"}`}>{selected && <Check size={11} className="text-white" />}</span>}
                          {c.name}
                        </span>
                        <span className="text-xs text-stone-400 font-mono">{c.price > 0 ? `+฿${c.price}` : "฿0"}</span>
                      </button>
                    );
                  })}
                </div>
              </div>
            ))}

            <div className="border-t border-stone-100 pt-3 mt-3">
              <Field label="หมายเหตุถึงครัว (ถ้ามี)">
                <input className={inputCls} placeholder="เช่น ไม่ใส่ผัก ไม่เผ็ด" value={picker.note} onChange={e => setPicker(prev => ({ ...prev, note: e.target.value }))} />
              </Field>
            </div>

            <div className="flex items-center justify-between mt-4">
              <div className="flex items-center gap-2">
                <button onClick={() => setPicker(prev => ({ ...prev, qty: Math.max(1, prev.qty - 1) }))} className="w-8 h-8 flex items-center justify-center rounded-md border border-stone-300 text-stone-500 hover:bg-stone-50"><Minus size={14} /></button>
                <span className="w-6 text-center font-mono">{picker.qty}</span>
                <button onClick={() => setPicker(prev => ({ ...prev, qty: prev.qty + 1 }))} className="w-8 h-8 flex items-center justify-center rounded-md border border-stone-300 text-stone-500 hover:bg-stone-50"><Plus size={14} /></button>
              </div>
              <Btn disabled={pickerMissingRequired()} onClick={confirmAdd}>
                {picker.editingCartLineId ? "บันทึกการแก้ไข" : "เพิ่มลงตะกร้า"} · ฿{fmtMoney((priceForChannel(picker.item) + pickerAddonTotal()) * picker.qty)}
              </Btn>
            </div>
            {pickerMissingRequired() && <div className="text-[11px] text-rose-500 mt-2">กรุณาเลือกตัวเลือกที่ต้องระบุก่อนเพิ่มลงตะกร้า</div>}
          </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: OPEN TABLES
   ========================================================================= */

function OpenTablesPage({ tables, setTables, currentBranchId, branches, sessions, setSessions, staff, ownerProfile, logActivity, onReviewSlip }) {
  const [selected, setSelected] = useState(null);
  const [closingTable, setClosingTable] = useState(null); // { id }, PIN-confirmed manual close for a table opened by mistake

  // Manual "close table" for a table that got opened by mistake (e.g. tapped
  // the wrong table when seating a party) and staff can't find a way to
  // close it since there's no real order/payment to go through. Resets it
  // back to available and clears whatever session it was left with — same
  // end state as closing out after payment, minus the payment itself.
  function forceCloseTable(tableId) {
    setTables(prev => prev.map(t => t.id === tableId
      ? { ...t, status: "available", channelName: null, guestCount: null, fulfillment: null }
      : t));
    if (setSessions) {
      setSessions(prev => {
        const next = { ...prev };
        delete next[tableId];
        return next;
      });
    }
    setClosingTable(null);
    setSelected(null);
  }

  // Clears the "🔔 เรียกพนักงาน" flag once staff has seen/handled it — same
  // fields the call-staff banner in POS Order clears, just reachable from
  // this overview page too so staff don't have to open the table's POS
  // screen just to dismiss the alert.
  function acknowledgeCallStaff(tableId) {
    if (!setSessions) return;
    setSessions(prev => ({ ...prev, [tableId]: { ...prev[tableId], callStaffRequested: false, callStaffReason: null, callStaffAt: null } }));
  }
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleTables = tables.filter(t => !effectiveBranchId || !t.branchId || t.branchId === effectiveBranchId);
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }
  // When viewing more than one branch at once (Central mode with no branch
  // picked), group by zone *and* branch so same-named zones in different
  // branches don't merge together — and show the branch name after the zone.
  const zoneGroups = [...new Map(visibleTables.map(t => [`${t.zone}__${t.branchId || ""}`, { zone: t.zone, branchId: t.branchId || null }])).values()];

  return (
    <div>
      <PageHeader eyebrow="หน้าร้าน" title="โต๊ะที่เปิดอยู่" subtitle="ภาพรวมสถานะโต๊ะทั้งหมดแบบเรียลไทม์"
        right={
          <div className="flex items-center gap-3">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <div className="flex gap-3 text-xs">
              {Object.entries(STATUS_STYLE).map(([k, v]) => (
                <div key={k} className="flex items-center gap-1.5"><span className={`w-2 h-2 rounded-full ${v.dot}`} />{v.label}</div>
              ))}
            </div>
          </div>
        } />

      {zoneGroups.map(({ zone, branchId }) => (
        <div key={`${zone}__${branchId || ""}`} className="mb-6">
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2 flex items-center gap-1">
            <MapPin size={12} /> {zone}
            {!effectiveBranchId && branchNameFor(branchId) && (
              <span className="text-stone-300 normal-case font-normal">— {branchNameFor(branchId)}</span>
            )}
          </div>
          <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-3">
            {visibleTables.filter(t => t.zone === zone && (t.branchId || null) === branchId).map(t => {
              const s = STATUS_STYLE[t.status];
              const tSession = sessions?.[t.id];
              const needsAttention = tSession?.callStaffRequested || tSession?.paymentStatus === "pending_verification";
              return (
                // A plain <button> can't legally contain the nested "รับทราบ"
                // button below (nested interactive elements break the DOM),
                // so this card is a clickable <div> with button semantics
                // instead — role/tabIndex/onKeyDown keep it keyboard-accessible.
                <div key={t.id} onClick={() => setSelected(t)} role="button" tabIndex={0}
                  onKeyDown={e => { if (e.key === "Enter" || e.key === " ") setSelected(t); }}
                  className={`relative p-4 rounded-lg border text-left cursor-pointer ${s.bg} ${s.border} hover:shadow-sm transition-shadow`}>
                  {needsAttention && (
                    <span className="absolute -top-1.5 -right-1.5 w-4 h-4 rounded-full bg-rose-500 animate-pulse border-2 border-white" />
                  )}
                  <div className="flex items-center justify-between">
                    <span className="font-serif text-lg text-stone-800">{t.id}</span>
                    <span className={`w-2 h-2 rounded-full ${s.dot}`} />
                  </div>
                  <div className="text-xs text-stone-500 mt-1">{t.seats} ที่นั่ง</div>
                  <div className={`text-xs font-medium mt-1 ${s.text}`}>{s.label}</div>
                  {needsAttention && (
                    <div className="mt-1.5">
                      <div className="text-[10px] font-medium text-rose-600 leading-snug">
                        {tSession.callStaffRequested
                          ? `🔔 เรียกพนักงาน${tSession.callStaffReason ? ` — ${tSession.callStaffReason}` : ""}`
                          : "📎 รอตรวจสลิป"}
                      </div>
                      {tSession.callStaffRequested && (
                        <button
                          onClick={e => { e.stopPropagation(); acknowledgeCallStaff(t.id); }}
                          className="mt-1.5 w-full text-[11px] font-semibold text-white bg-rose-500 hover:bg-rose-600 rounded-md px-2 py-1 transition-colors"
                        >
                          รับทราบ
                        </button>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      ))}

      {selected && (() => {
        const session = sessions?.[selected.id];
        const allItems = session ? [...(session.sentItems || []), ...(session.cart || [])] : [];
        return (
          <Card className="p-5 fixed right-8 bottom-8 w-80 shadow-xl border-stone-300 max-h-[70vh] overflow-y-auto">
            <div className="flex items-center justify-between mb-3">
              <div className="font-serif text-lg">โต๊ะ {selected.id}</div>
              <button onClick={() => setSelected(null)} className="text-stone-400 hover:text-stone-600"><X size={16} /></button>
            </div>
            <div className="text-sm text-stone-500 mb-3">โซน: {selected.zone} · {selected.seats} ที่นั่ง</div>

            {allItems.length > 0 ? (
              <>
                <div className="space-y-1.5 mb-3 pt-3 border-t border-stone-100">
                  {allItems.map((it, i) => (
                    <div key={i} className="flex items-center justify-between text-sm">
                      <span className="text-stone-600 truncate pr-2">{it.name} x{it.qty}</span>
                      <span className="font-mono text-stone-700 flex-shrink-0">฿{fmtMoney(it.unitPrice * it.qty)}</span>
                    </div>
                  ))}
                </div>
                <div className="flex items-center justify-between pt-3 border-t border-stone-200 font-semibold text-stone-800">
                  <span>ยอดปัจจุบัน</span>
                  <span className="font-mono">฿{fmtMoney(session.billTotal || 0)}</span>
                </div>
              </>
            ) : (
              <div className="text-sm text-stone-400 text-center py-4 border-t border-stone-100">ยังไม่มีออเดอร์สำหรับโต๊ะนี้</div>
            )}

            {session?.callStaffRequested && (
              <div className="mt-3 pt-3 border-t border-stone-100">
                <div className="text-xs text-rose-600 font-medium mb-2">
                  🔔 เรียกพนักงาน{session.callStaffReason ? ` — ${session.callStaffReason}` : ""}
                </div>
                <Btn className="w-full justify-center" onClick={() => acknowledgeCallStaff(selected.id)}>รับทราบ</Btn>
              </div>
            )}

            {session?.paymentStatus === "pending_verification" && (
              <div className="mt-3 pt-3 border-t border-stone-100">
                <div className="text-xs text-sky-700 font-medium mb-2">
                  📎 ลูกค้าแนบสลิปโอนเงินมาแล้ว — รอตรวจสอบก่อนปิดโต๊ะ
                </div>
                <Btn className="w-full justify-center" onClick={() => onReviewSlip?.(selected.id)}>
                  <CheckCircle2 size={14} /> ตรวจสอบสลิป & ชำระเงิน
                </Btn>
              </div>
            )}

            {selected.status !== "available" && (
              <Btn variant="ghost" className="w-full justify-center mt-3 text-rose-600 hover:bg-rose-50"
                onClick={() => setClosingTable(selected)}>
                <Ban size={14} /> ปิดโต๊ะ
              </Btn>
            )}
          </Card>
        );
      })()}

      {/* Manual close — for a table opened by mistake with no real order to pay out */}
      {closingTable && (
        <ConfirmDeletePin
          message={(() => {
            const s = sessions?.[closingTable.id];
            const hasItems = s && ([...(s.sentItems || []), ...(s.cart || [])].length > 0);
            return hasItems
              ? `โต๊ะ ${closingTable.id} ยังมีรายการสั่งอยู่ (ยอด ฿${fmtMoney(s.billTotal || 0)}) — ปิดโต๊ะตอนนี้จะล้างรายการนี้ทิ้งโดยไม่บันทึกการขาย ใช่ไหม?`
              : `ปิดโต๊ะ ${closingTable.id} กลับไปเป็น "ว่าง" ใช่ไหม? (ใช้เมื่อกดเปิดโต๊ะผิดและไม่มีออเดอร์จริง)`;
          })()}
          staff={staff} ownerProfile={ownerProfile}
          confirmLabel="ปิดโต๊ะ"
          onCancel={() => setClosingTable(null)}
          onConfirm={() => forceCloseTable(closingTable.id)}
          logActivity={logActivity} activityLabel={`ปิดโต๊ะ ${closingTable.id} (ปิดมือ)`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: RESERVATIONS (CALENDAR)
   ========================================================================= */

function ReservationsPage({ tables, setTables, channels, sessions, setSessions, setActive, setCancelHistory, currentBranchId, branches }) {
  const [reservations, setReservations] = useState([
    { id: 1, day: 16, name: "คุณเบญจ", phone: "081-000-1111", time: "18:30", guests: 4, table: "T4" },
    { id: 2, day: 16, name: "คุณกิตติ", phone: "089-222-3333", time: "19:00", guests: 2, table: "T5" },
    { id: 3, day: 20, name: "คุณมานี", phone: "062-444-5555", time: "12:00", guests: 6, table: "T8" },
  ]);
  const [month] = useState(7); // July 2026
  const [year] = useState(2026);
  const [selectedDay, setSelectedDay] = useState(16);
  const [form, setForm] = useState({ name: "", phone: "", time: "18:00", guests: 2, table: "T1" });
  const [openTableModal, setOpenTableModal] = useState(null); // { reservation, guestCount }
  const [cancelModal, setCancelModal] = useState(null); // { reservation, reason }
  const [showAddModal, setShowAddModal] = useState(false);
  const [formBranchId, setFormBranchId] = useState("");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleTables = tables.filter(t => !effectiveBranchId || !t.branchId || t.branchId === effectiveBranchId);
  // Calendar + reservation-list side-by-side layout is driven from JS (actual
  // window width) rather than a Tailwind lg: breakpoint alone — some
  // embedded/preview viewports report a CSS width the responsive utility
  // classes don't pick up correctly, so we measure directly.
  const [windowWidth, setWindowWidth] = useState(() => (typeof window !== "undefined" ? window.innerWidth : 1280));
  useEffect(() => {
    function handleResize() { setWindowWidth(window.innerWidth); }
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);
  const isWideScreen = windowWidth >= 1024;
  function branchNameForTable(tableId) {
    const t = tables.find(x => x.id === tableId);
    return t?.branchId ? branches?.find(b => b.id === t.branchId)?.name : null;
  }

  const firstWeekday = new Date(year, month - 1, 1).getDay();
  const daysInMonth = new Date(year, month, 0).getDate();
  const cells = [...Array(firstWeekday).fill(null), ...Array(daysInMonth)].map((_, i) => (i < firstWeekday ? null : i - firstWeekday + 1));

  const reservationsInScope = reservations.filter(r => {
    if (!effectiveBranchId) return true;
    const t = tables.find(x => x.id === r.table);
    return !t?.branchId || t.branchId === effectiveBranchId;
  });
  const dayReservations = reservationsInScope.filter(r => r.day === selectedDay);
  const countFor = day => reservationsInScope.filter(r => r.day === day).length;

  function addReservation() {
    if (!form.name) return;
    setReservations(prev => [...prev, { id: Date.now(), day: selectedDay, ...form, guests: Number(form.guests) }]);
    setForm({ name: "", phone: "", time: "18:00", guests: 2, table: "T1" });
    setShowAddModal(false);
  }
  function openAddModal() {
    const initialBranchId = effectiveBranchId || branches?.find(b => b.active)?.id || "";
    setFormBranchId(initialBranchId);
    const tablesForBranch = tables.filter(t => !initialBranchId || !t.branchId || t.branchId === initialBranchId);
    setForm({ name: "", phone: "", time: "18:00", guests: 2, table: tablesForBranch[0]?.id || "" });
    setShowAddModal(true);
  }
  const formTables = tables.filter(t => !formBranchId || !t.branchId || t.branchId === formBranchId);

  function startOpenTable(r) {
    setOpenTableModal({ reservation: r, guestCount: String(r.guests) });
  }
  function confirmStartOrder() {
    const { reservation, guestCount } = openTableModal;
    if (!(Number(guestCount) > 0)) return;
    const dineIn = channels.find(c => c.name === "หน้าร้าน");
    setTables(prev => prev.map(t => t.id === reservation.table
      ? { ...t, status: "ordering", channelName: "หน้าร้าน", guestCount, fulfillment: null }
      : t));
    if (dineIn) {
      setSessions(prev => ({ ...prev, [reservation.table]: { channelId: dineIn.id, fulfillment: null, guestCount, cart: [], billTotal: 0, sentItems: [], qrToken: generateQrToken(), callStaffRequested: false, callStaffReason: null, callStaffAt: null, paymentSlipDataUrl: null, paymentStatus: "unpaid" } }));
    }
    setReservations(prev => prev.filter(r => r.id !== reservation.id));
    setOpenTableModal(null);
    setActive("pos");
  }

  function startCancel(r) {
    setCancelModal({ reservation: r, reason: "" });
  }
  function confirmCancel() {
    const { reservation, reason } = cancelModal;
    if (!reason.trim()) return;
    setCancelHistory(prev => [{
      id: "cx" + Date.now(),
      branchId: tables.find(t => t.id === reservation.table)?.branchId || null,
      table: reservation.table,
      item: `การจอง: ${reservation.name} (${reservation.time})`,
      reason: reason.trim(),
      time: "วันนี้",
      by: "พนักงาน",
    }, ...prev]);
    setReservations(prev => prev.filter(r => r.id !== reservation.id));
    setCancelModal(null);
  }

  return (
    <div>
      <PageHeader eyebrow="หน้าร้าน" title="จองโต๊ะล่วงหน้า" subtitle="ปฏิทินการจองของลูกค้า"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <Btn className="whitespace-nowrap flex-shrink-0" onClick={openAddModal}><Plus size={14} /> เพิ่มการจอง</Btn>
          </div>
        } />
      <div className={`grid ${isWideScreen ? "grid-cols-12" : "grid-cols-1"} gap-5`}>
        <div className={isWideScreen ? "col-span-7" : ""}>
          <Card className="p-4">
            <div className="flex items-center justify-between mb-3">
              <button className="text-stone-400 hover:text-stone-600"><ChevronLeft size={18} /></button>
              <div className="font-serif text-lg">กรกฎาคม {year + 543}</div>
              <button className="text-stone-400 hover:text-stone-600"><ChevronRight size={18} /></button>
            </div>
            <div className="grid grid-cols-7 gap-1 text-center text-xs text-stone-400 mb-1">
              {WEEKDAYS.map(d => <div key={d} className="py-1">{d}</div>)}
            </div>
            <div className="grid grid-cols-7 gap-1">
              {cells.map((day, i) => {
                const n = day ? countFor(day) : 0;
                return (
                  <button key={i} disabled={!day} onClick={() => day && setSelectedDay(day)}
                    className={`aspect-square rounded-md text-sm flex flex-col items-center justify-center gap-0.5
                    ${!day ? "invisible" : selectedDay === day ? "bg-stone-900 text-white" : "hover:bg-stone-100 text-stone-700"}`}>
                    <span>{day}</span>
                    {n > 0 && <span className={`w-1.5 h-1.5 rounded-full ${selectedDay === day ? "bg-amber-400" : "bg-amber-500"}`} />}
                  </button>
                );
              })}
            </div>
          </Card>
        </div>

        <div className={isWideScreen ? "col-span-5" : ""}>
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">รายการจองวันที่ {selectedDay} ก.ค. {year + 543}</div>
          <div className="space-y-3">
            {dayReservations.length === 0 && <div className="text-sm text-stone-400 py-8 text-center border border-dashed border-stone-300 rounded-lg">ไม่มีรายการจองในวันนี้</div>}
            {dayReservations.map(r => (
              <Card key={r.id} className="p-3.5">
                <div className="flex justify-between items-start">
                  <div className="font-medium text-stone-800">{r.name}</div>
                  <span className="text-xs font-mono bg-sky-50 text-sky-700 border border-sky-200 px-2 py-0.5 rounded">{r.time}</span>
                </div>
                <div className="text-xs text-stone-500 mt-1 flex items-center gap-1"><PhoneCall size={11} /> {r.phone}</div>
                <div className="text-xs text-stone-500 mt-1">{r.guests} ที่นั่ง · โต๊ะ {r.table}</div>
                {!effectiveBranchId && branchNameForTable(r.table) && (
                  <div className="text-[11px] text-amber-700 mt-0.5">สาขา{branchNameForTable(r.table)}</div>
                )}
                <Btn variant="subtle" className="w-full justify-center mt-3" onClick={() => startOpenTable(r)}>
                  <Armchair size={14} /> เปิดโต๊ะ
                </Btn>
                <Btn variant="ghost" className="w-full justify-center mt-2" onClick={() => startCancel(r)}>
                  <X size={14} /> ยกเลิกการจอง
                </Btn>
              </Card>
            ))}
          </div>
        </div>
      </div>

      {/* Add reservation modal */}
      {showAddModal && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowAddModal(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มการจอง — วันที่ {selectedDay} ก.ค. {year + 543}</div>
              <button onClick={() => setShowAddModal(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อลูกค้า"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="ชื่อผู้จอง" autoFocus /></Field>
              <Field label="เบอร์โทร"><input className={inputCls} value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} placeholder="08x-xxx-xxxx" /></Field>
              <div className="grid grid-cols-2 gap-3">
                <Field label="เวลา"><input type="time" className={inputCls} value={form.time} onChange={e => setForm({ ...form, time: e.target.value })} /></Field>
                <Field label="จำนวนที่นั่ง"><input type="number" min={1} className={inputCls} value={form.guests} onChange={e => setForm({ ...form, guests: e.target.value })} /></Field>
              </div>
              {!currentBranchId && branches && branches.length > 0 && (
                <Field label="สาขา">
                  <select className={inputCls} value={formBranchId} onChange={e => {
                    const newBranchId = e.target.value;
                    setFormBranchId(newBranchId);
                    const nextTables = tables.filter(t => !newBranchId || !t.branchId || t.branchId === newBranchId);
                    setForm(f => ({ ...f, table: nextTables[0]?.id || "" }));
                  }}>
                    {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
                  </select>
                </Field>
              )}
              <Field label="โต๊ะ">
                <select className={inputCls} value={form.table} onChange={e => setForm({ ...form, table: e.target.value })}>
                  {formTables.map(t => <option key={t.id} value={t.id}>{t.id} ({t.zone}, {t.seats} ที่นั่ง)</option>)}
                </select>
              </Field>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={addReservation}><Plus size={14} /> เพิ่มการจอง</Btn>
          </div>
        </div>
      )}

      {/* Cancel reservation modal */}
      {cancelModal && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setCancelModal(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">ยกเลิกการจอง · {cancelModal.reservation.name}</div>
              <button onClick={() => setCancelModal(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mt-1">โต๊ะ {cancelModal.reservation.table} · {cancelModal.reservation.guests} ที่นั่ง เวลา {cancelModal.reservation.time}</div>

            <div className="mt-4">
              <Field label="เหตุผลที่ยกเลิก">
                <textarea rows={3} autoFocus className={inputCls} value={cancelModal.reason}
                  onChange={e => setCancelModal(prev => ({ ...prev, reason: e.target.value }))} placeholder="เช่น ลูกค้าติดธุระ ขอยกเลิก" />
              </Field>
            </div>

            <div className="flex gap-2 mt-4">
              <Btn variant="danger" disabled={!cancelModal.reason.trim()} onClick={confirmCancel}>ยืนยันยกเลิกการจอง</Btn>
              <Btn variant="ghost" onClick={() => setCancelModal(null)}>ปิด</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Confirm arrival / open table modal */}
      {openTableModal && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setOpenTableModal(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">เปิดโต๊ะ · {openTableModal.reservation.name}</div>
              <button onClick={() => setOpenTableModal(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mt-1">โต๊ะ {openTableModal.reservation.table} · จองไว้ {openTableModal.reservation.guests} ที่นั่ง เวลา {openTableModal.reservation.time}</div>

            <div className="mt-4">
              <Field label="ยืนยันจำนวนคน (ลูกค้ามาถึงแล้ว)">
                <input type="number" min={1} autoFocus className={inputCls} value={openTableModal.guestCount}
                  onChange={e => setOpenTableModal(prev => ({ ...prev, guestCount: e.target.value }))} />
              </Field>
            </div>

            <Btn className="w-full justify-center mt-4" disabled={!(Number(openTableModal.guestCount) > 0)} onClick={confirmStartOrder}>
              <Flame size={15} /> เริ่มออเดอร์
            </Btn>
            <div className="text-center text-[11px] text-stone-400 mt-2">ระบบจะเปิดโต๊ะและพาไปหน้า POS Order ให้ทันที</div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: TABLE AREA SETTINGS
   ========================================================================= */

function TableSettingsPage({ tables, setTables, zones, setZones, currentBranchId, branches, staff, ownerProfile, logActivity }) {
  const [showForm, setShowForm] = useState(false);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleTables = tables.filter(t => !effectiveBranchId || !t.branchId || t.branchId === effectiveBranchId);
  const emptyForm = { id: "", zone: zones[0] || "", seats: 2 };
  const [form, setForm] = useState(emptyForm);
  const [editingOriginalId, setEditingOriginalId] = useState(null);
  const [deletingTable, setDeletingTable] = useState(null);
  const [showZoneForm, setShowZoneForm] = useState(false);
  const [newZoneName, setNewZoneName] = useState("");
  const [editingZone, setEditingZone] = useState(null);
  const [editZoneName, setEditZoneName] = useState("");
  const [deletingZone, setDeletingZone] = useState(null);
  // Union of the persisted zone list with any zone names still referenced by
  // tables, so nothing silently disappears if data gets out of sync.
  const allZoneNames = [...new Set([...(zones || []), ...visibleTables.map(t => t.zone)])];

  function openForm() {
    setForm(emptyForm);
    setEditingOriginalId(null);
    setShowForm(true);
  }
  function startEdit(t) {
    setForm({ id: t.id, zone: t.zone, seats: t.seats });
    setEditingOriginalId(t.id);
    setShowForm(true);
  }
  function saveTable() {
    if (!form.id) return;
    if (editingOriginalId) {
      setTables(prev => prev.map(t => t.id === editingOriginalId ? { ...t, zone: form.zone, seats: Number(form.seats) } : t));
    } else {
      setTables(prev => [...prev, { id: form.id, branchId: effectiveBranchId || null, zone: form.zone, seats: Number(form.seats), status: "available" }]);
    }
    setShowForm(false);
  }
  function removeTable(id) {
    setTables(prev => prev.filter(t => t.id !== id));
    setDeletingTable(null);
  }

  function addZone() {
    if (!newZoneName.trim()) return;
    setZones(prev => [...prev, newZoneName.trim()]);
    setNewZoneName("");
    setShowZoneForm(false);
  }
  function startEditZone(zone) {
    setEditingZone(zone);
    setEditZoneName(zone);
  }
  function saveZoneRename() {
    if (!editZoneName.trim() || !editingZone) return;
    setZones(prev => prev.map(z => z === editingZone ? editZoneName.trim() : z));
    setTables(prev => prev.map(t => t.zone === editingZone ? { ...t, zone: editZoneName.trim() } : t));
    setEditingZone(null);
    setEditZoneName("");
  }
  function confirmDeleteZone() {
    setZones(prev => prev.filter(z => z !== deletingZone));
    setDeletingZone(null);
  }

  const ZONE_STYLE = {
    stone: { bg: "bg-stone-100", text: "text-stone-600" },
    amber: { bg: "bg-amber-100", text: "text-amber-700" },
    sky: { bg: "bg-sky-100", text: "text-sky-700" },
    emerald: { bg: "bg-emerald-100", text: "text-emerald-700" },
  };
  const zonePalette = ["amber", "sky", "emerald", "stone"];

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่า" title="ตั้งค่าพื้นที่โต๊ะ" subtitle="จัดการโซนและผังโต๊ะภายในร้าน"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <Btn variant="ghost" onClick={() => setShowZoneForm(true)}><Plus size={14} /> เพิ่มโซน</Btn>
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มโต๊ะ</Btn>
          </div>
        } />

      <div className="space-y-5">
        {allZoneNames.map((zone, zi) => {
          const zoneTables = visibleTables.filter(t => t.zone === zone);
          const colorKey = zonePalette[zi % zonePalette.length];
          const style = ZONE_STYLE[colorKey];
          const zoneBranchNames = !effectiveBranchId
            ? [...new Set(zoneTables.map(t => branches?.find(b => b.id === t.branchId)?.name).filter(Boolean))]
            : [];
          return (
            <Card key={zone} className="p-5">
              <div className="flex items-center justify-between mb-4">
                <div className="flex items-center gap-2.5">
                  <span className={`w-9 h-9 rounded-lg ${style.bg} ${style.text} flex items-center justify-center flex-shrink-0`}><MapPin size={16} /></span>
                  <span className="font-semibold text-stone-800">{zone}</span>
                  {zoneBranchNames.length > 0 && (
                    <span className="text-sm font-normal text-stone-400">— {zoneBranchNames.join(", ")}</span>
                  )}
                  <button onClick={() => startEditZone(zone)} className="text-stone-300 hover:text-amber-700"><Pencil size={13} /></button>
                  {zoneTables.length === 0 && (
                    <button onClick={() => setDeletingZone(zone)} className="text-stone-300 hover:text-rose-500"><Trash2 size={13} /></button>
                  )}
                </div>
                <span className="text-xs px-2 py-0.5 rounded-full bg-stone-100 text-stone-500 font-medium">{zoneTables.length} โต๊ะ</span>
              </div>
              <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
                {zoneTables.map(t => (
                  <div key={t.id} className="group flex items-center gap-3 p-3 rounded-lg border border-stone-200 bg-white hover:border-stone-300 hover:shadow-sm transition-all">
                    <span className={`w-9 h-9 rounded-lg ${style.bg} ${style.text} flex items-center justify-center flex-shrink-0`}><Armchair size={16} /></span>
                    <div className="min-w-0 flex-1">
                      <div className="font-medium text-stone-800 text-sm truncate">โต๊ะ {t.id}</div>
                      <div className="text-xs text-stone-400">{t.seats} ที่นั่ง</div>
                    </div>
                    <div className="flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0">
                      <button onClick={() => startEdit(t)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                      <button onClick={() => setDeletingTable(t)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                    </div>
                  </div>
                ))}
                {zoneTables.length === 0 && (
                  <div className="col-span-full text-sm text-stone-300 text-center py-6 border border-dashed border-stone-200 rounded-lg">ยังไม่มีโต๊ะในโซนนี้</div>
                )}
              </div>
            </Card>
          );
        })}
      </div>

      {/* Add / edit table popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{editingOriginalId ? "แก้ไขโต๊ะ" : "เพิ่มโต๊ะใหม่"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="รหัสโต๊ะ">
                <input className={`${inputCls} ${editingOriginalId ? "bg-stone-100 text-stone-400" : ""}`} placeholder="เช่น T9" value={form.id} onChange={e => setForm({ ...form, id: e.target.value })}
                  disabled={!!editingOriginalId} autoFocus={!editingOriginalId} />
              </Field>
              <Field label="โซน">
                <select className={inputCls} value={form.zone} onChange={e => setForm({ ...form, zone: e.target.value })}>
                  {allZoneNames.map(z => <option key={z}>{z}</option>)}
                </select>
              </Field>
              <Field label="จำนวนที่นั่ง"><input type="number" min={1} className={inputCls} value={form.seats} onChange={e => setForm({ ...form, seats: e.target.value })} /></Field>
            </div>
            <Btn className="mt-4 w-full justify-center" onClick={saveTable}>
              <Plus size={14} /> {editingOriginalId ? "บันทึกการแก้ไข" : "เพิ่มโต๊ะ"}
            </Btn>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingTable && (
        <ConfirmDeletePin
          message={`ลบ "โต๊ะ ${deletingTable.id}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingTable(null)}
          onConfirm={() => removeTable(deletingTable.id)}
          logActivity={logActivity} activityLabel={`ลบโต๊ะ ${deletingTable.id}`}
        />
      )}

      {/* Add zone popup */}
      {showZoneForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowZoneForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มโซน</div>
              <button onClick={() => setShowZoneForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <Field label="ชื่อโซน"><input className={inputCls} value={newZoneName} onChange={e => setNewZoneName(e.target.value)} placeholder="เช่น โซนกลางแจ้ง" autoFocus /></Field>
            <Btn className="w-full justify-center mt-4" disabled={!newZoneName.trim()} onClick={addZone}>เพิ่มโซน</Btn>
          </div>
        </div>
      )}

      {/* Rename zone popup */}
      {editingZone && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setEditingZone(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขชื่อโซน</div>
              <button onClick={() => setEditingZone(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <Field label="ชื่อโซน"><input className={inputCls} value={editZoneName} onChange={e => setEditZoneName(e.target.value)} autoFocus /></Field>
            <p className="text-[11px] text-stone-400 mt-1">โต๊ะทุกโต๊ะในโซนนี้จะเปลี่ยนชื่อโซนตามไปด้วยอัตโนมัติ</p>
            <Btn className="w-full justify-center mt-4" disabled={!editZoneName.trim()} onClick={saveZoneRename}>บันทึก</Btn>
          </div>
        </div>
      )}

      {/* Confirm delete zone popup */}
      {deletingZone && (
        <ConfirmDeletePin
          message={`ลบโซน "${deletingZone}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingZone(null)}
          onConfirm={confirmDeleteZone}
          logActivity={logActivity} activityLabel={`ลบโซน ${deletingZone}`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: KITCHEN (FOOD / DRINKS)
   ========================================================================= */

const KITCHEN_COLS = [
  { key: "queued", label: "รอดำเนินการ", icon: CircleDot, tint: "text-stone-500" },
  { key: "cooking", label: "กำลังทำ", icon: Timer, tint: "text-amber-600" },
  { key: "done", label: "เสร็จแล้ว", icon: CheckCircle2, tint: "text-emerald-600" },
];

function KitchenBoard({ title, subtitle, icon: Icon, tickets, setTickets, soundSettings, currentBranchId, branches, printers, boardType, staff, positions, ownerProfile, currentUser }) {
  const prevCountRef = useRef(tickets.length);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const [confirmingClear, setConfirmingClear] = useState(false);
  const [clearPin, setClearPin] = useState("");
  const [clearPinError, setClearPinError] = useState("");
  const visibleTickets = !currentBranchId && centralBranchFilter
    ? tickets.filter(t => t.branchId === centralBranchFilter)
    : tickets;

  useEffect(() => {
    if (tickets.length > prevCountRef.current) {
      if (shouldHearAlert(soundSettings?.newOrder, currentUser)) {
        playAlertSound(soundSettings?.newOrder, "Order เข้าแล้ว", "kitchen-notify-yt-frame");
      }
    }
    prevCountRef.current = tickets.length;
  }, [tickets.length]);

  function advance(id) {
    setTickets(prev => prev.map(t => {
      if (t.id !== id) return t;
      const order = ["queued", "cooking", "done"];
      const next = order[Math.min(order.indexOf(t.status) + 1, order.length - 1)];
      return { ...t, status: next };
    }));
  }
  function clearDone() {
    // Only remove the "done" tickets currently visible under the active
    // branch filter — if another branch's tickets are hidden right now,
    // leave them alone rather than wiping tickets the user can't even see.
    const visibleDoneIds = new Set(visibleTickets.filter(t => t.status === "done").map(t => t.id));
    setTickets(prev => prev.filter(t => !visibleDoneIds.has(t.id)));
  }
  function confirmClearDone() {
    const manager = (staff || []).find(s => s.pin === clearPin && s.active);
    const isOwner = isOwnerPin(ownerProfile, clearPin);
    if (!manager && !isOwner) {
      setClearPinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    if (manager && !isOwner) {
      const position = (positions || []).find(p => p.id === manager.positionId);
      if (!position?.pinPermissions?.includes("kitchenClearDone")) {
        setClearPinError(`ตำแหน่ง "${position?.name || "-"}" ไม่มีสิทธิ์อนุมัติรายการนี้`);
        return;
      }
    }
    clearDone();
    setConfirmingClear(false);
    setClearPin("");
    setClearPinError("");
  }
  function printTicket(id) {
    const ticket = tickets.find(t => t.id === id);
    if (ticket) {
      printViaAgentOrIsolatedWindow(id, ticket);
      return;
    }
  }
  async function printViaAgentOrIsolatedWindow(id, ticket) {
    // Only send to the print agent if a connected printer (relevant to this
    // branch) has "ครัว"/"เครื่องดื่ม" printing turned on in Section 3 of
    // "ตั้งค่าเครื่องพิมพ์" — otherwise skip straight to the browser fallback.
    const toggleKey = boardType === "drink" ? "drinkEnabled" : "kitchenEnabled";
    const eligiblePrinter = (printers || []).find(p =>
      p.connected && p[toggleKey] && (!p.branchId || p.branchId === currentBranchId)
    );
    if (eligiblePrinter) {
      const ok = await printViaAgent("kitchen", buildKitchenTicketDoc(ticket));
      if (ok) return; // printed via agent — no browser dialog needed at all
    }
    // Fallback: multiple hidden ticket templates share the .print-receipt
    // class, so before printing we hide every OTHER ticket via inline style
    // and let only the target one show through the existing @media print
    // rule — then restore afterward.
    const all = document.querySelectorAll("[data-kitchen-print]");
    all.forEach(el => {
      el.style.display = el.getAttribute("data-kitchen-print") === String(id) ? "" : "none";
    });
    printReceiptPage();
    setTimeout(() => {
      all.forEach(el => { el.style.display = "none"; });
    }, 500);
  }
  return (
    <div>
      <iframe id="kitchen-notify-yt-frame" title="เสียงแจ้งเตือนออเดอร์ใหม่" width="0" height="0" style={{ border: 0, position: "absolute" }} allow="autoplay" />
      <PageHeader eyebrow="ครัว" title={title} subtitle={subtitle}
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[200px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา (รวม)</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />
      <div className="grid grid-cols-3 gap-2 sm:gap-4">
        {KITCHEN_COLS.map(col => (
          <div key={col.key}>
            <div className={`flex items-center justify-between gap-1.5 mb-2`}>
              <div className={`flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide ${col.tint}`}>
                <col.icon size={13} /> {col.label} ({visibleTickets.filter(t => t.status === col.key).length})
              </div>
              {col.key === "done" && visibleTickets.some(t => t.status === "done") && (
                <button onClick={() => setConfirmingClear(true)} className="text-[11px] font-medium text-stone-400 hover:text-rose-500 flex items-center gap-1 normal-case tracking-normal">
                  <Trash2 size={11} /> เคลียร์รายการ
                </button>
              )}
            </div>
            <div className="space-y-3">
              {visibleTickets.filter(t => t.status === col.key).map(t => (
                <Card key={t.id} className="p-2 sm:p-3.5">
                  <div className="flex justify-between items-center mb-2">
                    <span className="font-semibold text-stone-800"><span className="font-mono">#{t.id}</span> · โต๊ะ {t.table}</span>
                    <Icon size={14} className="text-stone-300" />
                  </div>
                  <ul className="text-xs text-stone-600 space-y-2 mb-2">
                    {t.items.map((it, i) => (
                      <li key={i}>
                        <div className="flex items-baseline gap-1 font-medium text-stone-800">
                          <span>·</span><span>{it.name}</span><span className="font-mono text-stone-500">x{it.qty}</span>
                        </div>
                        {it.options && it.options.length > 0 && (
                          <div className="pl-3.5 mt-0.5 space-y-0.5">
                            {it.options.map((opt, oi) => (
                              <div key={oi} className="text-sky-700">— {opt}</div>
                            ))}
                          </div>
                        )}
                        {it.note && (
                          <div className="pl-3.5 mt-0.5 text-rose-500 italic">หมายเหตุ: {it.note}</div>
                        )}
                      </li>
                    ))}
                  </ul>

                  {/* Hidden reprint template for this ticket */}
                  <div id={`kitchen-ticket-${t.id}`} data-kitchen-print={t.id} className="print-receipt font-mono text-xs text-black">
                    <div style={{ textAlign: "center", fontWeight: 700, fontSize: 14 }}>#{t.id} · โต๊ะ {t.table}</div>
                    <div style={{ textAlign: "center", fontSize: 10, color: "#666" }}>{title} · {t.time}</div>
                    <div style={{ borderTop: "1px dashed #999", margin: "6px 0" }} />
                    {t.items.map((it, i) => (
                      <div key={i} style={{ marginBottom: 4 }}>
                        <div style={{ fontWeight: 700 }}>· {it.name} x{it.qty}</div>
                        {it.options && it.options.length > 0 && it.options.map((opt, oi) => (
                          <div key={oi} style={{ paddingLeft: 10 }}>— {opt}</div>
                        ))}
                        {it.note && <div style={{ paddingLeft: 10, fontStyle: "italic" }}>หมายเหตุ: {it.note}</div>}
                      </div>
                    ))}
                  </div>

                  <div className="flex items-center justify-between">
                    <span className="text-[11px] text-stone-400 flex items-center gap-1"><Clock size={10} /> {t.time}</span>
                    <div className="flex items-center gap-3">
                      <button onClick={() => printTicket(t.id)}
                        className="text-xs font-medium text-stone-400 hover:text-stone-600 flex items-center gap-1">
                        <Printer size={11} /> พิมพ์
                      </button>
                      {col.key !== "done" && (
                        <button onClick={() => advance(t.id)} className="text-xs font-medium text-amber-700 hover:text-amber-900">
                          {col.key === "queued" ? "เริ่มทำ →" : "เสร็จแล้ว →"}
                        </button>
                      )}
                    </div>
                  </div>
                </Card>
              ))}
              {visibleTickets.filter(t => t.status === col.key).length === 0 && (
                <div className="text-xs text-stone-300 text-center py-6 border border-dashed border-stone-200 rounded-lg">ไม่มีออเดอร์</div>
              )}
            </div>
          </div>
        ))}
      </div>

      {/* Confirm clear popup — requires a manager/owner PIN, same pattern used
          elsewhere in the app for destructive actions */}
      {confirmingClear && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setConfirmingClear(false); setClearPin(""); setClearPinError(""); }}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="text-sm text-stone-700 mb-3">เคลียร์รายการที่เสร็จแล้วทั้งหมดใช่ไหม?</div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} autoFocus className={inputCls}
                value={clearPin} onChange={e => { setClearPin(e.target.value.replace(/\D/g, "").slice(0, 6)); setClearPinError(""); }}
                placeholder="••••••" />
            </Field>
            {clearPinError && <div className="text-xs text-rose-500 mt-1.5">{clearPinError}</div>}
            <div className="flex justify-end gap-2 mt-4">
              <Btn variant="ghost" onClick={() => { setConfirmingClear(false); setClearPin(""); setClearPinError(""); }}>ยกเลิก</Btn>
              <Btn disabled={clearPin.length !== 6} onClick={confirmClearDone}>ยืนยัน</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: MEMBERS
   ========================================================================= */

function MembersPage({ members, setMembers, tiers, history, orderHistory, logActivity }) {
  const [query, setQuery] = useState("");
  const [monthFilter, setMonthFilter] = useState("");
  const [showForm, setShowForm] = useState(false);
  const emptyForm = { name: "", phone: "", email: "", birthday: "", nationalId: "" };
  const [form, setForm] = useState(emptyForm);
  const [viewingProfile, setViewingProfile] = useState(null);

  const MONTHS = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];

  const filtered = members.filter(m => {
    const matchesQuery = m.name.includes(query) || m.phone.includes(query) || m.id.includes(query);
    const matchesMonth = !monthFilter || (m.birthday && new Date(m.birthday).getMonth() + 1 === Number(monthFilter));
    return matchesQuery && matchesMonth;
  });

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }

  function submit() {
    if (!form.name || !form.phone) return;
    const nextNum = members.length + 1;
    const id = "MB" + String(nextNum).padStart(3, "0");
    const today = new Date().toISOString().slice(0, 10);
    setMembers(prev => [...prev, { id, name: form.name, phone: form.phone, email: form.email, birthday: form.birthday, nationalId: form.nationalId, tier: "Silver", points: 0, joined: today, taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" } }]);
    setShowForm(false);
  }

  const exportRows = members.map(m => ({
    "ชื่อ": m.name, "เบอร์โทร": m.phone, "เลขบัตรประชาชน": m.nationalId || "-", "วันเกิด": fmtDate(m.birthday),
    "ระดับ": m.tier, "แต้มสะสม": m.points, "วันที่สมัคร": fmtDate(m.joined),
  }));

  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="สมาชิกทั้งหมด" subtitle="รายชื่อสมาชิกและแต้มสะสมปัจจุบัน"
        right={
          <div className="flex items-center gap-2">
            <ExportButton data={exportRows} filename="รายชื่อสมาชิก" sheetName="Members" />
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มสมาชิก</Btn>
          </div>
        } />

      <div className="grid grid-cols-2 sm:grid-cols-5 gap-3 mb-5">
        <Card className="p-4">
          <div className="text-xs text-stone-400">สมาชิกทั้งหมด</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{members.length}</div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center gap-1.5 text-xs text-stone-400">
            <MessageCircle size={12} className="text-emerald-500" /> เชื่อมต่อ LINE แล้ว
          </div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{members.filter(m => m.lineUserId).length}</div>
        </Card>
        {tiers.map(t => {
          const count = members.filter(m => m.tier === t.name).length;
          return (
            <Card key={t.id} className="p-4">
              <div className="flex items-center gap-1.5 text-xs text-stone-400">
                <span className={`w-2 h-2 rounded-full ${TIER_COLOR_DOT[t.color] || "bg-stone-400"}`} />
                {t.name}
              </div>
              <div className="text-2xl font-serif text-stone-900 mt-1">{count}</div>
            </Card>
          );
        })}
      </div>

      <div className="flex items-center gap-3 mb-4">
        <div className="relative max-w-lg flex-1">
          <Search size={18} className="absolute left-3.5 top-3 text-stone-400" />
          <input className={`${inputCls} pl-10 py-2.5 text-base`} placeholder="ค้นหาชื่อ, เบอร์โทร หรือรหัสสมาชิก" value={query} onChange={e => setQuery(e.target.value)} />
        </div>
        <select className={`${inputCls} max-w-[180px] py-2.5 text-base`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)}>
          <option value="">ทุกเดือนเกิด</option>
          {MONTHS.map((m, i) => <option key={i} value={i + 1}>เกิดเดือน {m}</option>)}
        </select>
      </div>
      <Card>
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
              <th className="px-4 py-3 font-medium">รหัส</th>
              <th className="px-4 py-3 font-medium">ชื่อสมาชิก</th>
              <th className="px-4 py-3 font-medium">เบอร์โทร</th>
              <th className="px-4 py-3 font-medium">วันเดือนปีเกิด</th>
              <th className="px-4 py-3 font-medium">LINE</th>
              <th className="px-4 py-3 font-medium">ระดับ</th>
              <th className="px-4 py-3 font-medium text-right">แต้มสะสม</th>
              <th className="px-4 py-3 font-medium">วันที่สมัคร</th>
              <th className="px-4 py-3 font-medium"></th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(m => (
              <tr key={m.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                <td className="px-4 py-3 font-mono text-stone-500">{m.id}</td>
                <td className="px-4 py-3 font-medium text-stone-800">{m.name}</td>
                <td className="px-4 py-3 text-stone-500">{m.phone}</td>
                <td className="px-4 py-3 text-stone-500">
                  {m.birthday ? fmtDate(m.birthday) : "-"}
                </td>
                <td className="px-4 py-3">
                  {m.lineUserId ? (
                    <span className="text-xs px-2 py-0.5 rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200 font-medium">เชื่อมต่อแล้ว</span>
                  ) : (
                    <span className="text-xs px-2 py-0.5 rounded-full bg-stone-100 text-stone-400 border border-stone-200">ยังไม่เชื่อมต่อ</span>
                  )}
                </td>
                <td className="px-4 py-3">
                  <span className={`text-xs px-2 py-0.5 rounded border font-medium ${TIER_COLOR[m.tier === "Gold" ? "amber" : m.tier === "Platinum" ? "purple" : "stone"]}`}>{m.tier}</span>
                </td>
                <td className="px-4 py-3 text-right font-mono text-stone-700">{m.points.toLocaleString()}</td>
                <td className="px-4 py-3 text-stone-400">{fmtDate(m.joined)}</td>
                <td className="px-4 py-3 text-right">
                  <Btn variant="ghost" onClick={() => setViewingProfile(m)}>ดูข้อมูลรายบุคคล</Btn>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </Card>

      {/* Member registration popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">สมัครสมาชิกใหม่</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อสมาชิก"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="ชื่อ-นามสกุล" autoFocus /></Field>
              <Field label="เบอร์โทร"><input className={inputCls} value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} placeholder="08x-xxx-xxxx" /></Field>
              <Field label="อีเมล (ถ้ามี)"><input type="email" className={inputCls} value={form.email} onChange={e => setForm({ ...form, email: e.target.value })} placeholder="name@email.com" /></Field>
              <Field label="วันเกิด (ถ้ามี)"><input type="date" className={inputCls} value={form.birthday} onChange={e => setForm({ ...form, birthday: e.target.value })} /></Field>
              <Field label="เลขบัตรประชาชน (ถ้ามี)">
                <input className={inputCls} value={form.nationalId} onChange={e => setForm({ ...form, nationalId: e.target.value.replace(/\D/g, "").slice(0, 13) })} placeholder="เลข 13 หลัก" />
              </Field>
            </div>
            <div className="text-xs text-stone-400 mt-3">สมาชิกใหม่จะเริ่มที่ระดับ Silver ด้วยแต้มสะสม 0 แต้ม</div>
            <Btn className="w-full justify-center mt-4" onClick={submit}>สมัครสมาชิก</Btn>
          </div>
        </div>
      )}

      {viewingProfile && (
        <MemberProfileModal member={viewingProfile} members={members} setMembers={setMembers} tiers={tiers} history={history} orderHistory={orderHistory} onClose={() => setViewingProfile(null)} logActivity={logActivity} />
      )}
    </div>
  );
}

/* =========================================================================
   MEMBER PROFILE MODAL (individual analytics)
   ========================================================================= */

const TIME_BUCKETS = [
  { key: "morning", label: "เช้า (06:00–11:00)", from: 6, to: 11 },
  { key: "noon", label: "กลางวัน (11:00–14:00)", from: 11, to: 14 },
  { key: "afternoon", label: "บ่าย (14:00–17:00)", from: 14, to: 17 },
  { key: "evening", label: "เย็น-ค่ำ (17:00–22:00)", from: 17, to: 22 },
  { key: "night", label: "ดึก (22:00–06:00)", from: 22, to: 30 },
];

function MemberProfileModal({ member, members, setMembers, tiers, history, orderHistory, onClose, logActivity }) {
  const tier = tiers.find(t => t.name === member.tier);
  const [taxInfo, setTaxInfo] = useState(member.taxInvoiceInfo || { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" });
  const [taxInfoSaved, setTaxInfoSaved] = useState(false);
  function saveTaxInfo() {
    setMembers(prev => prev.map(m => m.id === member.id ? { ...m, taxInvoiceInfo: taxInfo } : m));
    setTaxInfoSaved(true);
    setTimeout(() => setTaxInfoSaved(false), 1500);
  }
  const [nationalId, setNationalId] = useState(member.nationalId || "");
  const [address, setAddress] = useState(member.address || "");
  const [email, setEmail] = useState(member.email || "");
  const [personalInfoSaved, setPersonalInfoSaved] = useState(false);
  function savePersonalInfo() {
    setMembers(prev => prev.map(m => m.id === member.id ? { ...m, nationalId, address, email } : m));
    setPersonalInfoSaved(true);
    setTimeout(() => setPersonalInfoSaved(false), 1500);
  }
  const [currentLineUserId, setCurrentLineUserId] = useState(member.lineUserId || "");
  const [confirmUnlinkLine, setConfirmUnlinkLine] = useState(false);
  function unlinkLineId() {
    setMembers(prev => prev.map(m => m.id === member.id ? { ...m, lineUserId: "" } : m));
    setCurrentLineUserId("");
    setConfirmUnlinkLine(false);
    if (logActivity) logActivity({ category: "บัตรสะสมแต้ม", action: `ลบการเชื่อมต่อ LINE ของสมาชิก ${member.name}`, detail: `รหัสสมาชิก ${member.id}` });
  }
  const visits = history.filter(h => h.member === member.name && h.amount > 0);
  const redemptions = history.filter(h => h.member === member.name && h.pointChange?.startsWith("-"));
  const orders = orderHistory.filter(o => o.memberId === member.id).sort((a, b) => (b.date + b.time).localeCompare(a.date + a.time));

  const lifetimeSpend = visits.reduce((s, h) => s + h.amount, 0);
  const visitCount = visits.length;
  const avgSpend = visitCount > 0 ? Math.round(lifetimeSpend / visitCount) : 0;
  const pointsRedeemed = redemptions.reduce((s, h) => s + Math.abs(Number(h.pointChange.replace(/[^\d-]/g, "")) || 0), 0);

  // Visit frequency: average gap between visit dates
  const visitDates = [...new Set(orders.map(o => o.date))].sort();
  let avgGapDays = null;
  if (visitDates.length >= 2) {
    const first = new Date(visitDates[0]);
    const last = new Date(visitDates[visitDates.length - 1]);
    const spanDays = Math.round((last - first) / 86400000);
    avgGapDays = Math.round(spanDays / (visitDates.length - 1));
  }
  const daysSinceLastVisit = visitDates.length > 0 ? Math.round((new Date() - new Date(visitDates[visitDates.length - 1])) / 86400000) : null;
  const churnRisk = avgGapDays != null && daysSinceLastVisit != null && daysSinceLastVisit > avgGapDays * 1.5;

  // Favorite items: aggregate qty across all orders
  const itemTotals = {};
  orders.forEach(o => o.items.forEach(it => {
    itemTotals[it.name] = (itemTotals[it.name] || 0) + it.qty;
  }));
  const favoriteItems = Object.entries(itemTotals).sort((a, b) => b[1] - a[1]).slice(0, 5);

  // Time-of-day pattern
  const bucketCounts = TIME_BUCKETS.map(b => ({ ...b, count: 0 }));
  orders.forEach(o => {
    const hour = Number((o.time || "00:00").split(":")[0]);
    const bucket = bucketCounts.find(b => hour >= b.from && hour < b.to) || bucketCounts.find(b => b.key === "night");
    if (bucket) bucket.count++;
  });
  const maxBucketCount = Math.max(1, ...bucketCounts.map(b => b.count));

  // Favorite ordering channel
  const channelCounts = {};
  orders.forEach(o => { if (o.channel) channelCounts[o.channel] = (channelCounts[o.channel] || 0) + 1; });
  const channelBreakdown = Object.entries(channelCounts).sort((a, b) => b[1] - a[1]);
  const maxChannelCount = Math.max(1, ...channelBreakdown.map(c => c[1]));

  // Monthly trend (spend + visit count for the last 6 calendar months, oldest first)
  const monthKeys = [];
  const cursor = new Date();
  cursor.setDate(1);
  for (let i = 5; i >= 0; i--) {
    const d = new Date(cursor.getFullYear(), cursor.getMonth() - i, 1);
    monthKeys.push(`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`);
  }
  const THAI_MONTH_SHORT = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];
  const monthlyTrend = monthKeys.map(key => {
    const [y, m] = key.split("-");
    const spend = orders.filter(o => o.date.startsWith(key)).reduce((s, o) => s + (o.amount || 0), 0);
    return { key, label: THAI_MONTH_SHORT[Number(m) - 1], spend };
  });
  const maxMonthlySpend = Math.max(1, ...monthlyTrend.map(m => m.spend));

  // Peer comparison: other members in the same tier
  const peers = (members || []).filter(m => m.id !== member.id && m.tier === member.tier);
  function memberStats(m) {
    const mOrders = orderHistory.filter(o => o.memberId === m.id);
    const mSpend = mOrders.reduce((s, o) => s + (o.amount || 0), 0);
    const mDates = [...new Set(mOrders.map(o => o.date))].sort();
    let mGap = null;
    if (mDates.length >= 2) {
      mGap = Math.round((new Date(mDates[mDates.length - 1]) - new Date(mDates[0])) / 86400000 / (mDates.length - 1));
    }
    return { spend: mSpend, gap: mGap };
  }
  const peerStats = peers.map(memberStats).filter(s => s.spend > 0 || s.gap != null);
  const peerAvgSpend = peerStats.length > 0 ? Math.round(peerStats.reduce((s, p) => s + p.spend, 0) / peerStats.length) : null;
  const peerGaps = peerStats.map(p => p.gap).filter(g => g != null);
  const peerAvgGap = peerGaps.length > 0 ? Math.round(peerGaps.reduce((s, g) => s + g, 0) / peerGaps.length) : null;

  return (
    <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={onClose}>
      <div className="min-h-full flex items-start justify-center py-8">
      <div className="bg-white rounded-xl w-full max-w-2xl p-6" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <div>
            <div className="font-semibold text-stone-800 text-lg">{member.name}</div>
            <div className="text-xs text-stone-400 mt-0.5">{member.id} · {member.phone}</div>
          </div>
          <button onClick={onClose} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
        </div>

        <div className="flex items-center gap-2 mb-5 flex-wrap">
          <span className={`text-xs px-2 py-0.5 rounded border font-medium ${TIER_COLOR[tier?.color] || TIER_COLOR.stone}`}>{member.tier}</span>
          <span className="text-xs text-stone-400">สมาชิกตั้งแต่ {fmtDate(member.joined)}</span>
          {member.birthday && <span className="text-xs text-stone-400">· เกิด {fmtDate(member.birthday)}</span>}
          {churnRisk && (
            <span className="text-xs px-2 py-0.5 rounded border font-medium bg-rose-50 text-rose-600 border-rose-200 flex items-center gap-1">
              ⚠️ มีความเสี่ยงจะหายไป — ปกติมาทุก {avgGapDays} วัน แต่ห่างไปแล้ว {daysSinceLastVisit} วัน
            </span>
          )}
        </div>

        <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-5">
          <Card className="p-3">
            <div className="text-[11px] text-stone-400">แต้มคงเหลือ</div>
            <div className="text-lg font-serif text-stone-900 mt-0.5">{member.points.toLocaleString()}</div>
          </Card>
          <Card className="p-3">
            <div className="text-[11px] text-stone-400">ยอดใช้จ่ายสะสม</div>
            <div className="text-lg font-serif text-stone-900 mt-0.5">฿{fmtMoney(lifetimeSpend)}</div>
          </Card>
          <Card className="p-3">
            <div className="text-[11px] text-stone-400">เฉลี่ยต่อบิล</div>
            <div className="text-lg font-serif text-stone-900 mt-0.5">฿{fmtMoney(avgSpend)}</div>
          </Card>
          <Card className="p-3">
            <div className="text-[11px] text-stone-400">แต้มที่ใช้ไปแล้ว</div>
            <div className="text-lg font-serif text-stone-900 mt-0.5">{pointsRedeemed.toLocaleString()}</div>
          </Card>
        </div>

        <Card className="p-4 mb-5">
          <div className="text-sm font-semibold text-stone-700 mb-1 flex items-center gap-1.5"><Sparkles size={14} className="text-emerald-600" /> เชื่อมต่อ LINE (สำหรับเช็คแต้ม/แลกของรางวัลเอง)</div>
          <p className="text-xs text-stone-400 mb-3">LINE User ID จะถูกผูกอัตโนมัติเมื่อสมาชิกเชื่อมต่อผ่าน LINE เอง (ไม่รองรับให้พนักงานพิมพ์กรอกเองแล้ว เพื่อความถูกต้อง) — ถ้าสมาชิกเปลี่ยนบัญชี LINE ใหม่ ให้กด "ลบ" เพื่อให้เชื่อมต่อใหม่ได้</p>
          {currentLineUserId ? (
            <div className="flex items-center justify-between p-3 rounded-lg bg-emerald-50 border border-emerald-200">
              <div className="min-w-0">
                <div className="text-xs text-emerald-700 font-medium">เชื่อมต่อแล้ว</div>
                <div className="text-xs font-mono text-stone-500 truncate">{currentLineUserId}</div>
              </div>
              <Btn variant="ghost" onClick={() => setConfirmUnlinkLine(true)} className="flex-shrink-0"><Trash2 size={14} /> ลบ</Btn>
            </div>
          ) : (
            <div className="text-xs text-stone-400 p-3 rounded-lg bg-stone-50 border border-stone-200 text-center">ยังไม่เชื่อมต่อ LINE</div>
          )}
        </Card>

        <Card className="p-4 mb-5">
          <div className="text-sm font-semibold text-stone-700 mb-1">ข้อมูลส่วนตัว (สำหรับใบกำกับภาษีบุคคลธรรมดา)</div>
          <p className="text-xs text-stone-400 mb-3">บันทึกไว้ล่วงหน้าเพื่อดึงมาเติมอัตโนมัติเมื่อสมาชิกคนนี้ขอใบกำกับภาษีแบบบุคคลธรรมดาตอนชำระเงิน</p>
          <div className="space-y-3">
            <Field label="อีเมล"><input type="email" className={inputCls} value={email} onChange={e => setEmail(e.target.value)} placeholder="name@email.com" /></Field>
            <Field label="เลขบัตรประชาชน"><input className={inputCls} value={nationalId} onChange={e => setNationalId(e.target.value.replace(/\D/g, "").slice(0, 13))} placeholder="เลข 13 หลัก" /></Field>
            <Field label="ที่อยู่"><textarea rows={2} className={inputCls} value={address} onChange={e => setAddress(e.target.value)} /></Field>
          </div>
          <div className="flex items-center gap-3 mt-3">
            <Btn onClick={savePersonalInfo}>บันทึก</Btn>
            {personalInfoSaved && <span className="text-xs text-emerald-600">บันทึกแล้ว</span>}
          </div>
        </Card>

        <Card className="p-4 mb-5">
          <div className="text-sm font-semibold text-stone-700 mb-1 flex items-center gap-1.5"><ReceiptText size={14} className="text-sky-600" /> ข้อมูลนิติบุคคล (สำหรับออกใบกำกับภาษี)</div>
          <p className="text-xs text-stone-400 mb-3">บันทึกไว้ล่วงหน้าเพื่อดึงมาเติมอัตโนมัติทุกครั้งที่สมาชิกคนนี้ขอใบกำกับภาษีเต็มรูปแบบตอนชำระเงิน</p>
          <div className="space-y-3">
            <Field label="ชื่อนิติบุคคล/บริษัท"><input className={inputCls} value={taxInfo.name} onChange={e => setTaxInfo(f => ({ ...f, name: e.target.value }))} /></Field>
            <Field label="ที่อยู่"><textarea rows={2} className={inputCls} value={taxInfo.address} onChange={e => setTaxInfo(f => ({ ...f, address: e.target.value }))} /></Field>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <Field label="เลขประจำตัวผู้เสียภาษี (13 หลัก)">
                <input className={inputCls} value={taxInfo.taxId} onChange={e => setTaxInfo(f => ({ ...f, taxId: e.target.value.replace(/\D/g, "").slice(0, 13) }))} placeholder="เลข 13 หลัก" />
              </Field>
              <Field label="สำนักงานใหญ่/สาขา">
                <input className={inputCls} value={taxInfo.branch || ""} onChange={e => setTaxInfo(f => ({ ...f, branch: e.target.value }))} placeholder="เช่น สำนักงานใหญ่ หรือ สาขาที่ 001" />
              </Field>
            </div>
          </div>
          <div className="flex items-center gap-3 mt-3">
            <Btn onClick={saveTaxInfo}>บันทึก</Btn>
            {taxInfoSaved && <span className="text-xs text-emerald-600">บันทึกแล้ว</span>}
          </div>
        </Card>

        <div className="grid grid-cols-1 sm:grid-cols-2 gap-5 mb-5">
          <div>
            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">เมนูโปรด (5 อันดับแรก)</div>
            {favoriteItems.length === 0 ? (
              <div className="text-sm text-stone-400">ยังไม่มีข้อมูลการสั่งอาหาร</div>
            ) : (
              <div className="space-y-1.5">
                {favoriteItems.map(([name, qty], i) => (
                  <div key={name} className="flex items-center justify-between text-sm">
                    <span className="text-stone-700 truncate">{i + 1}. {name}</span>
                    <span className="font-mono text-stone-400 flex-shrink-0">{qty} ครั้ง</span>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div>
            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">ความถี่ในการรับบริการ</div>
            <div className="text-sm text-stone-700 space-y-1">
              <div>มาใช้บริการทั้งหมด <span className="font-mono">{visitDates.length || visitCount}</span> ครั้ง</div>
              <div>เฉลี่ยทุก <span className="font-mono">{avgGapDays ?? "-"}</span> วัน</div>
              <div>มาล่าสุดเมื่อ <span className="font-mono">{daysSinceLastVisit ?? "-"}</span> วันก่อน</div>
              {peerAvgGap != null && (
                <div className="text-xs text-stone-400 pt-1">
                  เทียบสมาชิกระดับ {member.tier} คนอื่น: เฉลี่ยทุก {peerAvgGap} วัน
                  {avgGapDays != null && (avgGapDays < peerAvgGap
                    ? <span className="text-emerald-600"> (มาบ่อยกว่าค่าเฉลี่ย)</span>
                    : avgGapDays > peerAvgGap ? <span className="text-amber-600"> (มาห่างกว่าค่าเฉลี่ย)</span> : null)}
                </div>
              )}
              {peerAvgSpend != null && (
                <div className="text-xs text-stone-400">
                  ยอดใช้จ่ายสะสมเทียบเฉลี่ยกลุ่ม: ฿{fmtMoney(lifetimeSpend)} vs ฿{fmtMoney(peerAvgSpend)}
                </div>
              )}
            </div>
          </div>
        </div>

        {channelBreakdown.length > 0 && (
          <div className="mb-5">
            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">ช่องทางที่สั่งบ่อยที่สุด</div>
            <div className="space-y-1.5">
              {channelBreakdown.map(([name, count]) => (
                <div key={name} className="flex items-center gap-2 text-xs">
                  <span className="w-28 flex-shrink-0 text-stone-500 truncate">{name}</span>
                  <div className="flex-1 h-2 rounded-full bg-stone-100 overflow-hidden">
                    <div className="h-full bg-sky-500 rounded-full" style={{ width: `${(count / maxChannelCount) * 100}%` }} />
                  </div>
                  <span className="w-6 text-right font-mono text-stone-400 flex-shrink-0">{count}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        <div className="mb-5">
          <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">แนวโน้มยอดใช้จ่ายรายเดือน (6 เดือนล่าสุด)</div>
          <div className="flex items-end gap-2 h-24">
            {monthlyTrend.map(m => (
              <div key={m.key} className="flex-1 flex flex-col items-center justify-end h-full">
                <div className="w-full bg-amber-400 rounded-t" style={{ height: `${(m.spend / maxMonthlySpend) * 100}%`, minHeight: m.spend > 0 ? 4 : 0 }} title={`฿${m.spend}`} />
                <div className="text-[10px] text-stone-400 mt-1">{m.label}</div>
              </div>
            ))}
          </div>
        </div>

        <div className="mb-5">
          <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">ช่วงเวลาที่ใช้บริการ</div>
          <div className="space-y-1.5">
            {bucketCounts.map(b => (
              <div key={b.key} className="flex items-center gap-2 text-xs">
                <span className="w-40 flex-shrink-0 text-stone-500">{b.label}</span>
                <div className="flex-1 h-2 rounded-full bg-stone-100 overflow-hidden">
                  <div className="h-full bg-amber-500 rounded-full" style={{ width: `${(b.count / maxBucketCount) * 100}%` }} />
                </div>
                <span className="w-6 text-right font-mono text-stone-400 flex-shrink-0">{b.count}</span>
              </div>
            ))}
          </div>
        </div>

        <div>
          <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-2">ประวัติการใช้บริการ</div>
          {history.filter(h => h.member === member.name).length === 0 ? (
            <div className="text-sm text-stone-400">ยังไม่มีประวัติการใช้บริการ</div>
          ) : (
            <div className="space-y-1.5 max-h-48 overflow-y-auto pr-1">
              {history.filter(h => h.member === member.name).map(h => (
                <div key={h.id} className="flex items-center justify-between text-sm p-2 rounded-lg border border-stone-100">
                  <div>
                    <div className="text-stone-700">{h.action}</div>
                    <div className="text-xs text-stone-400">{fmtDate(h.date)}</div>
                  </div>
                  <div className="text-right flex-shrink-0">
                    {h.amount > 0 && <div className="font-mono text-stone-700">฿{fmtMoney(h.amount)}</div>}
                    <div className={`text-xs font-mono ${h.pointChange?.startsWith("+") ? "text-emerald-600" : "text-rose-500"}`}>{h.pointChange}</div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
      </div>

      {/* Confirm unlink LINE popup */}
      {confirmUnlinkLine && (
        <div className="fixed inset-0 bg-stone-900/50 flex items-center justify-center z-[60] p-4" onClick={() => setConfirmUnlinkLine(false)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="text-sm text-stone-700 mb-4">ลบการเชื่อมต่อ LINE ของ "{member.name}" ใช่ไหม? สมาชิกจะต้องเชื่อมต่อ LINE ใหม่อีกครั้งภายหลัง</div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setConfirmUnlinkLine(false)}>ยกเลิก</Btn>
              <Btn onClick={unlinkLineId}>ยืนยันลบ</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: TIERS
   ========================================================================= */

function tierPerksList(t, categories) {
  const list = [];
  if (t.pointsMultiplier?.enabled) list.push(`สะสมแต้ม x${t.pointsMultiplier.multiplier}`);
  if (t.birthdayDiscount?.enabled) {
    const catNames = (t.birthdayDiscount.categoryIds || []).map(id => categories.find(c => c.id === id)?.name).filter(Boolean);
    list.push(`ส่วนลดวันเกิด ${t.birthdayDiscount.percent}%${catNames.length ? ` (เฉพาะ ${catNames.join(", ")})` : " (ทุกหมวดหมู่)"}`);
  }
  (t.otherPerks || []).forEach(p => list.push(p));
  return list;
}

function TiersPage({ tiers, setTiers, categories }) {
  const [showForm, setShowForm] = useState(false);
  const emptyForm = {
    name: "", minPoints: "", color: "stone",
    birthdayDiscount: { enabled: false, percent: "10", categoryIds: [] },
    pointsMultiplier: { enabled: false, multiplier: "1.2" },
    otherPerks: [""],
  };
  const [form, setForm] = useState(emptyForm);

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }
  function startEdit(t) {
    setForm({
      id: t.id,
      name: t.name,
      minPoints: String(t.minPoints),
      color: t.color,
      birthdayDiscount: { enabled: t.birthdayDiscount.enabled, percent: String(t.birthdayDiscount.percent), categoryIds: t.birthdayDiscount.categoryIds },
      pointsMultiplier: { enabled: t.pointsMultiplier.enabled, multiplier: String(t.pointsMultiplier.multiplier) },
      otherPerks: t.otherPerks.length ? t.otherPerks : [""],
    });
    setShowForm(true);
  }
  function setBirthday(patch) {
    setForm(prev => ({ ...prev, birthdayDiscount: { ...prev.birthdayDiscount, ...patch } }));
  }
  function toggleBirthdayCategory(catId) {
    setForm(prev => {
      const cur = prev.birthdayDiscount.categoryIds;
      const next = cur.includes(catId) ? cur.filter(id => id !== catId) : [...cur, catId];
      return { ...prev, birthdayDiscount: { ...prev.birthdayDiscount, categoryIds: next } };
    });
  }
  function setMultiplier(patch) {
    setForm(prev => ({ ...prev, pointsMultiplier: { ...prev.pointsMultiplier, ...patch } }));
  }
  function updateOtherPerk(i, value) {
    setForm(prev => ({ ...prev, otherPerks: prev.otherPerks.map((p, idx) => idx === i ? value : p) }));
  }
  function addOtherPerkRow() {
    setForm(prev => ({ ...prev, otherPerks: [...prev.otherPerks, ""] }));
  }
  function removeOtherPerkRow(i) {
    setForm(prev => ({ ...prev, otherPerks: prev.otherPerks.filter((_, idx) => idx !== i) }));
  }
  function submit() {
    if (!form.name) return;
    const tierData = {
      name: form.name,
      minPoints: Number(form.minPoints) || 0,
      color: form.color,
      birthdayDiscount: { enabled: form.birthdayDiscount.enabled, percent: Number(form.birthdayDiscount.percent) || 0, categoryIds: form.birthdayDiscount.categoryIds },
      pointsMultiplier: { enabled: form.pointsMultiplier.enabled, multiplier: Number(form.pointsMultiplier.multiplier) || 1 },
      otherPerks: form.otherPerks.map(p => p.trim()).filter(Boolean),
    };
    if (form.id) {
      setTiers(prev => prev.map(t => t.id === form.id ? { ...t, ...tierData } : t));
    } else {
      setTiers(prev => [...prev, { id: "t" + Date.now(), ...tierData }]);
    }
    setShowForm(false);
  }

  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="จัดระดับสมาชิก" subtitle="กำหนดเงื่อนไขและสิทธิประโยชน์แต่ละระดับ"
        right={<Btn onClick={openForm}><Plus size={14} /> เพิ่มระดับ</Btn>} />
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
        {tiers.map(t => (
          <Card key={t.id} className="p-5">
            <div className="flex items-center justify-between mb-3">
              <span className={`px-2.5 py-1 rounded border text-sm font-semibold ${TIER_COLOR[t.color]}`}>{t.name}</span>
              <Award size={18} className="text-stone-300" />
            </div>
            <div className="text-xs text-stone-400 mb-3">แต้มขั้นต่ำ: <span className="font-mono text-stone-700">{t.minPoints.toLocaleString()}</span></div>
            <ul className="space-y-1.5">
              {tierPerksList(t, categories).map((p, i) => (
                <li key={i} className="text-sm text-stone-600 flex items-start gap-1.5"><Star size={12} className="text-amber-500 mt-1 flex-shrink-0" /> {p}</li>
              ))}
              {tierPerksList(t, categories).length === 0 && <li className="text-sm text-stone-300">ยังไม่มีสิทธิประโยชน์</li>}
            </ul>
            <button onClick={() => startEdit(t)} className="text-xs text-stone-400 hover:text-amber-700 flex items-center gap-1 mt-4"><Pencil size={11} /> แก้ไข</button>
          </Card>
        ))}
      </div>

      {/* Add tier popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-3xl p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขระดับสมาชิก" : "เพิ่มระดับสมาชิก"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
              {/* Left column */}
              <div className="space-y-4">
                <Field label="ชื่อระดับ"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น Diamond" autoFocus /></Field>
                <Field label="แต้มขั้นต่ำ"><input type="number" className={inputCls} value={form.minPoints} onChange={e => setForm({ ...form, minPoints: e.target.value })} placeholder="เช่น 10000" /></Field>

                <div>
                  <div className="text-xs font-medium text-stone-500 mb-2">สีป้ายระดับ</div>
                  <div className="flex flex-wrap gap-2">
                    {Object.keys(TIER_COLOR).map(c => (
                      <button key={c} onClick={() => setForm({ ...form, color: c })}
                        className={`w-8 h-8 rounded-full border-2 ${TIER_COLOR_DOT[c]} ${form.color === c ? "border-stone-800 ring-2 ring-offset-1 ring-stone-300" : "border-white"}`}
                        title={c} />
                    ))}
                  </div>
                </div>

                <div className="border-t border-stone-100 pt-4">
                  <div className="text-sm font-semibold text-stone-700 mb-3">สิทธิประโยชน์</div>

                  {/* Birthday discount */}
                  <div className="p-3 rounded-lg border border-stone-200 mb-3">
                    <ToggleRow label="ส่วนลดวันเกิด" checked={form.birthdayDiscount.enabled} onChange={v => setBirthday({ enabled: v })} />
                    {form.birthdayDiscount.enabled && (
                      <div className="mt-3 space-y-3">
                        <Field label="ส่วนลด (%) — ใช้ได้เฉพาะในวันเกิด">
                          <input type="number" className={`${inputCls} max-w-[140px]`} value={form.birthdayDiscount.percent} onChange={e => setBirthday({ percent: e.target.value })} />
                        </Field>
                        <div>
                          <div className="text-xs text-stone-400 mb-1.5">หมวดหมู่อาหารที่เข้าร่วมส่วนลด (เว้นว่าง = ทุกหมวดหมู่)</div>
                          <div className="flex flex-wrap gap-2">
                            {categories.map(c => (
                              <button key={c.id} onClick={() => toggleBirthdayCategory(c.id)}
                                className={`px-3 py-1.5 rounded-full text-xs border ${form.birthdayDiscount.categoryIds.includes(c.id) ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>
                                {c.name}
                              </button>
                            ))}
                          </div>
                        </div>
                      </div>
                    )}
                  </div>
                </div>
              </div>

              {/* Right column: points multiplier + other perks */}
              <div className="space-y-4">
                <div>
                  {/* Points multiplier */}
                  <div className="p-3 rounded-lg border border-stone-200">
                    <ToggleRow label="สะสมแต้มคูณเท่า" checked={form.pointsMultiplier.enabled} onChange={v => setMultiplier({ enabled: v })} />
                    {form.pointsMultiplier.enabled && (
                      <div className="mt-3">
                        <Field label="คูณแต้ม (เท่า)">
                          <input type="number" step="0.1" className={`${inputCls} max-w-[140px]`} value={form.pointsMultiplier.multiplier} onChange={e => setMultiplier({ multiplier: e.target.value })} />
                        </Field>
                      </div>
                    )}
                  </div>
                </div>

                <div>
                  <div className="text-sm font-semibold text-stone-700 mb-3">สิทธิประโยชน์อื่นๆ</div>
                  <div className="p-3 rounded-lg border border-stone-200">
                    <div className="space-y-2">
                      {form.otherPerks.map((p, i) => (
                        <div key={i} className="flex items-center gap-2">
                          <input className={inputCls} value={p} onChange={e => updateOtherPerk(i, e.target.value)} placeholder="เช่น ที่จอดรถ VIP" />
                          <button onClick={() => removeOtherPerkRow(i)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                        </div>
                      ))}
                    </div>
                    <button onClick={addOtherPerkRow} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2">
                      <Plus size={12} /> เพิ่มสิทธิประโยชน์อื่น
                    </button>
                  </div>
                </div>
              </div>
            </div>

            <Btn className="w-full justify-center mt-5" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "เพิ่มระดับสมาชิก"}</Btn>
          </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: POINT RATE
   ========================================================================= */

function PointRatePage({ settings, setSettings }) {
  const [draft, setDraft] = useState(settings);
  const [saved, setSaved] = useState(false);
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings);
  useEffect(() => { setDraft(settings); }, [settings]);
  function change(patch) {
    setDraft(prev => ({ ...prev, ...patch }));
  }
  function saveChanges() {
    setSettings(draft);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }
  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="อัตราสะสมแต้ม" subtitle="กำหนดอัตราแลกเปลี่ยนบาทเป็นแต้ม" />
      <Card className="p-6 max-w-lg">
        <Field label="ทุกการใช้จ่าย (บาท) ต่อ 1 แต้ม">
          <div className="flex items-center gap-2">
            <input type="number" className={inputCls} value={draft.baht} onChange={e => change({ baht: Number(e.target.value) })} />
            <span className="text-sm text-stone-400 whitespace-nowrap">บาท = 1 แต้ม</span>
          </div>
        </Field>
        <div className="text-xs text-stone-400 mt-3">ตัวอย่าง: ยอดใช้จ่าย 500 บาท ลูกค้าจะได้รับ {Math.floor(500 / draft.baht)} แต้ม</div>
        {isDirty && <div className="text-xs text-amber-700 mt-3">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</div>}
        <div className="flex items-center gap-3 mt-2">
          <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
          {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings)}>ยกเลิกการแก้ไข</Btn>}
        </div>
        {saved && !isDirty && <div className="text-emerald-600 text-xs mt-2">บันทึกเรียบร้อย ✓</div>}
      </Card>
    </div>
  );
}

/* =========================================================================
   PAGE: REWARDS
   ========================================================================= */

const REWARD_TYPES = [
  { key: "food", label: "แลกรับอาหาร", icon: UtensilsCrossed },
  { key: "discount", label: "แลกส่วนลด", icon: Percent },
  { key: "prize", label: "แลกของรางวัล", icon: Gift },
];

function RewardsPage({ rewards, setRewards, members, setMembers, setHistory, menu, categories }) {
  const [showForm, setShowForm] = useState(false);
  const emptyForm = {
    type: "food", name: "", startDate: "", endDate: "", quota: "", points: "", limitPerMember: "", limitPerBill: "",
    food: { itemId: menu[0]?.id || "" },
    discount: { mode: "amount", value: "" },
    prize: { itemName: "" },
  };
  const [form, setForm] = useState(emptyForm);
  const [redeeming, setRedeeming] = useState(null); // reward being redeemed
  const [phone, setPhone] = useState("");
  const [redeemed, setRedeemed] = useState(false);

  const member = members.find(m => m.phone.replace(/-/g, "") === phone.replace(/-/g, "") && phone.trim() !== "");
  const enoughPoints = member && redeeming ? member.points >= redeeming.points : false;
  const memberRedeemedCount = member && redeeming ? (redeeming.redemptionsByMember?.[member.id] || 0) : 0;
  const limitReached = member && redeeming && redeeming.limitPerMember !== "" && redeeming.limitPerMember != null
    ? memberRedeemedCount >= redeeming.limitPerMember
    : false;
  const canRedeem = enoughPoints && !limitReached;

  function remainingQuota(r) {
    return r.quota === "" || r.quota == null ? null : Math.max(0, r.quota - (r.usedCount || 0));
  }
  function rewardDetail(r) {
    if (r.type === "food") {
      const item = menu.find(m => m.id === r.food?.itemId);
      return item ? `แลกได้: ${item.name}` : "ยังไม่ได้เลือกเมนู";
    }
    if (r.type === "discount") {
      return r.discount.mode === "percent" ? `รับส่วนลด ${r.discount.value}%` : `รับส่วนลด ฿${r.discount.value}`;
    }
    if (r.type === "prize") {
      return `ของรางวัล: ${r.prize.itemName || "-"}`;
    }
    return "";
  }

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }
  function startEdit(r) {
    setForm({
      id: r.id,
      type: r.type, name: r.name, startDate: r.startDate || "", endDate: r.endDate || "",
      quota: r.quota === "" || r.quota == null ? "" : String(r.quota),
      points: String(r.points),
      limitPerMember: r.limitPerMember === "" || r.limitPerMember == null ? "" : String(r.limitPerMember),
      limitPerBill: r.limitPerBill === "" || r.limitPerBill == null ? "" : String(r.limitPerBill),
      food: { itemId: r.food?.itemId || menu[0]?.id || "" },
      discount: { mode: r.discount?.mode || "amount", value: r.discount?.value ?? "" },
      prize: { itemName: r.prize?.itemName || "" },
    });
    setShowForm(true);
  }
  function submit() {
    if (!form.name || !form.points) return;
    const payload = {
      type: form.type, name: form.name, startDate: form.startDate, endDate: form.endDate,
      quota: form.quota === "" ? "" : Number(form.quota), points: Number(form.points),
      limitPerMember: form.limitPerMember === "" ? "" : Number(form.limitPerMember),
      limitPerBill: form.limitPerBill === "" ? "" : Number(form.limitPerBill),
      food: { itemId: form.food.itemId },
      discount: { mode: form.discount.mode, value: Number(form.discount.value) || 0 },
      prize: { itemName: form.prize.itemName },
    };
    if (form.id) {
      setRewards(prev => prev.map(r => r.id === form.id ? { ...r, ...payload } : r));
    } else {
      setRewards(prev => [...prev, { id: "r" + Date.now(), usedCount: 0, redemptionsByMember: {}, ...payload }]);
    }
    setShowForm(false);
  }

  function openRedeem(reward) {
    setRedeeming(reward);
    setPhone("");
    setRedeemed(false);
  }
  function confirmRedeem() {
    if (!member || !canRedeem) return;
    setMembers(prev => prev.map(m => m.id === member.id ? { ...m, points: m.points - redeeming.points } : m));
    setRewards(prev => prev.map(r => r.id === redeeming.id
      ? { ...r, usedCount: (r.usedCount || 0) + 1, redemptionsByMember: { ...r.redemptionsByMember, [member.id]: (r.redemptionsByMember?.[member.id] || 0) + 1 } }
      : r));
    setHistory(prev => [{
      id: "h" + Date.now(), member: member.name, date: new Date().toISOString().slice(0, 10),
      action: `แลกของรางวัล: ${redeeming.name}`, amount: 0, pointChange: `-${redeeming.points}`,
    }, ...prev]);
    setRedeemed(true);
  }

  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="แลกของรางวัล" subtitle="คลังของรางวัลให้สมาชิกแลกด้วยแต้ม"
        right={<Btn onClick={openForm}><Plus size={14} /> เพิ่มของรางวัล</Btn>} />
      <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4">
        {rewards.map(r => {
          const typeInfo = REWARD_TYPES.find(t => t.key === r.type) || REWARD_TYPES[0];
          const remaining = remainingQuota(r);
          const soldOut = remaining !== null && remaining <= 0;
          return (
            <Card key={r.id} className="p-4 flex flex-col">
              <div className="flex items-start justify-between mb-2">
                <typeInfo.icon size={20} className="text-amber-600" />
                <button onClick={() => startEdit(r)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
              </div>
              <div className="font-medium text-stone-800 text-sm">{r.name}</div>
              <div className="text-xs text-stone-500 mt-1">{rewardDetail(r)}</div>
              {(r.startDate || r.endDate) && (
                <div className="text-[11px] text-stone-400 mt-1">{fmtDate(r.startDate)} – {fmtDate(r.endDate)}</div>
              )}
              <div className="text-xs text-stone-400 mt-2 flex-1">
                สิทธิ์คงเหลือ {remaining === null ? "ไม่จำกัด" : remaining}
                {r.limitPerMember !== "" && r.limitPerMember != null && <div>จำกัด {r.limitPerMember} สิทธิ์/บัญชี</div>}
                {r.limitPerBill !== "" && r.limitPerBill != null && <div>ใช้ได้ {r.limitPerBill} สิทธิ์/บิล</div>}
              </div>
              <div className="flex items-center justify-between mt-3">
                <span className="font-mono text-amber-700 font-semibold">{r.points} แต้ม</span>
                <Btn variant="subtle" disabled={soldOut} onClick={() => openRedeem(r)}>
                  แลก
                </Btn>
              </div>
            </Card>
          );
        })}
      </div>

      {/* Add reward popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขของรางวัล" : "เพิ่มของรางวัลใหม่"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="mb-3">
              <div className="text-xs font-medium text-stone-500 mb-2">ประเภทของรางวัล</div>
              <SegmentedChoice value={form.type} onChange={v => setForm({ ...form, type: v })}
                options={REWARD_TYPES.map(t => ({ value: t.key, label: t.label }))} />
            </div>

            <div className="space-y-3">
              <Field label="ชื่อของรางวัล"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น เครื่องดื่มฟรี 1 แก้ว" autoFocus /></Field>

              <div className="grid grid-cols-2 gap-3">
                <Field label="วันที่เริ่มโปร"><input type="date" className={inputCls} value={form.startDate} onChange={e => setForm({ ...form, startDate: e.target.value })} /></Field>
                <Field label="วันที่สิ้นสุดโปร"><input type="date" className={inputCls} value={form.endDate} onChange={e => setForm({ ...form, endDate: e.target.value })} /></Field>
              </div>

              <div className="grid grid-cols-3 gap-3">
                <Field label="จำนวนสิทธิ์ที่ใช้ได้ (เว้นว่าง = ไม่จำกัด)"><input type="number" className={inputCls} value={form.quota} onChange={e => setForm({ ...form, quota: e.target.value })} placeholder="เช่น 20" /></Field>
                <Field label="1 บัญชีแลกได้เพียง (สิทธิ์) — เว้นว่าง = ไม่จำกัด">
                  <input type="number" min={1} className={inputCls} value={form.limitPerMember} onChange={e => setForm({ ...form, limitPerMember: e.target.value })} placeholder="เช่น 1" />
                </Field>
                <Field label="ใช้ได้ (สิทธิ์) / บิล — เว้นว่าง = ไม่จำกัด">
                  <input type="number" min={1} className={inputCls} value={form.limitPerBill} onChange={e => setForm({ ...form, limitPerBill: e.target.value })} placeholder="เช่น 1" />
                </Field>
              </div>

              <Field label="ใช้แต้มแลก"><input type="number" className={inputCls} value={form.points} onChange={e => setForm({ ...form, points: e.target.value })} placeholder="เช่น 100" /></Field>

              {form.type === "food" && (
                <Field label="เมนูอาหาร/เครื่องดื่มที่แลกได้">
                  <select className={inputCls} value={form.food.itemId} onChange={e => setForm({ ...form, food: { itemId: e.target.value } })}>
                    {categories.map(cat => (
                      <optgroup key={cat.id} label={cat.name}>
                        {menu.filter(m => m.catId === cat.id).map(m => <option key={m.id} value={m.id}>{m.name}</option>)}
                      </optgroup>
                    ))}
                  </select>
                </Field>
              )}

              {form.type === "discount" && (
                <div className="grid grid-cols-2 gap-3">
                  <Field label="รูปแบบส่วนลด">
                    <SegmentedChoice value={form.discount.mode} onChange={v => setForm({ ...form, discount: { ...form.discount, mode: v } })}
                      options={[{ value: "amount", label: "บาท" }, { value: "percent", label: "%" }]} />
                  </Field>
                  <Field label={form.discount.mode === "percent" ? "ส่วนลด (%)" : "ส่วนลด (บาท)"}>
                    <input type="number" className={inputCls} value={form.discount.value} onChange={e => setForm({ ...form, discount: { ...form.discount, value: e.target.value } })} />
                  </Field>
                </div>
              )}

              {form.type === "prize" && (
                <Field label="รายการของรางวัลที่ได้รับ"><input className={inputCls} value={form.prize.itemName} onChange={e => setForm({ ...form, prize: { itemName: e.target.value } })} placeholder="เช่น ตุ๊กตา, ร่ม" /></Field>
              )}
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "เพิ่มของรางวัล"}</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Redeem popup */}
      {redeeming && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setRedeeming(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">แลกของรางวัล</div>
              <button onClick={() => setRedeeming(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-sm text-stone-600 mt-2">{redeeming.name} · <span className="font-mono text-amber-700">{redeeming.points} แต้ม</span></div>
            <div className="text-xs text-stone-400 mt-0.5">{rewardDetail(redeeming)}</div>

            {redeemed ? (
              <div className="text-center py-6">
                <CheckCircle2 size={32} className="text-emerald-500 mx-auto mb-2" />
                <div className="text-sm font-medium text-stone-800">แลกของรางวัลสำเร็จ</div>
                <div className="text-xs text-stone-400 mt-1">{member.name} · แต้มคงเหลือ {(member.points - redeeming.points).toLocaleString()}</div>
                <Btn className="mt-4" onClick={() => setRedeeming(null)}>เสร็จสิ้น</Btn>
              </div>
            ) : (
              <>
                <div className="mt-4">
                  <Field label="เบอร์โทรสมาชิก">
                    <input className={inputCls} value={phone} onChange={e => setPhone(e.target.value)} placeholder="08x-xxx-xxxx" autoFocus />
                  </Field>
                </div>

                {phone.trim() !== "" && (
                  member ? (
                    <div className={`mt-3 p-3 rounded-lg border text-sm ${canRedeem ? "border-emerald-200 bg-emerald-50" : "border-rose-200 bg-rose-50"}`}>
                      <div className="font-medium text-stone-800">{member.name}</div>
                      <div className="text-xs text-stone-500 mt-0.5">แต้มสะสม {member.points.toLocaleString()} แต้ม</div>
                      {!enoughPoints && <div className="text-xs text-rose-500 mt-1">แต้มไม่เพียงพอ ต้องใช้ {redeeming.points} แต้ม</div>}
                      {limitReached && <div className="text-xs text-rose-500 mt-1">บัญชีนี้แลกของรางวัลนี้ครบสิทธิ์แล้ว ({memberRedeemedCount}/{redeeming.limitPerMember})</div>}
                    </div>
                  ) : (
                    <div className="mt-3 p-3 rounded-lg border border-stone-200 bg-stone-50 text-sm text-stone-400">ไม่พบสมาชิกด้วยเบอร์นี้</div>
                  )
                )}

                <Btn className="w-full justify-center mt-4" disabled={!member || !canRedeem} onClick={confirmRedeem}>ยืนยันแลกของรางวัล</Btn>
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: HISTORY
   ========================================================================= */

function HistoryPage({ history }) {
  const exportRows = history.map(h => ({
    "วันที่": fmtDate(h.date), "เวลา": h.time || "", "สมาชิก": h.member,
    "รายการ": h.action, "ยอดใช้จ่าย": h.amount, "แต้มที่เปลี่ยนแปลง": h.pointChange,
  }));
  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="ประวัติการใช้บริการ" subtitle="ประวัติการมาใช้บริการและการแลกแต้ม"
        right={<ExportButton data={exportRows} filename="ประวัติการใช้บริการ" sheetName="History" />} />
      <Card>
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
              <th className="px-4 py-3 font-medium">วันที่</th>
              <th className="px-4 py-3 font-medium">สมาชิก</th>
              <th className="px-4 py-3 font-medium">รายการ</th>
              <th className="px-4 py-3 font-medium text-right">ยอดใช้จ่าย</th>
              <th className="px-4 py-3 font-medium text-right">แต้มเปลี่ยนแปลง</th>
            </tr>
          </thead>
          <tbody>
            {history.map(h => (
              <tr key={h.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                <td className="px-4 py-3 text-stone-400 font-mono">{fmtDate(h.date)}</td>
                <td className="px-4 py-3 font-medium text-stone-800">{h.member}</td>
                <td className="px-4 py-3 text-stone-600">{h.action}</td>
                <td className="px-4 py-3 text-right font-mono text-stone-600">{h.amount ? `฿${h.amount}` : "-"}</td>
                <td className={`px-4 py-3 text-right font-mono font-medium ${h.pointChange.startsWith("+") ? "text-emerald-600" : "text-rose-500"}`}>{h.pointChange}</td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </Card>
    </div>
  );
}

/* =========================================================================
   PAGE: หน้าร้าน — ประวัติใบเสร็จ
   ========================================================================= */

function ReceiptHistoryPage({ history, financeAccounts, storeInfo, paymentSettings, branches, currentBranchId, printers }) {
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [query, setQuery] = useState("");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const [viewingReceipt, setViewingReceipt] = useState(null);

  function accountName(id) {
    const a = financeAccounts?.find(x => x.id === id);
    return a ? financeAccountDisplayName(a) : "-";
  }
  function paymentChannelLabel(h) {
    if (h.splitPayments?.length > 0) {
      return h.splitPayments.map(p => `${accountName(p.methodId)} ฿${fmtMoney(p.amount)}`).join(" + ");
    }
    return accountName(h.financeAccountId);
  }
  function branchName(id) {
    return branches?.find(b => b.id === id)?.name || "-";
  }

  const bills = history
    .filter(h => h.amount > 0)
    .filter(h => h.date.slice(0, 7) === monthFilter)
    .filter(h => !effectiveBranchId || h.branchId === effectiveBranchId)
    .filter(h => !query || h.member.includes(query) || h.action.includes(query))
    .sort((a, b) => (b.date + (b.time || "")).localeCompare(a.date + (a.time || "")));

  const totalThisMonth = bills.reduce((s, h) => s + h.amount, 0);

  const todayStr = new Date().toISOString().slice(0, 10);
  const billsToday = history
    .filter(h => h.amount > 0 && h.date === todayStr)
    .filter(h => !effectiveBranchId || h.branchId === effectiveBranchId);
  const totalToday = billsToday.reduce((s, h) => s + h.amount, 0);

  const exportRows = bills.map(h => ({
    "เลขที่ใบเสร็จ": h.receiptNumber || "-", "วันที่": fmtDate(h.date), "เวลา": h.time || "-", "รายการ": h.action, "ลูกค้า/สมาชิก": h.member,
    "ช่องทางชำระ": paymentChannelLabel(h), "ยอดรวม": h.amount,
    "ใบกำกับภาษี": h.taxInvoice ? "มี" : "-",
  }));

  const vatRate = paymentSettings?.vat?.rate || 7;
  const vatEnabled = !!paymentSettings?.vat?.enabled;

  return (
    <div>
      <PageHeader eyebrow="หน้าร้าน" title="ประวัติใบเสร็จ" subtitle="ดูและพิมพ์ใบเสร็จย้อนหลังของทุกบิลที่ปิดแล้ว" />

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        <input className={`${inputCls} max-w-[220px]`} placeholder="ค้นหาชื่อลูกค้า/รายการ" value={query} onChange={e => setQuery(e.target.value)} />
        {!currentBranchId && branches && branches.length > 0 && (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        )}
        {currentBranchId && (
          <span className="text-xs px-3 py-1.5 rounded-full bg-stone-100 text-stone-600 font-medium">{branchName(currentBranchId)}</span>
        )}
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`ประวัติใบเสร็จ-${monthFilter}`} sheetName="Receipts" />
        </div>
      </div>

      <div className="flex flex-wrap gap-4 mb-5">
        <Card className="p-4 max-w-xs flex-1 min-w-[200px]">
          <div className="text-xs text-stone-400">ยอดขายวันนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(totalToday)}</div>
          <div className="text-[11px] text-stone-400 mt-0.5">{billsToday.length} ใบเสร็จ</div>
        </Card>
        <Card className="p-4 max-w-xs flex-1 min-w-[200px]">
          <div className="text-xs text-stone-400">ยอดขายรวมเดือนนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(totalThisMonth)}</div>
          <div className="text-[11px] text-stone-400 mt-0.5">{bills.length} ใบเสร็จ</div>
        </Card>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">เลขที่ใบเสร็จ</th>
                <th className="px-4 py-3 font-medium">วันที่/เวลา</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                <th className="px-4 py-3 font-medium">รายการ</th>
                <th className="px-4 py-3 font-medium">ลูกค้า/สมาชิก</th>
                <th className="px-4 py-3 font-medium">ช่องทางชำระ</th>
                <th className="px-4 py-3 font-medium">ยอดรวม</th>
                <th className="px-4 py-3 font-medium">ใบกำกับภาษี</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {bills.map(h => (
                <tr key={h.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 font-mono text-stone-500">{h.receiptNumber || "-"}</td>
                  <td className="px-4 py-3 text-stone-400">{fmtDate(h.date)}{h.time && <div className="text-[11px]">{h.time} น.</div>}</td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{h.branchId ? branchName(h.branchId) : "-"}</td>}
                  <td className="px-4 py-3 text-stone-600">{h.action}</td>
                  <td className="px-4 py-3 font-medium text-stone-800">{h.member}</td>
                  <td className="px-4 py-3 text-stone-500">{paymentChannelLabel(h)}</td>
                  <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(h.amount)}</td>
                  <td className="px-4 py-3">
                    {h.taxInvoice ? (
                      <span className="text-xs px-2 py-0.5 rounded border font-medium bg-sky-50 text-sky-700 border-sky-300">มี</span>
                    ) : <span className="text-stone-300 text-xs">-</span>}
                  </td>
                  <td className="px-4 py-3">
                    <button onClick={() => setViewingReceipt(h)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1">
                      <ReceiptText size={12} /> ดูใบเสร็จ
                    </button>
                  </td>
                </tr>
              ))}
              {bills.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 8 : 9} className="px-4 py-10 text-center text-stone-400">ไม่พบใบเสร็จในเดือนนี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      <p className="text-xs text-stone-400 mt-3">
        หมายเหตุ: บิลที่ปิดตั้งแต่ตอนนี้เป็นต้นไปจะบันทึกรายการอาหารแบบละเอียดไว้ด้วย ดูใบเสร็จแบบแจกแจงทีละจานได้ครบถ้วน — บิลเก่าที่ปิดไปก่อนหน้านี้ (ก่อนมีการเก็บข้อมูลนี้) จะแสดงได้เฉพาะยอดรวมเท่านั้น
      </p>

      {/* View / print receipt popup */}
      {viewingReceipt && (() => {
        const h = viewingReceipt;
        const vatAmt = vatEnabled ? Math.round(h.amount * vatRate / (100 + vatRate) * 100) / 100 : 0;
        const baseAmt = h.amount - vatAmt;
        function buildReprintDoc() {
          const blocks = [
            { type: "text", value: h.receiptCompanyInfo?.name || storeInfo?.companyName || storeInfo?.name, align: "center", bold: true },
          ];
          const addr = h.receiptCompanyInfo?.address || storeInfo?.address;
          const taxId = h.receiptCompanyInfo?.taxId || storeInfo?.taxId;
          const phone = h.receiptCompanyInfo?.phone || storeInfo?.phone;
          if (addr) blocks.push({ type: "text", value: addr, align: "center" });
          if (taxId) blocks.push({ type: "text", value: `TAX ID: ${taxId}${h.receiptCompanyInfo?.officeType ? ` (${h.receiptCompanyInfo.officeType})` : ""}`, align: "center" });
          if (phone) blocks.push({ type: "text", value: `Tel: ${phone}`, align: "center" });
          blocks.push({ type: "text", value: !vatEnabled ? "ใบเสร็จรับเงิน" : h.taxInvoice ? "ใบเสร็จรับเงิน/ใบกำกับภาษี" : "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ", align: "center", bold: true });
          blocks.push({ type: "rule" });
          blocks.push({ type: "row", left: "ID", right: h.receiptNumber || "-" });
          if (h.staffDisplayName) blocks.push({ type: "row", left: "Staff", right: h.staffDisplayName });
          blocks.push({ type: "row", left: "Date/Time", right: `${fmtDate(h.date)} ${h.time || ""}` });
          blocks.push({ type: "text", value: `รายการ: ${h.action}` });
          blocks.push({ type: "text", value: `ลูกค้า/สมาชิก: ${h.member}` });
          blocks.push({ type: "rule" });
          (h.items || []).forEach(it => blocks.push({ type: "row", left: `${it.qty} ${it.name}`, right: fmtMoney(it.unitPrice * it.qty) }));
          blocks.push({ type: "rule" });
          if (vatEnabled) {
            blocks.push({ type: "row", left: "ก่อน VAT", right: fmtMoney(baseAmt) });
            blocks.push({ type: "row", left: `VAT ${vatRate}%`, right: fmtMoney(vatAmt) });
          }
          blocks.push({ type: "row", left: "ยอดรวมทั้งสิ้น", right: fmtMoney(h.amount), bold: true });
          return { charsPerLine: 32, cut: true, blocks };
        }
        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setViewingReceipt(null)}>
            <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-3">
                <div className="font-semibold text-stone-800">ใบเสร็จ</div>
                <div className="flex items-center gap-2">
                  <Btn variant="ghost" onClick={async () => {
                    const eligiblePrinter = (printers || []).find(p => p.connected && p.reprintEnabled && (!p.branchId || p.branchId === currentBranchId));
                    const ok = eligiblePrinter ? await printViaAgent("receipt", buildReprintDoc()) : false;
                    if (!ok) printReceiptPage();
                  }}><Printer size={14} /></Btn>
                  <Btn variant="ghost" onClick={() => downloadPrintTemplate("#receiptViewCard", `ใบเสร็จ-${h.receiptNumber || h.id}.html`)}><Download size={14} /></Btn>
                  <button onClick={() => setViewingReceipt(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
                </div>
              </div>

              <div id="receiptViewCard">
              <div className="text-center mb-2">
                <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-10 h-10 rounded-lg object-cover mx-auto mb-1" />
                <div className="font-semibold text-stone-800">{h.receiptCompanyInfo?.name || storeInfo?.companyName || storeInfo?.name}</div>
                {h.branchId && <div className="text-xs text-stone-400">{branchName(h.branchId)}</div>}
                {(h.receiptCompanyInfo?.address || storeInfo?.address) && <div className="text-[11px] text-stone-400 mt-0.5">{h.receiptCompanyInfo?.address || storeInfo.address}</div>}
                {(h.receiptCompanyInfo?.taxId || storeInfo?.taxId) && <div className="text-[11px] text-stone-400">TAX ID: {h.receiptCompanyInfo?.taxId || storeInfo.taxId}{h.receiptCompanyInfo?.officeType ? ` (${h.receiptCompanyInfo.officeType})` : ""}</div>}
                {(h.receiptCompanyInfo?.phone || storeInfo?.phone) && <div className="text-[11px] text-stone-400">Tel: {h.receiptCompanyInfo?.phone || storeInfo.phone}</div>}
              </div>

              <div className="text-center font-semibold text-stone-700 text-sm mt-3">{!vatEnabled ? "ใบเสร็จรับเงิน" : h.taxInvoice ? "ใบเสร็จรับเงิน/ใบกำกับภาษี" : "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ"}</div>
              {vatEnabled && <div className="text-center text-[11px] text-stone-400 mb-2">รวมภาษีมูลค่าเพิ่ม</div>}

              <div className="text-xs text-stone-500 space-y-1 border-t border-b border-dashed border-stone-300 py-2 mb-2 mt-2">
                <div className="flex justify-between"><span>ID</span><span className="font-mono">{h.receiptNumber || "-"}</span></div>
                {h.staffDisplayName && <div className="flex justify-between"><span>Staff</span><span>{h.staffDisplayName}</span></div>}
                <div className="flex justify-between"><span>Date/Time</span><span>{fmtDate(h.date)} {h.time || ""}</span></div>
                <div className="flex justify-between"><span>รายการ</span><span>{h.action}</span></div>
                <div className="flex justify-between"><span>ลูกค้า/สมาชิก</span><span>{h.member}</span></div>
              </div>

              {h.items && h.items.length > 0 ? (
                <div className="text-sm space-y-1 mb-2 border-b border-dashed border-stone-300 pb-2">
                  {h.items.map((it, i) => (
                    <div key={i} className="flex justify-between text-stone-700">
                      <span>{it.qty} {it.name}</span>
                      <span className="font-mono">฿{fmtMoney(it.unitPrice * it.qty)}</span>
                    </div>
                  ))}
                </div>
              ) : (
                <div className="text-xs text-stone-300 text-center mb-2 border-b border-dashed border-stone-300 pb-2">ไม่มีข้อมูลรายการอาหารสำหรับบิลนี้ (บันทึกก่อนระบบจะเก็บรายการละเอียด)</div>
              )}

              <div className="text-sm space-y-1 mb-2">
                {vatEnabled && (
                  <>
                    <div className="flex justify-between text-stone-500"><span>Before Tax</span><span className="font-mono">฿{fmtMoney(baseAmt)}</span></div>
                    <div className="flex justify-between text-stone-500"><span>TAX ({vatRate}%)</span><span className="font-mono">฿{fmtMoney(vatAmt)}</span></div>
                  </>
                )}
                <div className="flex justify-between font-semibold text-stone-800 pt-1 border-t border-stone-200"><span>Total</span><span className="font-mono">฿{fmtMoney(h.amount)}</span></div>
                <div className="flex justify-between text-stone-500 pt-1"><span>{paymentChannelGroupLabel(financeAccounts?.find(x => x.id === h.financeAccountId))}</span><span className="font-mono">฿{fmtMoney(h.amount)}</span></div>
              </div>

              {h.taxInvoice && (
                <div className="text-xs text-stone-500 border-t border-dashed border-stone-300 pt-2 space-y-0.5">
                  <div className="font-medium text-stone-600">ข้อมูลใบกำกับภาษี (ผู้ซื้อ) — {h.taxInvoice.type === "corporate" ? "นิติบุคคล" : "บุคคลธรรมดา"}</div>
                  <div>{h.taxInvoice.type === "corporate" ? "ชื่อบริษัท" : "ชื่อ"}: {h.taxInvoice.name || "-"}</div>
                  <div>{h.taxInvoice.type === "corporate" ? "เลขผู้เสียภาษี" : "เลขบัตรประชาชน"}: {h.taxInvoice.taxId || "-"}</div>
                  {h.taxInvoice.type === "corporate" && <div>สำนักงานใหญ่/สาขา: {h.taxInvoice.branch || "-"}</div>}
                  <div>ที่อยู่: {h.taxInvoice.address || "-"}</div>
                </div>
              )}
              </div>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

/* =========================================================================
   PAGE: หน้าร้าน — ประวัติการยกเลิก
   ========================================================================= */

function CancelHistoryPage({ cancelHistory, tables, currentBranchId, branches }) {
  const [query, setQuery] = useState("");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;

  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  const filtered = cancelHistory
    .filter(h => !effectiveBranchId || !h.branchId || h.branchId === effectiveBranchId)
    .filter(h => !query || h.item.includes(query) || h.by.includes(query) || h.table.includes(query));

  const exportRows = filtered.map(h => ({
    "วันที่/เวลา": h.time, "สาขา": branchNameFor(h.branchId) || "-", "เลขที่บิล": h.billNo || "-", "โต๊ะ": h.table,
    "รายการที่ยกเลิก": h.item, "เหตุผล": h.reason, "ยกเลิกโดย": h.by, "อนุมัติโดย": h.approvedBy || "-",
  }));

  return (
    <div>
      <PageHeader eyebrow="หน้าร้าน" title="ประวัติการยกเลิก" subtitle="ประวัติการยกเลิก/void รายการอาหารและการจองโต๊ะ"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <ExportButton data={exportRows} filename="ประวัติการยกเลิก" sheetName="CancelHistory" />
          </div>
        } />

      <div className="relative max-w-md mb-4">
        <Search size={18} className="absolute left-3.5 top-3 text-stone-400" />
        <input className={`${inputCls} pl-10 py-2.5 text-base`} placeholder="ค้นหาโต๊ะ, รายการ, หรือชื่อผู้ยกเลิก" value={query} onChange={e => setQuery(e.target.value)} />
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">วันที่/เวลา</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                <th className="px-4 py-3 font-medium">เลขที่บิล</th>
                <th className="px-4 py-3 font-medium">โต๊ะ</th>
                <th className="px-4 py-3 font-medium">รายการที่ยกเลิก</th>
                <th className="px-4 py-3 font-medium">เหตุผล</th>
                <th className="px-4 py-3 font-medium">ยกเลิกโดย</th>
                <th className="px-4 py-3 font-medium">อนุมัติโดย</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(h => (
                <tr key={h.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 text-stone-400">{h.time}</td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchNameFor(h.branchId) || "-"}</td>}
                  <td className="px-4 py-3 font-mono text-stone-500">{h.billNo || "-"}</td>
                  <td className="px-4 py-3 text-stone-600">โต๊ะ {h.table}</td>
                  <td className="px-4 py-3 font-medium text-stone-800">{h.item}</td>
                  <td className="px-4 py-3 text-stone-500">{h.reason}</td>
                  <td className="px-4 py-3 text-stone-500">{h.by}</td>
                  <td className="px-4 py-3 text-stone-500">{h.approvedBy || "-"}</td>
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 7 : 8} className="px-4 py-10 text-center text-stone-400">ไม่พบประวัติการยกเลิก</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
    </div>
  );
}

/* =========================================================================
   PAGE: ADD MENU
   ========================================================================= */

function AddMenuPage({ menu, setMenu, categories, channels, stockItems, staff, positions, ownerProfile, currentBranchId, branches }) {
  const emptyForm = { id: null, name: "", price: "", catId: categories[0]?.id, desc: "", imageDataUrl: null, channelPrices: {}, optionGroups: [], recipe: [], branchIds: currentBranchId ? [currentBranchId] : [] };
  const [form, setForm] = useState(emptyForm);
  const [showForm, setShowForm] = useState(false);
  const [expandedChoiceRecipes, setExpandedChoiceRecipes] = useState({});
  const [deletingItem, setDeletingItem] = useState(null);
  const [deletePin, setDeletePin] = useState("");
  const [deletePinError, setDeletePinError] = useState("");
  const imageInputRef = useRef(null);
  // Bulk "add via Excel" — download a template, fill it in, upload it back.
  const [excelImportOpen, setExcelImportOpen] = useState(false);
  const [excelPreview, setExcelPreview] = useState(null); // { validItems: [], errors: [] }
  const [excelParsing, setExcelParsing] = useState(false);
  const excelFileInputRef = useRef(null);
  // Grid column count is measured from the actual window width in JS rather
  // than left to Tailwind's sm:/md: breakpoints alone — some embedded/preview
  // viewports report a CSS width that the responsive utility classes don't
  // pick up correctly, so measuring directly keeps this reliable everywhere.
  const [windowWidth, setWindowWidth] = useState(() => (typeof window !== "undefined" ? window.innerWidth : 1024));
  useEffect(() => {
    function handleResize() { setWindowWidth(window.innerWidth); }
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);
  const menuGridColsClass = windowWidth >= 768 ? "grid-cols-6" : windowWidth >= 640 ? "grid-cols-3" : "grid-cols-2";
  // Branch owners only see their own branch's menu; Central mode sees everything.
  const visibleMenu = menu.filter(m => !currentBranchId || !m.branchIds?.length || m.branchIds.includes(currentBranchId));
  function toggleFormBranch(branchId) {
    setForm(f => ({ ...f, branchIds: f.branchIds.includes(branchId) ? f.branchIds.filter(id => id !== branchId) : [...f.branchIds, branchId] }));
  }

  function confirmDeleteItem() {
    const manager = (staff || []).find(s => s.pin === deletePin && s.active);
    const isOwner = isOwnerPin(ownerProfile, deletePin);
    if (!manager && !isOwner) {
      setDeletePinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    if (manager && !isOwner) {
      const position = (positions || []).find(p => p.id === manager.positionId);
      if (!position?.pinPermissions?.includes("menuItemDelete")) {
        setDeletePinError(`ตำแหน่ง "${position?.name || "-"}" ไม่มีสิทธิ์อนุมัติรายการนี้`);
        return;
      }
    }
    removeItem(deletingItem.id);
    setDeletePin("");
    setDeletePinError("");
  }

  function priceForChannel(item, ch) {
    const override = item.channelPrices?.[ch.id];
    if (override !== undefined && override !== null && override !== "") return Number(override);
    if (ch.adjustType === "percent") return Math.round(item.price * (1 + ch.value / 100));
    if (ch.adjustType === "fixed") return item.price + ch.value;
    return item.price;
  }

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }
  function saveItem() {
    if (!form.name || !form.price) return;
    if (form.id) {
      setMenu(prev => prev.map(m => m.id === form.id ? { ...form, price: Number(form.price) } : m));
    } else {
      setMenu(prev => [...prev, { ...form, id: "m" + Date.now(), price: Number(form.price) }]);
    }
    setShowForm(false);
  }
  function editItem(m) {
    setForm({ id: m.id, name: m.name, price: String(m.price), catId: m.catId, desc: m.desc || "", imageDataUrl: m.imageDataUrl || null, channelPrices: m.channelPrices || {}, optionGroups: m.optionGroups || [], recipe: m.recipe || [], branchIds: m.branchIds || [] });
    setShowForm(true);
  }
  function removeItem(id) {
    setMenu(prev => prev.filter(m => m.id !== id));
    setDeletingItem(null);
  }
  function handleImage(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => setForm(prev => ({ ...prev, imageDataUrl: reader.result }));
    reader.readAsDataURL(file);
  }

  function downloadMenuExcelTemplate() {
    const sampleRows = [
      { "ชื่อเมนู": "ผัดกะเพราหมูสับ", "หมวดหมู่": categories[0]?.name || "", "ราคา": 65, "คำอธิบาย": "ราดข้าว ไข่ดาว 1 ฟอง" },
      { "ชื่อเมนู": "", "หมวดหมู่": "", "ราคา": "", "คำอธิบาย": "" },
    ];
    const categoryRows = categories.map(c => ({ "ชื่อหมวดหมู่ที่ใช้ได้": c.name }));
    const wb = XLSX.utils.book_new();
    const wsMenu = XLSX.utils.json_to_sheet(sampleRows);
    XLSX.utils.book_append_sheet(wb, wsMenu, "เมนู");
    const wsCat = XLSX.utils.json_to_sheet(categoryRows.length ? categoryRows : [{ "ชื่อหมวดหมู่ที่ใช้ได้": "" }]);
    XLSX.utils.book_append_sheet(wb, wsCat, "หมวดหมู่ที่ใช้ได้");
    XLSX.writeFile(wb, "เทมเพลตเพิ่มเมนูอาหาร.xlsx");
  }

  function openExcelImport() {
    setExcelPreview(null);
    setExcelImportOpen(true);
  }

  function parseMenuExcelRows(rows) {
    const validItems = [];
    const errors = [];
    rows.forEach((row, i) => {
      const rowNum = i + 2; // header occupies row 1 in the spreadsheet
      const name = String(row["ชื่อเมนู"] ?? "").trim();
      const catName = String(row["หมวดหมู่"] ?? "").trim();
      const priceRaw = row["ราคา"];
      const desc = String(row["คำอธิบาย"] ?? "").trim();
      if (!name && !catName && (priceRaw === undefined || priceRaw === "")) return; // skip fully blank rows
      if (!name) { errors.push(`แถวที่ ${rowNum}: ไม่ได้กรอกชื่อเมนู`); return; }
      if (!catName) { errors.push(`แถวที่ ${rowNum} (${name}): ไม่ได้ระบุหมวดหมู่`); return; }
      const cat = categories.find(c => c.name === catName);
      if (!cat) { errors.push(`แถวที่ ${rowNum} (${name}): ไม่พบหมวดหมู่ "${catName}" — ต้องตรงกับชื่อหมวดหมู่ที่มีอยู่ในระบบ (ดูรายชื่อได้ในชีท "หมวดหมู่ที่ใช้ได้")`); return; }
      const price = Number(priceRaw);
      if (priceRaw === undefined || priceRaw === "" || isNaN(price) || price <= 0) { errors.push(`แถวที่ ${rowNum} (${name}): ราคาต้องเป็นตัวเลขมากกว่า 0`); return; }
      validItems.push({
        id: "m" + Date.now() + Math.random().toString(36).slice(2, 7),
        name, price, catId: cat.id, desc,
        imageDataUrl: null, channelPrices: {}, optionGroups: [], recipe: [],
        branchIds: currentBranchId ? [currentBranchId] : [],
      });
    });
    return { validItems, errors };
  }

  function handleExcelFile(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    setExcelParsing(true);
    setExcelPreview(null);
    const reader = new FileReader();
    reader.onload = evt => {
      try {
        const data = new Uint8Array(evt.target.result);
        const wb = XLSX.read(data, { type: "array" });
        const sheet = wb.Sheets[wb.SheetNames[0]];
        const rows = XLSX.utils.sheet_to_json(sheet, { defval: "" });
        setExcelPreview(parseMenuExcelRows(rows));
      } catch {
        setExcelPreview({ validItems: [], errors: ["ไม่สามารถอ่านไฟล์นี้ได้ กรุณาตรวจสอบว่าเป็นไฟล์ Excel (.xlsx) ที่ถูกต้อง"] });
      }
      setExcelParsing(false);
    };
    reader.readAsArrayBuffer(file);
  }

  function confirmExcelImport() {
    if (!excelPreview || excelPreview.validItems.length === 0) return;
    setMenu(prev => [...prev, ...excelPreview.validItems]);
    setExcelImportOpen(false);
    setExcelPreview(null);
    if (excelFileInputRef.current) excelFileInputRef.current.value = "";
  }

  function addRecipeRow() {
    setForm(prev => ({ ...prev, recipe: [...prev.recipe, { stockItemId: stockItems[0]?.id || "", qty: "" }] }));
  }
  function updateRecipeRow(i, patch) {
    setForm(prev => ({ ...prev, recipe: prev.recipe.map((r, idx) => idx === i ? { ...r, ...patch } : r) }));
  }
  function removeRecipeRow(i) {
    setForm(prev => ({ ...prev, recipe: prev.recipe.filter((_, idx) => idx !== i) }));
  }

  function setChannelPrice(chId, value) {
    setForm(prev => ({ ...prev, channelPrices: { ...prev.channelPrices, [chId]: value } }));
  }

  function addGroup() {
    setForm(prev => ({ ...prev, optionGroups: [...prev.optionGroups, { id: "og" + Date.now(), name: "", type: "single", required: true, max: 1, choices: [] }] }));
  }
  function updateGroup(gid, patch) {
    setForm(prev => ({ ...prev, optionGroups: prev.optionGroups.map(g => g.id === gid ? { ...g, ...patch } : g) }));
  }
  function removeGroup(gid) {
    setForm(prev => ({ ...prev, optionGroups: prev.optionGroups.filter(g => g.id !== gid) }));
  }
  function addChoice(gid) {
    setForm(prev => ({ ...prev, optionGroups: prev.optionGroups.map(g => g.id === gid ? { ...g, choices: [...g.choices, { id: "oc" + Date.now() + Math.random().toString(36).slice(2, 5), name: "", price: 0 }] } : g) }));
  }
  function updateChoice(gid, cid, patch) {
    setForm(prev => ({ ...prev, optionGroups: prev.optionGroups.map(g => g.id === gid ? { ...g, choices: g.choices.map(c => c.id === cid ? { ...c, ...patch } : c) } : g) }));
  }
  function removeChoice(gid, cid) {
    setForm(prev => ({ ...prev, optionGroups: prev.optionGroups.map(g => g.id === gid ? { ...g, choices: g.choices.filter(c => c.id !== cid) } : g) }));
  }
  function addChoiceRecipeRow(gid, cid) {
    setForm(prev => ({
      ...prev,
      optionGroups: prev.optionGroups.map(g => g.id !== gid ? g : {
        ...g,
        choices: g.choices.map(c => c.id !== cid ? c : { ...c, recipe: [...(c.recipe || []), { stockItemId: stockItems[0]?.id || "", qty: "" }] }),
      }),
    }));
    setExpandedChoiceRecipes(prev => ({ ...prev, [cid]: true }));
  }
  function updateChoiceRecipeRow(gid, cid, idx, patch) {
    setForm(prev => ({
      ...prev,
      optionGroups: prev.optionGroups.map(g => g.id !== gid ? g : {
        ...g,
        choices: g.choices.map(c => c.id !== cid ? c : { ...c, recipe: (c.recipe || []).map((r, i) => i === idx ? { ...r, ...patch } : r) }),
      }),
    }));
  }
  function removeChoiceRecipeRow(gid, cid, idx) {
    setForm(prev => ({
      ...prev,
      optionGroups: prev.optionGroups.map(g => g.id !== gid ? g : {
        ...g,
        choices: g.choices.map(c => c.id !== cid ? c : { ...c, recipe: (c.recipe || []).filter((_, i) => i !== idx) }),
      }),
    }));
  }
  function toggleChoiceRecipeExpanded(cid) {
    setExpandedChoiceRecipes(prev => ({ ...prev, [cid]: !prev[cid] }));
  }

  return (
    <div>
      <PageHeader eyebrow="จัดการเมนู" title="เพิ่มเมนูอาหาร" subtitle="เพิ่มเมนู ตั้งราคาตามช่องทางขาย และกำหนดตัวเลือกเสริมของเมนู"
        right={
          <div className="flex items-center gap-2">
            <Btn variant="ghost" onClick={openExcelImport}><FileSpreadsheet size={14} /> เพิ่มเมนูด้วย Excel</Btn>
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มเมนู</Btn>
          </div>
        } />

      <div className={`grid ${menuGridColsClass} gap-4`}>
        {visibleMenu.map(m => {
          const cat = categories.find(c => c.id === m.catId);
          const groupCount = (m.optionGroups || []).length;
          return (
            <Card key={m.id} className="overflow-hidden">
              <div className="aspect-square w-full bg-stone-100 flex items-center justify-center overflow-hidden">
                {m.imageDataUrl ? (
                  <img src={m.imageDataUrl} alt={m.name} className="w-full h-full object-cover" />
                ) : (
                  <UtensilsCrossed size={32} className="text-stone-300" />
                )}
              </div>
              <div className="p-3.5">
                <div className="flex items-start justify-between gap-2">
                  <div className="min-w-0">
                    <div className="font-medium text-stone-800 text-sm truncate">{m.name}</div>
                    <div className="text-xs text-stone-400">{cat?.name}</div>
                  </div>
                  <div className="flex items-center gap-1.5 flex-shrink-0">
                    <button onClick={() => editItem(m)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
                    <button onClick={() => setDeletingItem(m)} className="text-stone-300 hover:text-rose-500"><Trash2 size={14} /></button>
                  </div>
                </div>
                {m.desc && <div className="text-xs text-stone-400 mt-1 line-clamp-2">{m.desc}</div>}
                {!currentBranchId && m.branchIds?.length > 0 && (
                  <div className="flex flex-wrap gap-1 mt-1.5">
                    {m.branchIds.map(id => (
                      <span key={id} className="text-[10px] px-1.5 py-0.5 rounded bg-sky-50 text-sky-700 border border-sky-200">
                        {branches?.find(b => b.id === id)?.name || "-"}
                      </span>
                    ))}
                  </div>
                )}

                <div className="flex items-center justify-between mt-2.5 pt-2.5 border-t border-stone-100">
                  <span className="text-xs text-stone-400">ราคาปกติ</span>
                  <span className="font-mono text-amber-700 font-semibold">฿{fmtMoney(m.price)}</span>
                </div>

                <div className="mt-1.5 space-y-1">
                  {channels.map(ch => (
                    <div key={ch.id} className="flex items-center justify-between text-xs">
                      <span className={`px-1.5 py-0.5 rounded border ${CHANNEL_COLOR[ch.color]}`}>{ch.name}</span>
                      <span className="font-mono text-stone-600">฿{fmtMoney(priceForChannel(m, ch))}</span>
                    </div>
                  ))}
                </div>

                {groupCount > 0 && (
                  <div className="mt-2.5 pt-2 border-t border-stone-100">
                    <span className="text-[10px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">ตัวเลือก {groupCount} กลุ่ม</span>
                  </div>
                )}
              </div>
            </Card>
          );
        })}
        {visibleMenu.length === 0 && (
          <div className="col-span-full text-sm text-stone-400 text-center py-12 border border-dashed border-stone-300 rounded-lg">ยังไม่มีเมนูอาหาร กด "+ เพิ่มเมนู" เพื่อเริ่มต้น</div>
        )}
      </div>

      {/* Add / edit menu popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-2xl p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขเมนู" : "เพิ่มเมนูใหม่"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="flex gap-4 mb-4">
              <div className="flex-shrink-0">
                <div className="w-28 h-28 rounded-lg bg-stone-100 border border-stone-200 flex items-center justify-center overflow-hidden">
                  {form.imageDataUrl ? (
                    <img src={form.imageDataUrl} alt="" className="w-full h-full object-cover" />
                  ) : (
                    <UtensilsCrossed size={26} className="text-stone-300" />
                  )}
                </div>
                <input ref={imageInputRef} type="file" accept="image/*" className="hidden" onChange={handleImage} />
                <button type="button" onClick={() => imageInputRef.current?.click()} className="text-xs font-medium text-amber-700 hover:text-amber-900 mt-1.5 block">
                  {form.imageDataUrl ? "เปลี่ยนรูป" : "อัปโหลดรูป"}
                </button>
                <div className="text-[10px] text-stone-400 mt-0.5">สัดส่วน 1:1</div>
              </div>
              <div className="flex-1 space-y-3">
                <Field label="ชื่อเมนู"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น เตี๋ยวหมูต้มยำ โบราณ" autoFocus /></Field>
                <div className="grid grid-cols-2 gap-3">
                  <Field label="หมวดหมู่">
                    <select className={inputCls} value={form.catId} onChange={e => setForm({ ...form, catId: e.target.value })}>
                      {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
                    </select>
                  </Field>
                  <Field label="ราคาปกติ (บาท)"><input type="number" className={inputCls} value={form.price} onChange={e => setForm({ ...form, price: e.target.value })} /></Field>
                </div>
              </div>
            </div>
            <Field label="รายละเอียด"><input className={inputCls} value={form.desc} onChange={e => setForm({ ...form, desc: e.target.value })} placeholder="คำอธิบายสั้น ๆ" /></Field>

            {!currentBranchId && branches && branches.length > 0 && (
              <div className="mt-3">
                <div className="text-xs text-stone-500 mb-1.5">สาขาที่ขายเมนูนี้ (เลือกได้มากกว่า 1 สาขา)</div>
                <div className="flex flex-wrap gap-2">
                  {branches.filter(b => b.active).map(b => (
                    <label key={b.id} className={`flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border cursor-pointer ${form.branchIds.includes(b.id) ? "bg-amber-50 border-amber-300 text-amber-800" : "border-stone-300 text-stone-600"}`}>
                      <input type="checkbox" className="hidden" checked={form.branchIds.includes(b.id)} onChange={() => toggleFormBranch(b.id)} />
                      {b.name}
                    </label>
                  ))}
                </div>
                {form.branchIds.length === 0 && <p className="text-[11px] text-stone-400 mt-1">ไม่เลือกสาขาใดเลย = ขายได้ทุกสาขา</p>}
              </div>
            )}

            {/* Recipe / stock linking (main dish) */}
            <div className="mt-4 p-3.5 rounded-lg border border-stone-200">
              <div className="text-sm font-semibold text-stone-700 mb-1">วัตถุดิบที่ใช้ (เมนูหลัก)</div>
              <p className="text-xs text-stone-400 mb-3">ระบุปริมาณวัตถุดิบที่ใช้ต่อ 1 ที่/แก้ว ระบบจะตัดสต็อกให้อัตโนมัติทุกครั้งที่ส่งออเดอร์เมนูนี้เข้าครัว</p>

              {form.recipe.length === 0 && (
                <div className="text-xs text-stone-300 text-center py-4 border border-dashed border-stone-200 rounded-lg mb-2">ยังไม่ได้ผูกวัตถุดิบ — เมนูนี้จะไม่ตัดสต็อก</div>
              )}

              <div className="space-y-2">
                {form.recipe.map((r, i) => {
                  const stockItem = stockItems.find(s => s.id === r.stockItemId);
                  const info = getRecipeUnitInfo(stockItem);
                  const rowCost = (Number(r.qty) || 0) * info.costPerRecipeUnit;
                  return (
                    <div key={i} className="flex items-center gap-2">
                      <select className="flex-1 min-w-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={r.stockItemId} onChange={e => updateRecipeRow(i, { stockItemId: e.target.value })}>
                        <option value="">— เลือกวัตถุดิบ —</option>
                        {stockItems.map(s => <option key={s.id} value={s.id}>{s.name} ({getRecipeUnitInfo(s).label})</option>)}
                      </select>
                      <input type="number" step="any" className="w-20 flex-shrink-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={r.qty} onChange={e => updateRecipeRow(i, { qty: e.target.value })} placeholder={info.label || "ปริมาณ"} />
                      <span className="text-xs text-stone-400 w-16 flex-shrink-0 text-right">{r.stockItemId ? `=฿${rowCost.toFixed(2)}` : ""}</span>
                      <button onClick={() => removeRecipeRow(i)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={14} /></button>
                    </div>
                  );
                })}
              </div>
              <button onClick={addRecipeRow} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2">
                <Plus size={12} /> เพิ่มวัตถุดิบ
              </button>

              {form.recipe.length > 0 && (
                <div className="text-xs text-stone-500 mt-3 pt-2 border-t border-stone-100">
                  ต้นทุนวัตถุดิบโดยประมาณต่อจาน: <span className="font-semibold text-amber-700">฿{form.recipe.reduce((sum, r) => {
                    const info = getRecipeUnitInfo(stockItems.find(s => s.id === r.stockItemId));
                    return sum + (Number(r.qty) || 0) * info.costPerRecipeUnit;
                  }, 0).toFixed(2)}</span>
                </div>
              )}
            </div>

            {/* Per-channel pricing */}
            <div className="mt-4 p-3.5 rounded-lg border border-stone-200">
              <div className="text-sm font-semibold text-stone-700 mb-1">ราคาตามช่องทางการขาย</div>
              <p className="text-xs text-stone-400 mb-3">เว้นว่างไว้เพื่อคำนวณอัตโนมัติตามส่วนต่างที่ตั้งไว้ในหน้า “ช่องทางการขาย” หรือใส่ราคาเฉพาะเมนูนี้เพื่อกำหนดเอง</p>
              <div className="space-y-2">
                {channels.map(ch => (
                  <div key={ch.id} className="flex items-center justify-between gap-3">
                    <span className={`text-xs px-2 py-1 rounded border font-medium w-28 text-center ${CHANNEL_COLOR[ch.color]}`}>{ch.name}</span>
                    <input type="number" placeholder="อัตโนมัติ" className={`${inputCls} max-w-[140px]`}
                      value={form.channelPrices[ch.id] ?? ""} onChange={e => setChannelPrice(ch.id, e.target.value)} />
                    <span className="text-xs text-stone-400">บาท</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Option groups */}
            <div className="mt-4 p-3.5 rounded-lg border border-stone-200">
              <div className="flex items-center justify-between mb-1">
                <div className="text-sm font-semibold text-stone-700">ตัวเลือกเสริมของเมนู</div>
                <Btn variant="ghost" onClick={addGroup}><Plus size={13} /> เพิ่มกลุ่มตัวเลือก</Btn>
              </div>
              <p className="text-xs text-stone-400 mb-3">เช่น “ประเภท: น้ำ / แห้ง” ให้เลือก 1 ข้อ หรือ “พิเศษเครื่องต่างๆ” ให้เลือกได้หลายข้อพร้อมราคาเพิ่ม</p>

              {form.optionGroups.length === 0 && (
                <div className="text-xs text-stone-300 text-center py-6 border border-dashed border-stone-200 rounded-lg">ยังไม่มีกลุ่มตัวเลือก</div>
              )}

              <div className="space-y-4">
                {form.optionGroups.map(g => (
                  <div key={g.id} className="border border-stone-200 rounded-lg p-3.5">
                    <div className="flex items-start gap-2 mb-3">
                      <input className={`${inputCls} flex-1`} placeholder="ชื่อกลุ่มตัวเลือก เช่น ประเภท" value={g.name} onChange={e => updateGroup(g.id, { name: e.target.value })} />
                      <button onClick={() => removeGroup(g.id)} className="text-stone-300 hover:text-rose-500 p-2"><Trash2 size={15} /></button>
                    </div>

                    <div className="flex flex-wrap items-center gap-3 mb-3">
                      <div className="inline-flex rounded-md border border-stone-300 overflow-hidden">
                        <button onClick={() => updateGroup(g.id, { type: "single" })}
                          className={`px-3 py-1.5 text-xs font-medium ${g.type === "single" ? "bg-stone-900 text-white" : "bg-white text-stone-500 hover:bg-stone-50"}`}>เลือกได้ 1 ข้อ</button>
                        <button onClick={() => updateGroup(g.id, { type: "multiple" })}
                          className={`px-3 py-1.5 text-xs font-medium border-l border-stone-300 ${g.type === "multiple" ? "bg-stone-900 text-white" : "bg-white text-stone-500 hover:bg-stone-50"}`}>เลือกได้หลายข้อ</button>
                      </div>
                      {g.type === "single" ? (
                        <label className="flex items-center gap-1.5 text-xs text-stone-500">
                          <input type="checkbox" checked={g.required} onChange={e => updateGroup(g.id, { required: e.target.checked })} />
                          บังคับเลือก (ต้องระบุ)
                        </label>
                      ) : (
                        <label className="flex items-center gap-1.5 text-xs text-stone-500">
                          เลือกได้สูงสุด
                          <input type="number" min={1} className="w-14 rounded-md border border-stone-300 px-1.5 py-1 text-xs text-center" value={g.max} onChange={e => updateGroup(g.id, { max: Number(e.target.value) })} />
                          ข้อ
                        </label>
                      )}
                    </div>

                    <div className="space-y-1.5">
                      {g.choices.map(c => {
                        const isExpanded = !!expandedChoiceRecipes[c.id];
                        const choiceRecipe = c.recipe || [];
                        return (
                          <div key={c.id} className="p-2 rounded-lg border border-transparent hover:border-stone-200">
                            <div className="flex items-center gap-2">
                              {g.type === "single" ? <span className="w-3.5 h-3.5 rounded-full border border-stone-300 flex-shrink-0" /> : <span className="w-3.5 h-3.5 rounded border border-stone-300 flex-shrink-0" />}
                              <input className="flex-1 rounded-md border border-stone-300 px-2.5 py-1.5 text-sm" placeholder="ชื่อตัวเลือก เช่น หมูสับ (บะช่อ)" value={c.name} onChange={e => updateChoice(g.id, c.id, { name: e.target.value })} />
                              <span className="text-xs text-stone-400">฿</span>
                              <input type="number" className="w-20 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={c.price} onChange={e => updateChoice(g.id, c.id, { price: Number(e.target.value) })} />
                              <button onClick={() => removeChoice(g.id, c.id)} className="text-stone-300 hover:text-rose-500"><X size={14} /></button>
                            </div>

                            <button onClick={() => toggleChoiceRecipeExpanded(c.id)} className="text-[11px] font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-1.5 ml-5">
                              <Plus size={10} /> {choiceRecipe.length > 0 ? `วัตถุดิบสำหรับตัวเลือกนี้ (${choiceRecipe.length})` : "เพิ่มวัตถุดิบสำหรับตัวเลือกนี้"}
                            </button>

                            {isExpanded && (
                              <div className="ml-5 mt-1.5 space-y-1.5">
                                {choiceRecipe.map((r, ri) => {
                                  const stockItem = stockItems.find(s => s.id === r.stockItemId);
                                  const info = getRecipeUnitInfo(stockItem);
                                  const rowCost = (Number(r.qty) || 0) * info.costPerRecipeUnit;
                                  return (
                                    <div key={ri} className="flex items-center gap-2">
                                      <select className="flex-1 min-w-0 rounded-md border border-stone-300 px-2 py-1 text-xs" value={r.stockItemId} onChange={e => updateChoiceRecipeRow(g.id, c.id, ri, { stockItemId: e.target.value })}>
                                        <option value="">— เลือกวัตถุดิบ —</option>
                                        {stockItems.map(s => <option key={s.id} value={s.id}>{s.name} ({getRecipeUnitInfo(s).label})</option>)}
                                      </select>
                                      <input type="number" step="any" className="w-20 rounded-md border border-stone-300 px-2 py-1 text-xs" value={r.qty} onChange={e => updateChoiceRecipeRow(g.id, c.id, ri, { qty: e.target.value })} placeholder="ปริมาณ" />
                                      <span className="text-[11px] text-stone-400 w-14 flex-shrink-0 text-right">{r.stockItemId ? `=฿${rowCost.toFixed(2)}` : ""}</span>
                                      <button onClick={() => removeChoiceRecipeRow(g.id, c.id, ri)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={12} /></button>
                                    </div>
                                  );
                                })}
                                <button onClick={() => addChoiceRecipeRow(g.id, c.id)} className="text-[11px] font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1">
                                  <Plus size={10} /> เพิ่มวัตถุดิบ
                                </button>
                              </div>
                            )}
                          </div>
                        );
                      })}
                    </div>
                    <button onClick={() => addChoice(g.id)} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2">
                      <Plus size={12} /> เพิ่มตัวเลือกย่อย
                    </button>
                  </div>
                ))}
              </div>
            </div>

            <div className="flex gap-2 mt-4">
              <Btn onClick={saveItem}>{form.id ? "บันทึกการแก้ไข" : <><Plus size={14} /> เพิ่มเมนู</>}</Btn>
              <Btn variant="ghost" onClick={() => setShowForm(false)}>ยกเลิก</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup (minimal) */}
      {deletingItem && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setDeletingItem(null); setDeletePin(""); setDeletePinError(""); }}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="text-sm text-stone-700 mb-3">ลบ "{deletingItem.name}" ใช่ไหม?</div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} autoFocus className={inputCls}
                value={deletePin} onChange={e => { setDeletePin(e.target.value.replace(/\D/g, "").slice(0, 6)); setDeletePinError(""); }}
                placeholder="••••••" />
            </Field>
            {deletePinError && <div className="text-xs text-rose-500 mt-1.5">{deletePinError}</div>}
            <div className="flex justify-end gap-2 mt-4">
              <Btn variant="ghost" onClick={() => { setDeletingItem(null); setDeletePin(""); setDeletePinError(""); }}>ยกเลิก</Btn>
              <Btn disabled={deletePin.length !== 6} onClick={confirmDeleteItem}>ยืนยัน</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Bulk "add via Excel" popup — download a template, upload it back filled in */}
      {excelImportOpen && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setExcelImportOpen(false); setExcelPreview(null); }}>
          <div className="bg-white rounded-xl w-full max-w-lg p-5 max-h-[85vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 text-lg">เพิ่มเมนูด้วย Excel</div>
              <button onClick={() => { setExcelImportOpen(false); setExcelPreview(null); }} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <p className="text-sm text-stone-500 mb-4">ดาวน์โหลดเทมเพลต กรอกรายการเมนู แล้วอัปโหลดกลับเข้ามาเพื่อเพิ่มทีละหลายรายการ (รองรับเฉพาะ ชื่อเมนู / หมวดหมู่ / ราคา / คำอธิบาย — ตัวเลือกเสริมและสูตรวัตถุดิบยังต้องไปเพิ่มทีหลังในหน้าแก้ไขเมนูแต่ละรายการ)</p>

            <button onClick={downloadMenuExcelTemplate} className="w-full flex items-center justify-center gap-2 py-3 rounded-lg border border-dashed border-stone-300 text-stone-600 hover:border-amber-400 hover:text-amber-700 text-sm font-medium mb-3 transition-colors">
              <Download size={15} /> ดาวน์โหลดเทมเพลต Excel
            </button>

            <label className="w-full flex items-center justify-center gap-2 py-3 rounded-lg bg-stone-900 hover:bg-stone-800 text-white text-sm font-medium cursor-pointer transition-colors">
              <Upload size={15} /> เลือกไฟล์ Excel ที่กรอกแล้ว
              <input ref={excelFileInputRef} type="file" accept=".xlsx,.xls" className="hidden" onChange={handleExcelFile} />
            </label>

            {excelParsing && <div className="text-xs text-stone-400 mt-3 text-center">กำลังอ่านไฟล์...</div>}

            {excelPreview && (
              <div className="mt-4">
                <div className="text-sm text-stone-700 mb-2">
                  พร้อมนำเข้า <span className="font-semibold text-emerald-600">{excelPreview.validItems.length}</span> รายการ
                  {excelPreview.errors.length > 0 && <span className="text-rose-500"> · ข้าม {excelPreview.errors.length} แถวที่มีปัญหา</span>}
                </div>

                {excelPreview.validItems.length > 0 && (
                  <div className="max-h-40 overflow-y-auto border border-stone-200 rounded-lg mb-3">
                    {excelPreview.validItems.map((it, i) => {
                      const cat = categories.find(c => c.id === it.catId);
                      return (
                        <div key={i} className="flex items-center justify-between px-3 py-2 text-sm border-b border-stone-100 last:border-0">
                          <div className="min-w-0">
                            <div className="text-stone-800 truncate">{it.name}</div>
                            <div className="text-xs text-stone-400">{cat?.name}</div>
                          </div>
                          <span className="font-mono text-amber-700 text-sm flex-shrink-0">฿{fmtMoney(it.price)}</span>
                        </div>
                      );
                    })}
                  </div>
                )}

                {excelPreview.errors.length > 0 && (
                  <div className="space-y-1 mb-3">
                    {excelPreview.errors.map((e, i) => <div key={i} className="text-xs text-rose-500">{e}</div>)}
                  </div>
                )}

                <div className="flex gap-2">
                  <Btn disabled={excelPreview.validItems.length === 0} onClick={confirmExcelImport} className="flex-1 justify-center">
                    <Plus size={14} /> ยืนยันนำเข้า {excelPreview.validItems.length} รายการ
                  </Btn>
                  <Btn variant="ghost" onClick={() => { setExcelImportOpen(false); setExcelPreview(null); }}>ยกเลิก</Btn>
                </div>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: CATEGORIES
   ========================================================================= */

function CategoriesPage({ categories, setCategories, staff, ownerProfile, logActivity }) {
  const [showAddForm, setShowAddForm] = useState(false);
  const [name, setName] = useState("");
  const [kind, setKind] = useState("food");
  const [deletingCat, setDeletingCat] = useState(null);
  const [editingCat, setEditingCat] = useState(null);
  const [editForm, setEditForm] = useState(null);
  const [editPin, setEditPin] = useState("");
  const [editPinError, setEditPinError] = useState("");

  function openAdd() {
    setName("");
    setKind("food");
    setShowAddForm(true);
  }
  function addCat() {
    if (!name) return;
    setCategories(prev => [...prev, { id: "c" + Date.now(), name, kind }]);
    setShowAddForm(false);
  }
  function removeCat(id) {
    setCategories(prev => prev.filter(c => c.id !== id));
    setDeletingCat(null);
  }
  function openEdit(c) {
    setEditingCat(c);
    setEditForm({ name: c.name, kind: c.kind });
    setEditPin("");
    setEditPinError("");
  }
  function confirmEdit() {
    const manager = (staff || []).find(s => s.pin === editPin && s.active);
    const isOwner = isOwnerPin(ownerProfile, editPin);
    if (!manager && !isOwner) {
      setEditPinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    setCategories(prev => prev.map(c => c.id === editingCat.id ? { ...c, ...editForm } : c));
    setEditingCat(null);
    setEditForm(null);
  }

  return (
    <div>
      <PageHeader eyebrow="จัดการเมนู" title="หมวดหมู่อาหาร" subtitle="จัดกลุ่มหมวดหมู่เมนูของร้าน"
        right={<Btn onClick={openAdd}><Plus size={14} /> เพิ่มหมวดหมู่</Btn>} />

      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
        {categories.map(c => (
          <div key={c.id} className="flex items-center justify-between p-3 rounded-lg border border-stone-200 bg-white">
            <div className="flex items-center gap-2 min-w-0">
              {c.kind === "drink" ? <GlassWater size={15} className="text-sky-500 flex-shrink-0" /> : <UtensilsCrossed size={15} className="text-amber-600 flex-shrink-0" />}
              <span className="text-sm font-medium text-stone-800 truncate">{c.name}</span>
            </div>
            <div className="flex items-center gap-2 flex-shrink-0">
              <button onClick={() => openEdit(c)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
              <button onClick={() => setDeletingCat(c)} className="text-stone-300 hover:text-rose-500"><Trash2 size={14} /></button>
            </div>
          </div>
        ))}
      </div>

      {/* Add category popup */}
      {showAddForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowAddForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มหมวดหมู่</div>
              <button onClick={() => setShowAddForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อหมวดหมู่"><input className={inputCls} value={name} onChange={e => setName(e.target.value)} autoFocus /></Field>
              <div className="flex gap-2">
                <button onClick={() => setKind("food")} className={`flex-1 py-2 rounded-md text-sm border ${kind === "food" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>อาหาร</button>
                <button onClick={() => setKind("drink")} className={`flex-1 py-2 rounded-md text-sm border ${kind === "drink" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>เครื่องดื่ม</button>
              </div>
            </div>
            <div className="flex justify-end gap-2 mt-5">
              <Btn variant="ghost" onClick={() => setShowAddForm(false)}>ยกเลิก</Btn>
              <Btn disabled={!name} onClick={addCat}>เพิ่มหมวดหมู่</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Edit category popup (requires PIN) */}
      {editingCat && editForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setEditingCat(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขหมวดหมู่</div>
              <button onClick={() => setEditingCat(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อหมวดหมู่"><input className={inputCls} value={editForm.name} onChange={e => setEditForm(f => ({ ...f, name: e.target.value }))} /></Field>
              <div className="flex gap-2">
                <button onClick={() => setEditForm(f => ({ ...f, kind: "food" }))} className={`flex-1 py-2 rounded-md text-sm border ${editForm.kind === "food" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>อาหาร</button>
                <button onClick={() => setEditForm(f => ({ ...f, kind: "drink" }))} className={`flex-1 py-2 rounded-md text-sm border ${editForm.kind === "drink" ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>เครื่องดื่ม</button>
              </div>
              <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls}
                  value={editPin} onChange={e => { setEditPin(e.target.value.replace(/\D/g, "").slice(0, 6)); setEditPinError(""); }}
                  placeholder="••••••" />
              </Field>
              {editPinError && <div className="text-xs text-rose-500">{editPinError}</div>}
            </div>
            <div className="flex justify-end gap-2 mt-5">
              <Btn variant="ghost" onClick={() => setEditingCat(null)}>ยกเลิก</Btn>
              <Btn disabled={editPin.length !== 6} onClick={confirmEdit}>บันทึก</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingCat && (
        <ConfirmDeletePin
          message={`ลบ "${deletingCat.name}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingCat(null)}
          onConfirm={() => removeCat(deletingCat.id)}
          logActivity={logActivity} activityLabel={`ลบหมวดหมู่ ${deletingCat.name}`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: KITCHEN DISPLAY SETTINGS
   ========================================================================= */

function KitchenDisplaySettingsPage({ categories, setCategories }) {
  function setScreen(id, kind) {
    setCategories(prev => prev.map(c => c.id === id ? { ...c, kind } : c));
  }
  return (
    <div>
      <PageHeader eyebrow="ครัว" title="ตั้งค่าจอครัว" subtitle="เลือกว่าออเดอร์ในแต่ละหมวดหมู่จะถูกส่งไปแสดงที่จอครัวอาหาร หรือจอครัวเครื่องดื่ม" />
      <Card>
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
              <th className="px-4 py-3 font-medium">หมวดหมู่อาหาร</th>
              <th className="px-4 py-3 font-medium">จอครัวที่ส่งออเดอร์ไป</th>
            </tr>
          </thead>
          <tbody>
            {categories.map(c => (
              <tr key={c.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                <td className="px-4 py-3">
                  <div className="flex items-center gap-2">
                    {c.kind === "drink" ? <GlassWater size={15} className="text-sky-500" /> : <UtensilsCrossed size={15} className="text-amber-600" />}
                    <span className="font-medium text-stone-800">{c.name}</span>
                  </div>
                </td>
                <td className="px-4 py-3">
                  <div className="inline-flex rounded-md border border-stone-300 overflow-hidden">
                    <button onClick={() => setScreen(c.id, "food")}
                      className={`px-3 py-1.5 text-xs font-medium flex items-center gap-1.5 transition-colors
                      ${c.kind === "food" ? "bg-amber-600 text-white" : "bg-white text-stone-500 hover:bg-stone-50"}`}>
                      <ChefHat size={13} /> ครัวอาหาร
                    </button>
                    <button onClick={() => setScreen(c.id, "drink")}
                      className={`px-3 py-1.5 text-xs font-medium flex items-center gap-1.5 border-l border-stone-300 transition-colors
                      ${c.kind === "drink" ? "bg-sky-600 text-white" : "bg-white text-stone-500 hover:bg-stone-50"}`}>
                      <Coffee size={13} /> ครัวเครื่องดื่ม
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </Card>
      <div className="text-xs text-stone-400 mt-3">เมื่อพนักงานส่งออเดอร์จากหน้า POS ระบบจะแยกรายการตามหมวดหมู่นี้ไปยังจอครัวที่กำหนดไว้โดยอัตโนมัติ</div>
    </div>
  );
}

/* =========================================================================
   PAGE: PROMOTIONS
   ========================================================================= */

const PROMO_TYPES = [
  { key: "minSpend", label: "ยอดเงินขั้นต่ำ", icon: Percent, desc: "ลดราคาเมื่อยอดสั่งซื้อถึงขั้นต่ำที่กำหนด (ลด % หรือ บาท)" },
  { key: "bundle", label: "Meal Bundle", icon: Gift, desc: "อิ่มฟินยกเซต! เลือกอาหารและเครื่องดื่มมาจัดเป็นเซตราคาพิเศษ" },
  { key: "happyHour", label: "Happy Hour", icon: Clock, desc: "ลดราคาเฉพาะช่วงเวลาขายดีที่กำหนด" },
  { key: "mixMatch", label: "Mix and Match", icon: LayoutGrid, desc: "เลือกเมนูที่ร่วมรายการ กำหนดจำนวนที่เลือกได้ในราคาเดียว" },
  { key: "points", label: "สะสมแต้ม (Point)", icon: Award, desc: "โบนัสแต้มพิเศษ เช่น เดือนเกิด หรือยอดใช้จ่ายครบตามกำหนด" },
];

function defaultPromoForm(type) {
  const base = { name: "", start: "", end: "", excludedCategoryIds: [] };
  const byType = {
    minSpend: { minSpend: { amount: 300, discountType: "percent", value: 10 } },
    bundle: { bundle: { foodItemIds: [], drinkItemIds: [], fullPrice: 0, promoMode: "fixed", promoPrice: 0, promoPercent: 10 } },
    happyHour: { happyHour: { startTime: "14:00", endTime: "17:00", discountType: "percent", value: 15 } },
    mixMatch: { mixMatch: { itemIds: [], chooseCount: 2, price: 150 } },
    points: { points: { trigger: "birthdayMonth", rewardType: "multiplier", multiplier: 2, bonusPoints: 50, thresholdAmount: 500 } },
  };
  return { type, ...base, ...byType[type] };
}

function promoSummary(p) {
  switch (p.type) {
    case "minSpend": {
      const m = p.minSpend;
      return `ยอดขั้นต่ำ ฿${m.amount} · ลด ${m.value}${m.discountType === "percent" ? "%" : " บาท"}`;
    }
    case "bundle": {
      const b = p.bundle;
      const promo = b.promoMode === "fixed" ? `เหลือ ฿${b.promoPrice}` : `ลด ${b.promoPercent}%`;
      return `เต็ม ฿${b.fullPrice} → ${promo} · ${b.foodItemIds.length} อาหาร + ${b.drinkItemIds.length} เครื่องดื่ม`;
    }
    case "happyHour": {
      const h = p.happyHour;
      return `${h.startTime}–${h.endTime} น. · ลด ${h.value}${h.discountType === "percent" ? "%" : " บาท"}`;
    }
    case "mixMatch": {
      const mm = p.mixMatch;
      return `เลือก ${mm.chooseCount} จาก ${mm.itemIds.length} เมนู ในราคา ฿${mm.price}`;
    }
    case "points": {
      const pt = p.points;
      const trigger = pt.trigger === "birthdayMonth" ? "เดือนเกิดสมาชิก" : `ยอดครบ ฿${pt.thresholdAmount}`;
      const reward = pt.rewardType === "multiplier" ? `รับแต้ม x${pt.multiplier}` : `รับแต้มเพิ่ม ${pt.bonusPoints} แต้ม`;
      return `${trigger} · ${reward}`;
    }
    default: return "";
  }
}

function PromotionsPage({ promotions, setPromotions, categories, menu }) {
  const [creating, setCreating] = useState(false);
  const [form, setForm] = useState(null);

  function toggle(id) {
    setPromotions(prev => prev.map(p => p.id === id ? { ...p, active: !p.active } : p));
  }
  function remove(id) {
    setPromotions(prev => prev.filter(p => p.id !== id));
  }
  function startCreate() {
    setCreating(true);
    setForm(null);
  }
  function startEdit(p) {
    setCreating(true);
    setForm({ ...p });
  }
  function cancelCreate() {
    setCreating(false);
    setForm(null);
  }
  function save() {
    if (!form || !form.name) return;
    if (form.id) {
      setPromotions(prev => prev.map(p => p.id === form.id ? { ...form } : p));
    } else {
      setPromotions(prev => [...prev, { ...form, id: "p" + Date.now(), active: true }]);
    }
    setCreating(false);
    setForm(null);
  }

  function setCommon(patch) {
    setForm(prev => ({ ...prev, ...patch }));
  }
  function setSection(section, patch) {
    setForm(prev => ({ ...prev, [section]: { ...prev[section], ...patch } }));
  }
  function toggleExcludedCategory(catId) {
    setForm(prev => ({
      ...prev,
      excludedCategoryIds: prev.excludedCategoryIds.includes(catId)
        ? prev.excludedCategoryIds.filter(id => id !== catId)
        : [...prev.excludedCategoryIds, catId],
    }));
  }
  function toggleBundleItem(kind, itemId) {
    setForm(prev => {
      const key = kind === "food" ? "foodItemIds" : "drinkItemIds";
      const cur = prev.bundle[key];
      const nextIds = cur.includes(itemId) ? cur.filter(id => id !== itemId) : [...cur, itemId];
      const allIds = kind === "food" ? [...nextIds, ...prev.bundle.drinkItemIds] : [...prev.bundle.foodItemIds, ...nextIds];
      const fullPrice = allIds.reduce((s, id) => s + (menu.find(m => m.id === id)?.price || 0), 0);
      return { ...prev, bundle: { ...prev.bundle, [key]: nextIds, fullPrice } };
    });
  }
  function toggleMixMatchItem(itemId) {
    setForm(prev => ({
      ...prev,
      mixMatch: {
        ...prev.mixMatch,
        itemIds: prev.mixMatch.itemIds.includes(itemId)
          ? prev.mixMatch.itemIds.filter(id => id !== itemId)
          : [...prev.mixMatch.itemIds, itemId],
      },
    }));
  }

  const foodCategoryIds = categories.filter(c => c.kind !== "drink").map(c => c.id);
  const drinkCategoryIds = categories.filter(c => c.kind === "drink").map(c => c.id);
  const foodMenuItems = menu.filter(m => foodCategoryIds.includes(m.catId));
  const drinkMenuItems = menu.filter(m => drinkCategoryIds.includes(m.catId));

  return (
    <div>
      <PageHeader eyebrow="โปรโมชั่น" title="โปรโมชั่นทั้งหมด" subtitle="จัดการแคมเปญส่วนลดและโปรโมชั่น"
        right={!creating && <Btn onClick={startCreate}><Plus size={14} /> สร้างโปรโมชั่น</Btn>} />

      {creating && (
        <Card className="p-5 mb-5">
          {!form ? (
            <>
              <div className="text-sm font-semibold text-stone-700 mb-3">เลือกประเภทโปรโมชั่น</div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                {PROMO_TYPES.map(t => (
                  <button key={t.key} onClick={() => setForm(defaultPromoForm(t.key))}
                    className="text-left p-4 rounded-lg border border-stone-200 hover:border-amber-400 hover:shadow-sm transition-all flex gap-3">
                    <span className="w-10 h-10 rounded-lg bg-amber-50 text-amber-600 flex items-center justify-center flex-shrink-0"><t.icon size={18} /></span>
                    <div>
                      <div className="font-medium text-stone-800 text-sm">{t.label}</div>
                      <div className="text-xs text-stone-400 mt-0.5">{t.desc}</div>
                    </div>
                  </button>
                ))}
              </div>
              <Btn variant="ghost" className="mt-4" onClick={cancelCreate}>ยกเลิก</Btn>
            </>
          ) : (
            <>
              <div className="flex items-center gap-2.5 mb-4">
                {(() => { const t = PROMO_TYPES.find(t => t.key === form.type); return (<>
                  <span className="w-9 h-9 rounded-lg bg-amber-50 text-amber-600 flex items-center justify-center flex-shrink-0"><t.icon size={16} /></span>
                  <span className="font-semibold text-stone-800">{t.label}</span>
                </>); })()}
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-4">
                <Field label="ชื่อโปรโมชั่น"><input className={inputCls} value={form.name} onChange={e => setCommon({ name: e.target.value })} placeholder="ตั้งชื่อโปรโมชั่น" /></Field>
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                  <Field label="เริ่ม"><input type="date" className={inputCls} value={form.start} onChange={e => setCommon({ start: e.target.value })} /></Field>
                  <Field label="ถึง"><input type="date" className={inputCls} value={form.end} onChange={e => setCommon({ end: e.target.value })} /></Field>
                </div>
              </div>

              {/* Type-specific fields */}
              {form.type === "minSpend" && (
                <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 mb-4">
                  <Field label="ยอดขั้นต่ำ (บาท)">
                    <input type="number" className={inputCls} value={form.minSpend.amount} onChange={e => setSection("minSpend", { amount: Number(e.target.value) })} />
                  </Field>
                  <Field label="รูปแบบส่วนลด">
                    <SegmentedChoice value={form.minSpend.discountType} onChange={v => setSection("minSpend", { discountType: v })}
                      options={[{ value: "percent", label: "%" }, { value: "amount", label: "บาท" }]} />
                  </Field>
                  <Field label={`ลด (${form.minSpend.discountType === "percent" ? "%" : "บาท"})`}>
                    <input type="number" className={inputCls} value={form.minSpend.value} onChange={e => setSection("minSpend", { value: Number(e.target.value) })} />
                  </Field>
                </div>
              )}

              {form.type === "bundle" && (
                <div className="mb-4 space-y-3">
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                    <div>
                      <div className="text-xs font-medium text-stone-500 mb-2">เลือกอาหาร</div>
                      <div className="space-y-1 max-h-40 overflow-y-auto border border-stone-200 rounded-lg p-2">
                        {foodMenuItems.map(m => (
                          <label key={m.id} className="flex items-center justify-between text-sm py-0.5">
                            <span className="flex items-center gap-2"><input type="checkbox" checked={form.bundle.foodItemIds.includes(m.id)} onChange={() => toggleBundleItem("food", m.id)} />{m.name}</span>
                            <span className="text-xs text-stone-400 font-mono">฿{fmtMoney(m.price)}</span>
                          </label>
                        ))}
                      </div>
                    </div>
                    <div>
                      <div className="text-xs font-medium text-stone-500 mb-2">เลือกเครื่องดื่ม</div>
                      <div className="space-y-1 max-h-40 overflow-y-auto border border-stone-200 rounded-lg p-2">
                        {drinkMenuItems.map(m => (
                          <label key={m.id} className="flex items-center justify-between text-sm py-0.5">
                            <span className="flex items-center gap-2"><input type="checkbox" checked={form.bundle.drinkItemIds.includes(m.id)} onChange={() => toggleBundleItem("drink", m.id)} />{m.name}</span>
                            <span className="text-xs text-stone-400 font-mono">฿{fmtMoney(m.price)}</span>
                          </label>
                        ))}
                      </div>
                    </div>
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
                    <Field label="ราคาเต็ม (บาท)"><input type="number" className={inputCls} value={form.bundle.fullPrice} onChange={e => setSection("bundle", { fullPrice: Number(e.target.value) })} /></Field>
                    <Field label="รูปแบบราคาโปร">
                      <SegmentedChoice value={form.bundle.promoMode} onChange={v => setSection("bundle", { promoMode: v })}
                        options={[{ value: "fixed", label: "ราคาเหลือ (บาท)" }, { value: "percent", label: "ลด (%)" }]} />
                    </Field>
                    {form.bundle.promoMode === "fixed" ? (
                      <Field label="ราคาโปรเหลือ (บาท)"><input type="number" className={inputCls} value={form.bundle.promoPrice} onChange={e => setSection("bundle", { promoPrice: Number(e.target.value) })} /></Field>
                    ) : (
                      <Field label="ลด (%)"><input type="number" className={inputCls} value={form.bundle.promoPercent} onChange={e => setSection("bundle", { promoPercent: Number(e.target.value) })} /></Field>
                    )}
                  </div>
                </div>
              )}

              {form.type === "happyHour" && (
                <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-4">
                  <Field label="เวลาเริ่ม"><input type="time" className={inputCls} value={form.happyHour.startTime} onChange={e => setSection("happyHour", { startTime: e.target.value })} /></Field>
                  <Field label="เวลาสิ้นสุด"><input type="time" className={inputCls} value={form.happyHour.endTime} onChange={e => setSection("happyHour", { endTime: e.target.value })} /></Field>
                  <Field label="รูปแบบส่วนลด">
                    <SegmentedChoice value={form.happyHour.discountType} onChange={v => setSection("happyHour", { discountType: v })}
                      options={[{ value: "percent", label: "%" }, { value: "amount", label: "บาท" }]} />
                  </Field>
                  <Field label={`ลด (${form.happyHour.discountType === "percent" ? "%" : "บาท"})`}>
                    <input type="number" className={inputCls} value={form.happyHour.value} onChange={e => setSection("happyHour", { value: Number(e.target.value) })} />
                  </Field>
                </div>
              )}

              {form.type === "mixMatch" && (
                <div className="mb-4 space-y-3">
                  <div className="text-xs font-medium text-stone-500 mb-2">เลือกเมนูที่ร่วมรายการ</div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-1 max-h-40 overflow-y-auto border border-stone-200 rounded-lg p-2">
                    {menu.map(m => (
                      <label key={m.id} className="flex items-center justify-between text-sm py-0.5 pr-2">
                        <span className="flex items-center gap-2"><input type="checkbox" checked={form.mixMatch.itemIds.includes(m.id)} onChange={() => toggleMixMatchItem(m.id)} />{m.name}</span>
                        <span className="text-xs text-stone-400 font-mono">฿{fmtMoney(m.price)}</span>
                      </label>
                    ))}
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                    <Field label="เลือกได้กี่เมนู"><input type="number" min={1} className={inputCls} value={form.mixMatch.chooseCount} onChange={e => setSection("mixMatch", { chooseCount: Number(e.target.value) })} /></Field>
                    <Field label="ในราคา (บาท)"><input type="number" className={inputCls} value={form.mixMatch.price} onChange={e => setSection("mixMatch", { price: Number(e.target.value) })} /></Field>
                  </div>
                </div>
              )}

              {form.type === "points" && (
                <div className="mb-4 space-y-3">
                  <Field label="เงื่อนไข">
                    <SegmentedChoice value={form.points.trigger} onChange={v => setSection("points", { trigger: v })}
                      options={[{ value: "birthdayMonth", label: "เดือนเกิดสมาชิก" }, { value: "spendThreshold", label: "ยอดใช้จ่ายครบตามกำหนด" }]} />
                  </Field>
                  {form.points.trigger === "spendThreshold" && (
                    <Field label="ยอดครบ (บาท)"><input type="number" className={`${inputCls} max-w-xs`} value={form.points.thresholdAmount} onChange={e => setSection("points", { thresholdAmount: Number(e.target.value) })} /></Field>
                  )}
                  <Field label="รูปแบบแต้มที่ได้รับ">
                    <SegmentedChoice value={form.points.rewardType} onChange={v => setSection("points", { rewardType: v })}
                      options={[{ value: "multiplier", label: "คูณแต้ม (เท่า)" }, { value: "bonus", label: "รับแต้มเพิ่ม (แต้ม)" }]} />
                  </Field>
                  {form.points.rewardType === "multiplier" ? (
                    <Field label="คูณแต้ม (เท่า)"><input type="number" step="0.1" className={`${inputCls} max-w-xs`} value={form.points.multiplier} onChange={e => setSection("points", { multiplier: Number(e.target.value) })} /></Field>
                  ) : (
                    <Field label="รับแต้มเพิ่ม (แต้ม)"><input type="number" className={`${inputCls} max-w-xs`} value={form.points.bonusPoints} onChange={e => setSection("points", { bonusPoints: Number(e.target.value) })} /></Field>
                  )}
                </div>
              )}

              {/* Excluded categories */}
              <div className="mb-4">
                <div className="text-xs font-medium text-stone-500 mb-2">หมวดหมู่ที่ไม่ร่วมโปรโมชั่นนี้ (เช่น เครื่องดื่ม)</div>
                <div className="flex flex-wrap gap-2">
                  {categories.map(c => (
                    <button key={c.id} onClick={() => toggleExcludedCategory(c.id)}
                      className={`px-3 py-1.5 rounded-md text-xs border ${form.excludedCategoryIds.includes(c.id) ? "bg-rose-50 text-rose-600 border-rose-300" : "border-stone-300 text-stone-500"}`}>
                      {c.name}
                    </button>
                  ))}
                </div>
              </div>

              <div className="flex gap-2">
                <Btn onClick={save}>{form.id ? "บันทึกการแก้ไข" : "บันทึกโปรโมชั่น"}</Btn>
                <Btn variant="ghost" onClick={cancelCreate}>ยกเลิก</Btn>
              </div>
            </>
          )}
        </Card>
      )}

      <div className="space-y-3">
        {promotions.map(p => {
          const t = PROMO_TYPES.find(t => t.key === p.type);
          return (
            <Card key={p.id} className="p-4 flex items-center justify-between gap-3">
              <div className="flex items-center gap-3 min-w-0">
                <div className={`w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0 ${p.active ? "bg-amber-50" : "bg-stone-100"}`}>
                  {t ? <t.icon size={18} className={p.active ? "text-amber-600" : "text-stone-400"} /> : <Sparkles size={18} className="text-stone-400" />}
                </div>
                <div className="min-w-0">
                  <div className="font-medium text-stone-800 flex items-center gap-2">
                    {p.name}
                    <span className="text-[10px] px-1.5 py-0.5 rounded bg-stone-100 text-stone-500 flex-shrink-0">{t?.label}</span>
                  </div>
                  <div className="text-xs text-stone-400 mt-0.5 truncate">{promoSummary(p)} · {fmtDate(p.start)} ถึง {fmtDate(p.end)}</div>
                  {p.excludedCategoryIds.length > 0 && (
                    <div className="text-[11px] text-rose-500 mt-0.5">ไม่ร่วมรายการ: {p.excludedCategoryIds.map(id => categories.find(c => c.id === id)?.name).filter(Boolean).join(", ")}</div>
                  )}
                </div>
              </div>
              <div className="flex items-center gap-5 flex-shrink-0">
                <button onClick={() => toggle(p.id)}
                  className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${p.active ? "bg-emerald-500" : "bg-stone-300"}`}>
                  <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${p.active ? "translate-x-5" : "translate-x-0"}`} />
                </button>
                <div className="flex items-center gap-3">
                  <button onClick={() => startEdit(p)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                  <button onClick={() => remove(p.id)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                </div>
              </div>
            </Card>
          );
        })}
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: STORE INFO
   ========================================================================= */

function StoreInfoPage({ storeInfo, setStoreInfo }) {
  const [form, setForm] = useState(storeInfo);
  const [saved, setSaved] = useState(false);
  const logoInputRef = useRef(null);
  const qrInputRef = useRef(null);

  function change(patch) {
    setForm(prev => ({ ...prev, ...patch }));
    setSaved(false);
  }
  function save() {
    setStoreInfo(form);
    setSaved(true);
  }
  function handleFile(e, key) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => change({ [key]: reader.result });
    reader.readAsDataURL(file);
  }

  function addChannel() {
    change({ contactChannels: [...form.contactChannels, { id: "cc" + Date.now(), type: "Facebook", value: "" }] });
  }
  function updateChannel(id, patch) {
    change({ contactChannels: form.contactChannels.map(c => c.id === id ? { ...c, ...patch } : c) });
  }
  function removeChannel(id) {
    change({ contactChannels: form.contactChannels.filter(c => c.id !== id) });
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ข้อมูลร้านค้า"
        subtitle={<>ข้อมูลนี้จะแสดงในใบเสร็จอัตโนมัติ (หน้า "ตั้งค่า → รูปแบบใบเสร็จ") · <span className="text-emerald-600 font-medium">ตั้งค่าไว้แล้ว</span></>} />

      <div className="max-w-2xl space-y-5">
        {/* 1. Logo & name */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-4">
            <StepBadge n={1} />
            <span className="font-semibold text-stone-800">โลโก้ และชื่อร้าน</span>
          </div>
          <div className="ml-8">
            <div className="flex items-center gap-4 mb-4">
              <img src={form.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-full object-cover border border-stone-200" />
              <input ref={logoInputRef} type="file" accept="image/*" className="hidden" onChange={e => handleFile(e, "logoDataUrl")} />
              <Btn variant="ghost" onClick={() => logoInputRef.current?.click()}>อัปโหลดโลโก้</Btn>
            </div>
            <div className="space-y-4">
              <Field label="ชื่อร้าน"><input className={inputCls} value={form.name} onChange={e => change({ name: e.target.value })} /></Field>
              <Field label="แท็กไลน์ / คำอธิบายสั้นๆ"><input className={inputCls} value={form.tagline} onChange={e => change({ tagline: e.target.value })} placeholder="เช่น The Nur — ตำ ยำ แซ่บ" /></Field>
            </div>
          </div>
        </Card>

        {/* 2. Phone & contact channels */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-4">
            <StepBadge n={2} />
            <span className="font-semibold text-stone-800">เบอร์โทร และช่องทางติดต่อ</span>
          </div>
          <div className="ml-8 space-y-4">
            <Field label="เบอร์โทรศัพท์ร้าน"><input className={inputCls} value={form.phone} onChange={e => change({ phone: e.target.value })} /></Field>

            <div>
              <div className="block text-xs font-medium text-stone-500 mb-2">ช่องทางติดต่ออื่นๆ</div>
              <div className="space-y-2">
                {form.contactChannels.map(c => (
                  <div key={c.id} className="flex items-center gap-2">
                    <select className={`${inputCls} max-w-[140px]`} value={c.type} onChange={e => updateChannel(c.id, { type: e.target.value })}>
                      {["Facebook", "Instagram", "TikTok", "Website", "อื่นๆ"].map(t => <option key={t}>{t}</option>)}
                    </select>
                    <input className={inputCls} value={c.value} onChange={e => updateChannel(c.id, { value: e.target.value })} placeholder="ชื่อบัญชี / ลิงก์" />
                    <button onClick={() => removeChannel(c.id)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                  </div>
                ))}
              </div>
            </div>

            <Btn variant="ghost" onClick={addChannel}><Plus size={14} /> เพิ่มช่องทางติดต่อ</Btn>
          </div>
        </Card>

        {/* 3. QR Code LINE */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-1">
            <StepBadge n={3} />
            <span className="font-semibold text-stone-800">QR Code LINE</span>
          </div>
          <p className="text-sm text-stone-400 mb-4 ml-8">ใส่ LINE OA ID เพื่อสร้าง QR อัตโนมัติ หรืออัปโหลดรูป QR ของจริงที่ export มาจาก LINE OA ก็ได้ (ถ้าอัปโหลดรูปไว้ จะใช้รูปที่อัปโหลดก่อนเสมอ)</p>
          <div className="ml-8">
            <Field label="LINE OA ID">
              <div className="flex items-center gap-2">
                <input className={inputCls} value={form.lineOaId} onChange={e => change({ lineOaId: e.target.value })} placeholder="เช่น @thenur" />
                <input ref={qrInputRef} type="file" accept="image/*" className="hidden" onChange={e => handleFile(e, "lineQrDataUrl")} />
                <Btn variant="ghost" className="whitespace-nowrap" onClick={() => qrInputRef.current?.click()}>อัปโหลดรูป QR LINE (ถ้ามี)</Btn>
                {form.lineQrDataUrl && (
                  <button onClick={() => change({ lineQrDataUrl: null })} className="text-xs text-rose-500 hover:text-rose-700 whitespace-nowrap">ลบรูปที่อัปโหลด</button>
                )}
              </div>
            </Field>

            <div className="mt-4 w-32 h-32 rounded-lg border border-stone-200 bg-white flex items-center justify-center overflow-hidden">
              {form.lineQrDataUrl ? (
                <img src={form.lineQrDataUrl} alt="LINE QR" className="w-full h-full object-cover" />
              ) : form.lineOaId ? (
                <div className="text-stone-300 flex flex-col items-center gap-1">
                  <QrCode size={40} />
                  <span className="text-[9px] text-stone-400">{form.lineOaId}</span>
                </div>
              ) : (
                <QrCode size={40} className="text-stone-200" />
              )}
            </div>

            <div className="mt-5 pt-4 border-t border-stone-200">
              <label className="flex items-center justify-between cursor-pointer mb-3">
                <span className="text-sm font-medium text-stone-700">แสดง QR Code นี้ในใบเสร็จ</span>
                <button onClick={() => change({ lineQrShowOnReceipt: !form.lineQrShowOnReceipt })}
                  className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${form.lineQrShowOnReceipt ? "bg-emerald-500" : "bg-stone-300"}`}>
                  <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${form.lineQrShowOnReceipt ? "translate-x-5" : "translate-x-0"}`} />
                </button>
              </label>
              {form.lineQrShowOnReceipt && (
                <div className="space-y-2 pl-1">
                  <p className="text-xs text-stone-400 mb-1">แสดงในเอกสารประเภทไหนบ้าง</p>
                  <label className="flex items-center gap-2 text-sm text-stone-600 cursor-pointer">
                    <input type="checkbox" checked={form.lineQrOnPlainReceipt !== false} onChange={e => change({ lineQrOnPlainReceipt: e.target.checked })} />
                    ใบเสร็จรับเงิน / ใบกำกับภาษีอย่างย่อ
                  </label>
                  <label className="flex items-center gap-2 text-sm text-stone-600 cursor-pointer">
                    <input type="checkbox" checked={form.lineQrOnFullTaxInvoice !== false} onChange={e => change({ lineQrOnFullTaxInvoice: e.target.checked })} />
                    ใบกำกับภาษีเต็มรูปแบบ
                  </label>
                </div>
              )}
            </div>
          </div>
        </Card>

        {/* 4. Tax invoice info */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-4">
            <StepBadge n={4} />
            <span className="font-semibold text-stone-800">ข้อมูลใบกำกับภาษี</span>
          </div>
          <div className="ml-8 space-y-4">
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <Field label="ชื่อบริษัท"><input className={inputCls} value={form.companyName} onChange={e => change({ companyName: e.target.value })} placeholder="เช่น บริษัท เดอะนัวล์ จำกัด" /></Field>
              <Field label="สาขา"><input className={inputCls} value={form.officeType} onChange={e => change({ officeType: e.target.value })} placeholder="เช่น สำนักงานใหญ่ หรือ สาขาที่ 1" /></Field>
            </div>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <Field label="เลขประจำตัวผู้เสียภาษี"><input className={inputCls} value={form.taxId} onChange={e => change({ taxId: e.target.value })} /></Field>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <Field label="เวลาเปิด"><input type="time" className={inputCls} value={form.openTime} onChange={e => change({ openTime: e.target.value })} /></Field>
                <Field label="เวลาปิด"><input type="time" className={inputCls} value={form.closeTime} onChange={e => change({ closeTime: e.target.value })} /></Field>
              </div>
            </div>
            <Field label="ที่อยู่ร้าน"><input className={inputCls} value={form.address} onChange={e => change({ address: e.target.value })} /></Field>
          </div>
        </Card>

        <div>
          <Btn onClick={save}>บันทึกข้อมูลร้านค้า</Btn>
          {saved && <span className="text-emerald-600 text-xs ml-3">บันทึกเรียบร้อย ✓</span>}
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   SHARED: TOGGLE ROW
   ========================================================================= */

function ToggleRow({ label, checked, onChange }) {
  return (
    <div className="flex items-center justify-between py-2.5 border-b border-stone-100 last:border-0">
      <span className="text-sm text-stone-600">{label}</span>
      <button onClick={() => onChange(!checked)}
        className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${checked ? "bg-emerald-500" : "bg-stone-300"}`}>
        <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${checked ? "translate-x-5" : "translate-x-0"}`} />
      </button>
    </div>
  );
}

function SlipPreviewShell({ children, width = "w-64" }) {
  return (
    <div className="flex justify-center">
      <div className={`${width} bg-white border border-stone-300 rounded-md shadow-sm p-4 font-mono text-xs text-stone-700`}
        style={{ backgroundImage: "repeating-linear-gradient(transparent, transparent 100%)" }}>
        {children}
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: SLIP DESIGN — ใบเสร็จ (RECEIPT)
   ========================================================================= */

function SlipReceiptPage({ settings, setSettings, storeInfo, paymentSettings }) {
  const s = settings.receipt;
  const set = patch => setSettings(prev => ({ ...prev, receipt: { ...prev.receipt, ...patch } }));
  const pad = (n, len) => String(n).padStart(len, "0");
  const billNo = `${s.billPrefixStore || ""}-${pad(s.billStartStore || 1, 4)}`;

  return (
    <div>
      <PageHeader eyebrow="ออกแบบสลิป" title="ใบเสร็จ - ใบกำกับภาษี" subtitle="กำหนดรูปแบบใบเสร็จรับเงินที่พิมพ์ให้ลูกค้า" />
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-5">
        <div className="col-span-1 lg:col-span-7 space-y-5">
          {/* 1. Logo & text */}
          <Card className="p-5">
            <div className="flex items-center gap-2.5 mb-1">
              <StepBadge n={1} />
              <span className="font-semibold text-stone-800">โลโก้ และข้อความ</span>
            </div>
            <p className="text-sm text-stone-400 mb-4 ml-8">โลโก้, ชื่อร้าน, เบอร์โทร, ช่องทางติดต่อ และ QR LINE ตั้งค่าได้ที่แท็บ "ข้อมูลร้านค้า" — จะแสดงในใบเสร็จอัตโนมัติ</p>
            <div className="ml-8 space-y-4">
              <ToggleRow label="ดูตัวอย่างแบบใบกำกับภาษีเต็มรูปแบบ" checked={s.fullTaxInvoice} onChange={v => set({ fullTaxInvoice: v })} />
              <p className="text-xs text-stone-400 -mt-2">แค่สลับดูตัวอย่าง 2 แบบเท่านั้น — ของจริงพนักงานจะเลือก "ขอใบกำกับภาษีเต็มรูปแบบ" (บุคคลธรรมดา/นิติบุคคล) เป็นรายบิลเองตอนหน้าชำระเงินที่ POS ไม่ใช่การตั้งค่าตายตัวทั้งร้าน</p>
              <Field label="ข้อความส่วนหัว">
                <textarea rows={2} className={inputCls} value={s.headerText} onChange={e => set({ headerText: e.target.value })} placeholder="เช่น เดอะนัวล์ — ตำ ยำ แซ่บ" />
              </Field>
              <Field label="ข้อความส่วนท้าย">
                <textarea rows={2} className={inputCls} value={s.footerText} onChange={e => set({ footerText: e.target.value })} placeholder="ขอบคุณที่ใช้บริการ เดอะนัวล์" />
              </Field>
            </div>
          </Card>

          {/* 2. Reference numbers */}
          <Card className="p-5">
            <div className="flex items-center gap-2.5 mb-4">
              <StepBadge n={2} />
              <span className="font-semibold text-stone-800">หมายเลขอ้างอิง</span>
            </div>
            <div className="ml-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
              <div>
                <label className="flex items-center justify-between cursor-pointer mb-1.5">
                  <span className="text-sm font-medium text-stone-700">หมายเลขประจำเครื่อง POS</span>
                  <button onClick={() => set({ posNumberEnabled: !s.posNumberEnabled })}
                    className={`relative w-9 h-5 rounded-full transition-colors flex-shrink-0 ${s.posNumberEnabled ? "bg-emerald-500" : "bg-stone-300"}`}>
                    <span className={`absolute left-0.5 top-0.5 w-4 h-4 bg-white rounded-full shadow transition-transform ${s.posNumberEnabled ? "translate-x-4" : "translate-x-0"}`} />
                  </button>
                </label>
                <input className={inputCls} value={s.posNumber} onChange={e => set({ posNumber: e.target.value })} placeholder="เช่น POS-001" disabled={!s.posNumberEnabled} />
                <p className="text-[11px] text-stone-400 mt-1">{s.posNumberEnabled ? "จะแสดงในใบเสร็จจริง" : "ปิดอยู่ — จะไม่แสดงในใบเสร็จ"}</p>
              </div>
              <Field label="หมายเลขผู้เสียภาษี">
                <input className={inputCls} value={s.taxPayerNumber} onChange={e => set({ taxPayerNumber: e.target.value })} placeholder="เลข 13 หลัก" />
              </Field>
            </div>
          </Card>

          {/* 3. Bill numbering */}
          <Card className="p-5">
            <div className="flex items-center gap-2.5 mb-1">
              <StepBadge n={3} />
              <span className="font-semibold text-stone-800">เลขที่บิล</span>
            </div>
            <p className="text-sm text-stone-400 mb-4 ml-8">กำหนดคำนำหน้าและเลขเริ่มต้นของบิล แยกหน้าร้านกับออนไลน์</p>
            <div className="ml-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
              <Field label="บิลหน้าร้าน — คำนำหน้า">
                <input className={inputCls} value={s.billPrefixStore} onChange={e => set({ billPrefixStore: e.target.value })} placeholder="TN" />
              </Field>
              <Field label="บิลหน้าร้าน — เลขเริ่มต้น">
                <input type="number" min={1} className={inputCls} value={s.billStartStore} onChange={e => set({ billStartStore: Number(e.target.value) })} />
              </Field>
              <Field label="บิลออนไลน์ — คำนำหน้า">
                <input className={inputCls} value={s.billPrefixOnline} onChange={e => set({ billPrefixOnline: e.target.value })} placeholder="TNO" />
              </Field>
              <Field label="บิลออนไลน์ — เลขเริ่มต้น">
                <input type="number" min={1} className={inputCls} value={s.billStartOnline} onChange={e => set({ billStartOnline: Number(e.target.value) })} />
              </Field>
            </div>
          </Card>

          <Btn>บันทึกรูปแบบใบเสร็จ</Btn>
        </div>

        <div className="col-span-1 lg:col-span-5">
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ตัวอย่างใบเสร็จ</div>
          <SlipPreviewShell width="w-64">
            <img src={storeInfo.logoDataUrl || LOGO_DATA_URI} alt="logo" className="w-12 h-12 rounded-full object-cover mx-auto mb-2" />
            <div className="text-center font-semibold text-stone-800 text-sm">{storeInfo.name}</div>
            {s.headerText && <div className="text-center text-[10px] text-stone-400 mb-1">{s.headerText}</div>}
            {storeInfo.address && <div className="text-center text-[10px] text-stone-400">{storeInfo.address}</div>}
            {storeInfo.taxId && <div className="text-center text-[10px] text-stone-400">TAX ID: {storeInfo.taxId}</div>}
            <div className="text-center text-[10px] text-stone-400">Tel: {storeInfo.phone.replace(/-/g, "")}</div>

            <div className="text-center font-semibold text-xs mt-2">{!paymentSettings?.vat?.enabled ? "ใบเสร็จรับเงิน" : s.fullTaxInvoice ? "ใบเสร็จรับเงิน/ใบกำกับภาษี" : "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ"}</div>
            {paymentSettings?.vat?.enabled && <div className="text-center text-[10px] text-stone-400">รวมภาษีมูลค่าเพิ่ม</div>}

            <div className="border-t border-dashed border-stone-300 my-2" />
            <div className="flex justify-between text-[10px] text-stone-400">
              <span>Table: 5</span>
              <span>ID: {billNo}</span>
            </div>
            <div className="flex justify-between text-[10px] text-stone-400">
              <span>Date: 16/07/2026</span>
              <span>Time: 17:46</span>
            </div>
            {s.posNumberEnabled && s.posNumber && (
              <div className="text-[10px] text-stone-400">POS: {s.posNumber}</div>
            )}

            <div className="border-t border-dashed border-stone-300 my-2" />
            <div className="flex justify-between"><span>2 ส้มตำไทย</span><span>130</span></div>
            <div className="flex justify-between"><span>1 คอหมูย่างแซ่บ</span><span>120</span></div>
            <div className="flex justify-between"><span>3 ข้าวเหนียว</span><span>45</span></div>

            <div className="border-t border-dashed border-stone-300 my-2" />
            {paymentSettings?.vat?.enabled ? (
              <>
                <div className="flex justify-between"><span>Before Tax:</span><span>295</span></div>
                <div className="flex justify-between"><span>TAX(7%):</span><span>21</span></div>
              </>
            ) : (
              <div className="flex justify-between"><span>ยอดรวม:</span><span>295</span></div>
            )}
            <div className="border-t-2 border-double border-stone-400 my-1" />
            <div className="flex justify-between font-semibold text-sm"><span>Total:</span><span>฿{paymentSettings?.vat?.enabled ? "316" : "295"}</span></div>
            <div className="border-t-2 border-double border-stone-400 my-1" />
            <div className="flex justify-between text-[10px] text-stone-500"><span>เงินสด:</span><span>{paymentSettings?.vat?.enabled ? "316.00" : "295.00"}</span></div>

            {paymentSettings?.vat?.enabled && s.fullTaxInvoice && (
              <>
                <div className="border-t border-dashed border-stone-300 my-2" />
                <div className="text-[10px] text-stone-400">Customer Name: บริษัท ตัวอย่าง จำกัด</div>
                <div className="text-[10px] text-stone-400">Address: 99 ถนนตัวอย่าง กรุงเทพฯ</div>
                <div className="text-[10px] text-stone-400">TAX ID: 0105561000000</div>
                <div className="text-[10px] text-stone-400">Branch: สำนักงานใหญ่</div>
              </>
            )}

            <div className="border-t border-dashed border-stone-300 my-2" />
            <div className="text-center text-[10px] text-stone-400">{s.footerText}</div>

            {(() => {
              const qrApplies = storeInfo.lineQrShowOnReceipt &&
                (s.fullTaxInvoice ? storeInfo.lineQrOnFullTaxInvoice !== false : storeInfo.lineQrOnPlainReceipt !== false);
              if (storeInfo.lineQrDataUrl && qrApplies) {
                return (
                  <>
                    <img src={storeInfo.lineQrDataUrl} alt="LINE QR" className="w-16 h-16 mx-auto my-2 object-cover" />
                    <div className="text-center text-[10px] text-stone-400">แอดไลน์ร้านเพื่อรับโปรโมชั่น</div>
                  </>
                );
              }
              if (!storeInfo.lineQrDataUrl) {
                return <p className="text-center text-[10px] text-stone-300 mt-2">ยังไม่ได้อัปโหลดรูป QR LINE — อัปโหลดได้ที่แท็บ "ข้อมูลร้านค้า" เพื่อให้แสดงในใบเสร็จ</p>;
              }
              return <p className="text-center text-[10px] text-stone-300 mt-2">ปิดการแสดง QR ไว้สำหรับเอกสารประเภทนี้ — ปรับได้ที่แท็บ "ข้อมูลร้านค้า"</p>;
            })()}
          </SlipPreviewShell>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: SLIP DESIGN — ใบสรุปยอด (precheck bill)
   ========================================================================= */

function SlipPrecheckBillPage({ settings, setSettings, storeInfo, paymentSettings }) {
  const s = settings.precheckBill;
  const set = patch => setSettings(prev => ({ ...prev, precheckBill: { ...prev.precheckBill, ...patch } }));

  const sampleItems = [
    { name: "ส้มตำไทย", qty: 2, price: 130 },
    { name: "คอหมูย่างแซ่บ", qty: 1, price: 120 },
    { name: "ข้าวเหนียว", qty: 3, price: 45 },
  ];
  const sampleSubtotal = sampleItems.reduce((s2, it) => s2 + it.price, 0);
  const sampleVat = paymentSettings?.vat?.enabled ? Math.round(sampleSubtotal * (paymentSettings.vat.rate / 100) * 100) / 100 : 0;
  const sampleTotal = sampleSubtotal + sampleVat;

  return (
    <div>
      <PageHeader eyebrow="ออกแบบสลิป" title="ใบสรุปยอด" subtitle="กำหนดรูปแบบใบแจ้งยอดที่พิมพ์ให้ลูกค้าชำระเงิน" />
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-5">
        <div className="col-span-1 lg:col-span-7 space-y-5">
          {/* 1. Logo & text */}
          <Card className="p-5">
            <div className="flex items-center gap-2.5 mb-1">
              <StepBadge n={1} />
              <span className="font-semibold text-stone-800">โลโก้ และข้อความ</span>
            </div>
            <p className="text-sm text-stone-400 mb-4 ml-8">ชื่อร้าน, เบอร์โทร, ช่องทางติดต่อ และ QR LINE ตั้งค่าได้ที่แท็บ "ข้อมูลร้านค้า" — จะแสดงอัตโนมัติ</p>
            <div className="ml-8 space-y-4">
              <Field label="ข้อความส่วนหัว">
                <textarea rows={2} className={inputCls} value={s.headerText} onChange={e => set({ headerText: e.target.value })} placeholder="เช่น ตำ ยำ แซ่บ" />
              </Field>
              <Field label="ข้อความส่วนท้าย (2 บรรทัด)">
                <textarea rows={2} className={inputCls} value={s.footerText} onChange={e => set({ footerText: e.target.value })} placeholder={"ขอบคุณที่ใช้บริการ เดอะนัวล์\nกรุณาชำระเงินที่แคชเชียร์"} />
              </Field>
            </div>
          </Card>

          <Btn>บันทึกรูปแบบใบเสร็จ</Btn>
        </div>

        <div className="col-span-1 lg:col-span-5">
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ตัวอย่าง</div>
          <SlipPreviewShell width="w-64">
            <div className="text-center font-semibold text-stone-800 text-sm">{storeInfo.name}</div>
            {s.headerText && <div className="text-center text-[10px] text-stone-400 mb-1">{s.headerText}</div>}
            {storeInfo.address && <div className="text-center text-[10px] text-stone-400">{storeInfo.address}</div>}
            {storeInfo.taxId && <div className="text-center text-[10px] text-stone-400">TAX ID: {storeInfo.taxId}</div>}
            <div className="text-center text-[10px] text-stone-400 mb-2">Tel: {storeInfo.phone.replace(/-/g, "")}</div>

            <div className="text-center font-semibold text-xs mb-2">ใบแจ้งยอดค่าอาหาร</div>
            <div className="border-t border-dashed border-stone-300 my-1.5" />

            <div className="flex justify-between text-[11px]"><span>Table: 5</span><span>ID: TN-0001</span></div>
            <div className="flex justify-between text-[11px] mb-1.5"><span>Date: {fmtDate(new Date().toISOString().slice(0, 10))}</span><span>Time: {new Date().toLocaleTimeString("th-TH", { hour: "2-digit", minute: "2-digit" })}</span></div>
            <div className="border-t border-dashed border-stone-300 my-1.5" />

            {sampleItems.map((it, i) => (
              <div key={i} className="flex justify-between text-[11px]"><span>{it.qty} {it.name}</span><span>{it.price}</span></div>
            ))}
            <div className="border-t border-dashed border-stone-300 my-1.5" />

            <div className="flex justify-between text-[11px]"><span>Before Tax:</span><span>{sampleSubtotal}</span></div>
            {paymentSettings?.vat?.enabled && (
              <div className="flex justify-between text-[11px]"><span>TAX({paymentSettings.vat.rate}%):</span><span>{sampleVat}</span></div>
            )}
            <div className="border-t border-stone-300 my-1.5" />
            <div className="flex justify-between font-semibold text-sm"><span>Total:</span><span>฿{fmtMoney(sampleTotal)}</span></div>

            {s.footerText && (
              <div className="text-center text-[10px] text-stone-400 mt-3 whitespace-pre-line">{s.footerText}</div>
            )}

            <div className="border-t border-dashed border-stone-300 my-2" />
            <div className="w-16 h-16 bg-stone-100 border border-stone-200 rounded mx-auto flex items-center justify-center text-[9px] text-stone-400 text-center">QR<br />PROMPTPAY</div>
          </SlipPreviewShell>
          <p className="text-[11px] text-stone-400 text-center mt-2">QR PromptPay ใช้ค่าที่ตั้งไว้ในหน้า "สาขา" หรือ "ช่องทางการเงิน" อัตโนมัติ — ปรับได้ที่หน้านั้น</p>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: SLIP DESIGN — ใบสั่งอาหาร (QR ORDER)
   ========================================================================= */

function SlipOrderQrPage({ settings, setSettings, storeInfo }) {
  const [draft, setDraft] = useState(settings.orderQr);
  const [saved, setSaved] = useState(false);
  const s = draft;
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings.orderQr);
  useEffect(() => { setDraft(settings.orderQr); }, [settings.orderQr]);
  const set = patch => setDraft(prev => ({ ...prev, ...patch }));
  function saveChanges() {
    setSettings(prev => ({ ...prev, orderQr: draft }));
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }
  return (
    <div>
      <PageHeader eyebrow="ออกแบบสลิป" title="ใบสั่งอาหาร (QR สั่งอาหาร)" subtitle="ออกแบบป้าย QR Code สำหรับให้ลูกค้าสแกนสั่งอาหารเอง" />
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-5">
        <div className="col-span-1 lg:col-span-7">
          <Card className="p-5">
            <ToggleRow label="แสดงชื่อโต๊ะบนป้าย" checked={s.showTableName} onChange={v => set({ showTableName: v })} />
            <div className="pt-3">
              <Field label="ขนาด QR Code">
                <div className="flex gap-2">
                  {["small", "medium", "large"].map(sz => (
                    <button key={sz} onClick={() => set({ qrSize: sz })}
                      className={`px-3 py-1.5 rounded-md text-sm border capitalize ${s.qrSize === sz ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>{sz}</button>
                  ))}
                </div>
              </Field>
            </div>
            <div className="pt-3"><Field label="หัวข้อ"><input className={inputCls} value={s.headline} onChange={e => set({ headline: e.target.value })} /></Field></div>
            <div className="pt-3"><Field label="ข้อความอธิบาย"><input className={inputCls} value={s.message} onChange={e => set({ message: e.target.value })} /></Field></div>
            {isDirty && <div className="text-xs text-amber-700 mt-3">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</div>}
            <div className="flex items-center gap-3 mt-4">
              <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
              {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings.orderQr)}>ยกเลิกการแก้ไข</Btn>}
              {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
            </div>
          </Card>
        </div>
        <div className="col-span-1 lg:col-span-5">
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ตัวอย่างป้ายโต๊ะ</div>
          <div className="flex justify-center">
            <div className="w-56 bg-white border border-stone-300 rounded-lg shadow-sm p-5 text-center">
              <div className="font-semibold text-stone-800">{storeInfo.name}</div>
              {s.showTableName && <div className="inline-block mt-2 text-xs px-2 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">โต๊ะ T4</div>}
              <div className="text-sm font-medium text-stone-700 mt-3">{s.headline}</div>
              <div className={`bg-stone-100 mx-auto my-3 flex items-center justify-center text-stone-300 rounded
                ${s.qrSize === "small" ? "w-16 h-16" : s.qrSize === "large" ? "w-32 h-32" : "w-24 h-24"}`}>
                <QrCode size={s.qrSize === "small" ? 24 : s.qrSize === "large" ? 56 : 40} />
              </div>
              <div className="text-xs text-stone-400">{s.message}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: SLIP DESIGN — ใบออเดอร์ (KITCHEN ORDER)
   ========================================================================= */

function SlipKitchenOrderPage({ settings, setSettings }) {
  const [draft, setDraft] = useState(settings.kitchenOrder);
  const [saved, setSaved] = useState(false);
  const s = draft;
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings.kitchenOrder);
  useEffect(() => { setDraft(settings.kitchenOrder); }, [settings.kitchenOrder]);
  const set = patch => setDraft(prev => ({ ...prev, ...patch }));
  function saveChanges() {
    setSettings(prev => ({ ...prev, kitchenOrder: draft }));
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }
  return (
    <div>
      <PageHeader eyebrow="ออกแบบสลิป" title="ใบออเดอร์ (สำหรับครัว)" subtitle="กำหนดรูปแบบใบออเดอร์ที่พิมพ์ส่งเข้าครัว" />
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-5">
        <div className="col-span-1 lg:col-span-7">
          <Card className="p-5">
            <ToggleRow label="แสดงราคาบนใบออเดอร์" checked={s.showPrice} onChange={v => set({ showPrice: v })} />
            <ToggleRow label="แสดงเวลาที่สั่ง" checked={s.showTime} onChange={v => set({ showTime: v })} />
            <ToggleRow label="จัดกลุ่มตามหมวดหมู่อาหาร" checked={s.groupByCategory} onChange={v => set({ groupByCategory: v })} />
            <div className="pt-3">
              <Field label="ขนาดตัวอักษร">
                <div className="flex gap-2">
                  {["normal", "large"].map(sz => (
                    <button key={sz} onClick={() => set({ fontSize: sz })}
                      className={`px-3 py-1.5 rounded-md text-sm border capitalize ${s.fontSize === sz ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>{sz}</button>
                  ))}
                </div>
              </Field>
            </div>
            {isDirty && <div className="text-xs text-amber-700 mt-3">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</div>}
            <div className="flex items-center gap-3 mt-4">
              <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
              {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings.kitchenOrder)}>ยกเลิกการแก้ไข</Btn>}
              {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
            </div>
          </Card>
        </div>
        <div className="col-span-1 lg:col-span-5">
          <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ตัวอย่างใบออเดอร์</div>
          <SlipPreviewShell>
            <div className="flex justify-between font-semibold text-stone-800 mb-1"><span>#231 · โต๊ะ T2</span></div>
            {s.showTime && <div className="text-[10px] text-stone-400 mb-2">18:24 น.</div>}
            <div className="border-t border-dashed border-stone-300 my-2" />
            {s.groupByCategory && <div className="text-[10px] text-amber-700 font-semibold mb-1">— อาหารคาว —</div>}
            <div className={`flex justify-between ${s.fontSize === "large" ? "text-sm" : "text-xs"}`}><span>ผัดกะเพราหมูสับ x2</span>{s.showPrice && <span>130</span>}</div>
            <div className={`flex justify-between ${s.fontSize === "large" ? "text-sm" : "text-xs"}`}><span>ข้าวผัดปู x1</span>{s.showPrice && <span>95</span>}</div>
            {s.groupByCategory && <div className="text-[10px] text-amber-700 font-semibold mt-2 mb-1">— ของทานเล่น —</div>}
            <div className={`flex justify-between ${s.fontSize === "large" ? "text-sm" : "text-xs"}`}><span>ปีกไก่ทอดน้ำปลา x1</span>{s.showPrice && <span>70</span>}</div>
          </SlipPreviewShell>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: SALES CHANNELS
   ========================================================================= */

const CHANNEL_COLOR = {
  stone: "bg-stone-100 text-stone-700 border-stone-300",
  navy: "bg-blue-100 text-blue-900 border-blue-300",
  emerald: "bg-emerald-100 text-emerald-800 border-emerald-300",
  green: "bg-green-100 text-green-800 border-green-300",
  sky: "bg-sky-100 text-sky-800 border-sky-300",
  rose: "bg-rose-100 text-rose-800 border-rose-300",
  orange: "bg-orange-100 text-orange-800 border-orange-300",
};

/* Solid brand-colored buttons used for the channel picker (open-order modal). */
const CHANNEL_SOLID_COLOR = {
  stone: "bg-stone-800 hover:bg-stone-900 text-white",
  navy: "bg-blue-950 hover:bg-blue-900 text-white",
  emerald: "bg-emerald-500 hover:bg-emerald-600 text-white",
  green: "bg-green-500 hover:bg-green-600 text-white",
  sky: "bg-sky-500 hover:bg-sky-600 text-white",
  rose: "bg-rose-500 hover:bg-rose-600 text-white",
  orange: "bg-orange-500 hover:bg-orange-600 text-white",
};

/* =========================================================================
   PAGE: ตั้งค่าระบบ — ตั้งค่าส่งใบเสร็จ
   ========================================================================= */

function EmailReceiptSettingsPage({ settings, setSettings }) {
  const [draft, setDraft] = useState(settings);
  const [saved, setSaved] = useState(false);
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings);
  useEffect(() => { setDraft(settings); }, [settings]);
  function saveChanges() {
    setSettings(draft);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }
  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ตั้งค่าส่งใบเสร็จ" subtitle="กำหนดหัวข้อและรายละเอียดอีเมลที่ส่งใบเสร็จให้ลูกค้า" />
      <Card className="p-5 max-w-xl">
        <p className="text-xs text-stone-400 mb-4">
          ใช้ตัวแปรเหล่านี้ในข้อความได้ ระบบจะแทนที่ด้วยข้อมูลจริงตอนส่ง: <code className="font-mono bg-stone-100 px-1 rounded">{"{ชื่อร้าน}"}</code> <code className="font-mono bg-stone-100 px-1 rounded">{"{ชื่อลูกค้า}"}</code> <code className="font-mono bg-stone-100 px-1 rounded">{"{เลขที่ใบเสร็จ}"}</code> <code className="font-mono bg-stone-100 px-1 rounded">{"{ยอดรวม}"}</code>
        </p>
        <div className="space-y-4">
          <Field label="หัวข้ออีเมล (Subject)">
            <input className={inputCls} value={draft.subject} onChange={e => setDraft(d => ({ ...d, subject: e.target.value }))} placeholder="เช่น ใบเสร็จจาก {ชื่อร้าน}" />
          </Field>
          <Field label="รายละเอียดอีเมล (Body)">
            <textarea rows={6} className={inputCls} value={draft.body} onChange={e => setDraft(d => ({ ...d, body: e.target.value }))} />
          </Field>
        </div>
        {isDirty && <div className="text-xs text-amber-700 mt-3">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</div>}
        <div className="flex items-center gap-3 mt-4">
          <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
          {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings)}>ยกเลิกการแก้ไข</Btn>}
          {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-4 max-w-xl">
        หมายเหตุ: ระบบจะลองส่งจริงผ่าน SMTP ก่อน โดยยิงไปที่ endpoint <code className="font-mono bg-stone-100 px-1 rounded">/send-email</code> ของ print agent เครื่องเดียวกับที่ใช้พิมพ์ใบเสร็จ (host/port เดียวกัน ตั้งค่าได้ที่หน้า "ตั้งค่า Port") — ถ้า endpoint นี้ยังไม่มีในเครื่อง print agent หรือเชื่อมต่อไม่ได้ ระบบจะ fallback ไปเปิดโปรแกรมอีเมลของเครื่อง (mailto:) ให้พนักงานกดส่งเองแทนโดยอัตโนมัติ ไม่ต้องกังวลว่าจะพังถ้ายังไม่ได้ตั้งค่า backend ส่วนนี้
      </p>
    </div>
  );
}

function emptyChannelForm() {
  return { name: "", color: "stone", adjustType: "none", value: "" };
}

function SalesChannelsPage({ channels, setChannels, menu, staff, ownerProfile, logActivity }) {
  const [newOption, setNewOption] = useState({});
  const [draft, setDraft] = useState(channels);
  const [saved, setSaved] = useState(false);
  const [showAddForm, setShowAddForm] = useState(false);
  const [form, setForm] = useState(emptyChannelForm());
  const [deletingChannel, setDeletingChannel] = useState(null);
  const isDirty = JSON.stringify(draft) !== JSON.stringify(channels);
  useEffect(() => { setDraft(channels); }, [channels]);
  // Picks menu[1] (ข้าวผัดปู ฿95 in the original SEED menu) just as a
  // reference item to preview price adjustments — purely for display, not
  // tied to any real order. Falls back to menu[0] or null once the SEED menu
  // has been cleaned up and there's no second (or any) item left, so this
  // page doesn't crash the whole app when menu.length < 2.
  const sample = menu[1] || menu[0] || null;
  function updateValue(id, value) {
    setDraft(prev => prev.map(c => c.id === id ? { ...c, value: Number(value) } : c));
  }
  function updateType(id, adjustType) {
    setDraft(prev => prev.map(c => c.id === id ? { ...c, adjustType, value: adjustType === "none" ? 0 : c.value } : c));
  }
  function priceFor(c) {
    if (!sample) return 0;
    if (c.adjustType === "percent") return Math.round(sample.price * (1 + c.value / 100));
    if (c.adjustType === "fixed") return sample.price + c.value;
    return sample.price;
  }
  function addFulfillment(chId) {
    const val = (newOption[chId] || "").trim();
    if (!val) return;
    setDraft(prev => prev.map(c => c.id === chId ? { ...c, fulfillmentOptions: [...(c.fulfillmentOptions || []), val] } : c));
    setNewOption(prev => ({ ...prev, [chId]: "" }));
  }
  function removeFulfillment(chId, opt) {
    setDraft(prev => prev.map(c => c.id === chId ? { ...c, fulfillmentOptions: c.fulfillmentOptions.filter(o => o !== opt) } : c));
  }
  function saveChanges() {
    setChannels(draft);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }
  function openAddForm() {
    setForm(emptyChannelForm());
    setShowAddForm(true);
  }
  function submitAdd() {
    if (!form.name.trim()) return;
    const payload = {
      id: "ch" + Date.now(),
      name: form.name.trim(),
      color: form.color,
      adjustType: form.adjustType,
      value: form.adjustType === "none" ? 0 : Number(form.value) || 0,
      fulfillmentOptions: ["รับเอง", "ไรเดอร์"],
    };
    setChannels(prev => [...prev, payload]);
    setShowAddForm(false);
  }
  function removeChannel(id) {
    setChannels(prev => prev.filter(c => c.id !== id));
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ช่องทางการขาย" subtitle="กำหนดส่วนต่างราคาและตัวเลือกการรับอาหารของแต่ละช่องทางการขาย"
        right={<Btn onClick={openAddForm}><Plus size={14} /> เพิ่มช่องทาง</Btn>} />

      {isDirty && (
        <div className="flex items-center gap-3 mb-4 p-3 rounded-lg bg-amber-50 border border-amber-200">
          <span className="text-sm text-amber-800 flex-1">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</span>
          <Btn variant="ghost" onClick={() => setDraft(channels)}>ยกเลิกการแก้ไข</Btn>
          <Btn onClick={saveChanges}>บันทึกการเปลี่ยนแปลง</Btn>
        </div>
      )}
      {saved && !isDirty && (
        <div className="mb-4 p-3 rounded-lg bg-emerald-50 border border-emerald-200 text-emerald-700 text-sm">บันทึกเรียบร้อย ✓</div>
      )}

      {sample && (
        <div className="text-xs text-stone-400 mb-4">ตัวอย่างอ้างอิงจากเมนู "{sample.name}" ราคาปกติ ฿{fmtMoney(sample.price)}</div>
      )}
      <div className="space-y-3">
        {draft.map(c => {
          const isDineIn = c.name === "หน้าร้าน";
          return (
            <Card key={c.id} className="p-4">
              <div className="flex items-center justify-between gap-4">
                <div className="flex items-center gap-3 w-40 flex-shrink-0">
                  <span className={`px-2.5 py-1 rounded border text-sm font-medium ${CHANNEL_COLOR[c.color]}`}>{c.name}</span>
                </div>
                <div className="flex items-center gap-2 flex-1">
                  {["none", "percent", "fixed"].map(t => (
                    <button key={t} onClick={() => updateType(c.id, t)}
                      className={`px-2.5 py-1.5 rounded-md text-xs border ${c.adjustType === t ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>
                      {t === "none" ? "ราคาปกติ" : t === "percent" ? "บวกเปอร์เซ็นต์" : "บวกจำนวนเงิน"}
                    </button>
                  ))}
                  {c.adjustType !== "none" && (
                    <input type="number" value={c.value} onChange={e => updateValue(c.id, e.target.value)}
                      className="w-20 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-center" />
                  )}
                  {c.adjustType !== "none" && <span className="text-xs text-stone-400">{c.adjustType === "percent" ? "%" : "บาท"}</span>}
                </div>
                <div className="text-sm font-mono text-stone-700 w-20 text-right flex-shrink-0">฿{fmtMoney(priceFor(c))}</div>
                <button onClick={() => setDeletingChannel(c)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><Trash2 size={15} /></button>
              </div>

              {!isDineIn && (
                <div className="mt-3 pt-3 border-t border-stone-100">
                  <div className="text-xs text-stone-400 mb-2">ตัวเลือกการรับอาหาร (แสดงให้พนักงานเลือกตอนเปิดออเดอร์)</div>
                  <div className="flex flex-wrap items-center gap-2">
                    {(c.fulfillmentOptions || []).map(opt => (
                      <span key={opt} className="flex items-center gap-1 text-xs px-2.5 py-1 rounded-full bg-stone-100 text-stone-600 border border-stone-200">
                        {opt}
                        <button onClick={() => removeFulfillment(c.id, opt)} className="text-stone-400 hover:text-rose-500"><X size={11} /></button>
                      </span>
                    ))}
                    <input value={newOption[c.id] || ""} onChange={e => setNewOption(prev => ({ ...prev, [c.id]: e.target.value }))}
                      onKeyDown={e => { if (e.key === "Enter") addFulfillment(c.id); }}
                      placeholder="เพิ่มตัวเลือก เช่น ไรเดอร์" className="text-xs rounded-full border border-dashed border-stone-300 px-3 py-1 w-40 focus:outline-none focus:ring-1 focus:ring-amber-400" />
                    <button onClick={() => addFulfillment(c.id)} className="text-xs text-amber-700 hover:text-amber-900 font-medium flex items-center gap-0.5"><Plus size={12} /> เพิ่ม</button>
                  </div>
                </div>
              )}
            </Card>
          );
        })}
      </div>

      {isDirty && (
        <div className="flex items-center gap-3 mt-4">
          <Btn onClick={saveChanges}>บันทึกการเปลี่ยนแปลง</Btn>
          <Btn variant="ghost" onClick={() => setDraft(channels)}>ยกเลิกการแก้ไข</Btn>
        </div>
      )}

      {/* Add channel popup */}
      {showAddForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowAddForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มช่องทางการขาย</div>
              <button onClick={() => setShowAddForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อช่องทาง"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น Robinhood" autoFocus /></Field>
              <Field label="สี">
                <select className={inputCls} value={form.color} onChange={e => setForm({ ...form, color: e.target.value })}>
                  {Object.keys(CHANNEL_COLOR).map(k => <option key={k} value={k}>{k}</option>)}
                </select>
              </Field>
              <Field label="ส่วนต่างราคา">
                <select className={inputCls} value={form.adjustType} onChange={e => setForm({ ...form, adjustType: e.target.value })}>
                  <option value="none">ราคาปกติ</option>
                  <option value="percent">บวกเปอร์เซ็นต์</option>
                  <option value="fixed">บวกจำนวนเงิน</option>
                </select>
              </Field>
              {form.adjustType !== "none" && (
                <Field label={form.adjustType === "percent" ? "เปอร์เซ็นต์ (%)" : "จำนวนเงิน (บาท)"}>
                  <input type="number" className={inputCls} value={form.value} onChange={e => setForm({ ...form, value: e.target.value })} placeholder="0" />
                </Field>
              )}
            </div>
            <div className="flex gap-2 mt-4">
              <Btn onClick={submitAdd}><Plus size={14} /> เพิ่มช่องทาง</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingChannel && (
        <ConfirmDeletePin
          message={`ลบช่องทาง "${deletingChannel.name}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingChannel(null)}
          onConfirm={() => { removeChannel(deletingChannel.id); setDeletingChannel(null); }}
          logActivity={logActivity} activityLabel={`ลบช่องทางการขาย ${deletingChannel.name}`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: BRANCHES
   ========================================================================= */

function BranchesPage({ branches, setBranches, menu, currentBranchId, setCurrentBranchId, storeInfo, staff, ownerProfile, logActivity }) {
  // Same "reference item just for a price preview" pattern as
  // SalesChannelsPage — falls back once the SEED menu has been cleaned up,
  // so this page doesn't crash when menu.length < 2.
  const sample = menu[1] || menu[0] || null;
  const BRANCH_COLORS = ["#2563eb", "#059669", "#dc2626", "#d97706", "#7c3aed", "#db2777", "#0891b2", "#4b5563"];
  const [showAddForm, setShowAddForm] = useState(false);
  const [editingBranchId, setEditingBranchId] = useState(null);
  const [capturingGps, setCapturingGps] = useState(false);
  const [gpsError, setGpsError] = useState("");
  const [mapsLink, setMapsLink] = useState("");
  const [mapsError, setMapsError] = useState("");
  const [savePin, setSavePin] = useState("");
  const [savePinError, setSavePinError] = useState("");
  const [deletingBranch, setDeletingBranch] = useState(null);
  const [deletePin, setDeletePin] = useState("");
  const [deletePinError, setDeletePinError] = useState("");
  const qrInputRef = useRef(null);

  function defaultBranchForm() {
    return {
      name: "", openTime: storeInfo?.openTime || "10:00", closeTime: storeInfo?.closeTime || "22:00",
      companyName: storeInfo?.name || "", companyAddress: storeInfo?.address || "", officeType: "สาขา", taxId: storeInfo?.taxId || "",
      phone: storeInfo?.phone || "", contactChannels: (storeInfo?.contactChannels || []).map(c => ({ ...c, id: "cc" + Math.random().toString(36).slice(2, 8) })),
      lineQrDataUrl: storeInfo?.lineQrDataUrl || null,
      gpsLat: null, gpsLng: null,
      promptPayEnabled: false, promptPayId: "",
      address: storeInfo?.address || "", branchCode: "", color: BRANCH_COLORS[branches.length % BRANCH_COLORS.length], priceAdjust: 0,
    };
  }
  const [branchForm, setBranchForm] = useState(defaultBranchForm());
  function setBF(patch) { setBranchForm(prev => ({ ...prev, ...patch })); }

  function updateAdjust(id, priceAdjust) {
    setBranches(prev => prev.map(b => b.id === id ? { ...b, priceAdjust: Number(priceAdjust) } : b));
  }
  function updateBranchCode(id, branchCode) {
    setBranches(prev => prev.map(b => b.id === id ? { ...b, branchCode: branchCode.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6) } : b));
  }
  function updateColor(id, color) {
    setBranches(prev => prev.map(b => b.id === id ? { ...b, color } : b));
  }
  function toggleActive(id) {
    setBranches(prev => prev.map(b => b.id === id ? { ...b, active: !b.active } : b));
  }
  function openAddBranch() {
    setEditingBranchId(null);
    setBranchForm(defaultBranchForm());
    setGpsError("");
    setMapsLink("");
    setMapsError("");
    setSavePin("");
    setSavePinError("");
    setShowAddForm(true);
  }
  function openEditBranch(b) {
    setEditingBranchId(b.id);
    setBranchForm({ ...defaultBranchForm(), ...b, contactChannels: b.contactChannels || defaultBranchForm().contactChannels });
    setGpsError("");
    setMapsLink("");
    setMapsError("");
    setSavePin("");
    setSavePinError("");
    setShowAddForm(true);
  }
  function openDeleteBranch(b) {
    setDeletingBranch(b);
    setDeletePin("");
    setDeletePinError("");
  }
  function confirmDeleteBranch() {
    const isOwner = isOwnerPin(ownerProfile, deletePin);
    const isStaff = (staff || []).some(s => s.pin === deletePin && s.active);
    if (!isOwner && !isStaff) {
      setDeletePinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    setBranches(prev => prev.filter(b => b.id !== deletingBranch.id));
    if (logActivity) logActivity({ category: "ลบข้อมูล", action: `ลบสาขา ${deletingBranch.name}`, detail: `รหัสสาขา ${deletingBranch.id}` });
    setDeletingBranch(null);
  }
  function addContactChannel() {
    setBF({ contactChannels: [...branchForm.contactChannels, { id: "cc" + Date.now(), type: "Facebook", value: "" }] });
  }
  function updateContactChannel(id, patch) {
    setBF({ contactChannels: branchForm.contactChannels.map(c => c.id === id ? { ...c, ...patch } : c) });
  }
  function removeContactChannel(id) {
    setBF({ contactChannels: branchForm.contactChannels.filter(c => c.id !== id) });
  }
  function handleQrUpload(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => setBF({ lineQrDataUrl: reader.result });
    reader.readAsDataURL(file);
  }
  function captureBranchGps() {
    setCapturingGps(true);
    setGpsError("");
    if (!navigator.geolocation) {
      setGpsError("เบราว์เซอร์นี้ไม่รองรับ GPS");
      setCapturingGps(false);
      return;
    }
    navigator.geolocation.getCurrentPosition(
      pos => { setBF({ gpsLat: pos.coords.latitude, gpsLng: pos.coords.longitude }); setCapturingGps(false); },
      () => { setGpsError("ไม่สามารถอ่านตำแหน่งปัจจุบันได้ กรุณาอนุญาตการเข้าถึงตำแหน่งของเบราว์เซอร์"); setCapturingGps(false); },
      { enableHighAccuracy: true, timeout: 10000 }
    );
  }
  function extractLatLngFromGoogleMapsUrl(url) {
    // Covers the common link formats Google Maps produces:
    //  .../@13.7563,100.5018,15z         (viewing a location)
    //  ...?q=13.7563,100.5018            ("q=" shared pin)
    //  ...!3d13.7563!4d100.5018          (embedded place link)
    const patterns = [
      /@(-?\d+\.\d+),(-?\d+\.\d+)/,
      /[?&]q=(-?\d+\.\d+),(-?\d+\.\d+)/,
      /!3d(-?\d+\.\d+)!4d(-?\d+\.\d+)/,
    ];
    for (const re of patterns) {
      const m = url.match(re);
      if (m) return { lat: Number(m[1]), lng: Number(m[2]) };
    }
    return null;
  }
  function useBranchMapsLink() {
    setMapsError("");
    const coords = extractLatLngFromGoogleMapsUrl(mapsLink.trim());
    if (!coords) {
      setMapsError('ดึงพิกัดจากลิงก์นี้ไม่ได้ — ลองคัดลอกลิงก์แบบที่มีพิกัดในตัว เช่น เปิดตำแหน่งใน Google Maps บนคอมพิวเตอร์ แล้วคัดลอก URL จากแถบที่อยู่ (จะมี "@13.75,100.50" อยู่ในลิงก์)');
      return;
    }
    setBF({ gpsLat: coords.lat, gpsLng: coords.lng });
    setMapsLink("");
  }
  function saveBranchForm() {
    if (!branchForm.name.trim()) return;
    const isOwner = isOwnerPin(ownerProfile, savePin);
    const isStaff = (staff || []).some(s => s.pin === savePin && s.active);
    if (!isOwner && !isStaff) {
      setSavePinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    const payload = {
      name: branchForm.name.trim(), address: branchForm.address.trim(),
      openTime: branchForm.openTime, closeTime: branchForm.closeTime,
      companyName: branchForm.companyName.trim(), companyAddress: branchForm.companyAddress.trim(),
      officeType: branchForm.officeType.trim(), taxId: branchForm.taxId.trim(),
      phone: branchForm.phone.trim(), contactChannels: branchForm.contactChannels,
      lineQrDataUrl: branchForm.lineQrDataUrl,
      gpsLat: branchForm.gpsLat, gpsLng: branchForm.gpsLng,
      promptPayEnabled: branchForm.promptPayEnabled, promptPayId: branchForm.promptPayId.trim(),
      branchCode: branchForm.branchCode.toUpperCase().replace(/[^A-Z0-9]/g, "").slice(0, 6),
      color: branchForm.color, priceAdjust: Number(branchForm.priceAdjust) || 0,
    };
    if (editingBranchId) {
      setBranches(prev => prev.map(b => b.id === editingBranchId ? { ...b, ...payload } : b));
    } else {
      setBranches(prev => [...prev, { id: "br" + Date.now(), active: true, ...payload }]);
    }
    setShowAddForm(false);
  }

  const visibleBranches = currentBranchId ? branches.filter(b => b.id === currentBranchId) : branches;

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="สาขา"
        subtitle={currentBranchId ? "ข้อมูลของสาขาที่กำลังใช้งานอยู่" : "กำหนดส่วนต่างราคาและข้อมูลของแต่ละสาขา"}
        right={!currentBranchId ? <Btn onClick={openAddBranch}><Plus size={14} /> เพิ่มสาขา</Btn> : null} />

      {sample && (
        <div className="text-xs text-stone-400 mb-4">ส่วนต่างราคาคำนวณจากเมนู "{sample.name}" ราคาตั้งต้น ฿{fmtMoney(sample.price)}</div>
      )}
      <div className="space-y-3">
        {visibleBranches.map(b => (
          <Card key={b.id} className={`p-4 ${b.id === currentBranchId ? "border-amber-400" : ""}`}>
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <span className="w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0" style={{ backgroundColor: `${b.color || "#78716c"}1a` }}>
                  <Building2 size={17} style={{ color: b.color || "#78716c" }} />
                </span>
                <div>
                  <div className="font-medium text-stone-800 flex items-center gap-2">
                    {b.name}
                    {b.id === currentBranchId && <span className="text-[10px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">กำลังใช้งาน</span>}
                  </div>
                  <div className="text-xs text-stone-400 flex items-center gap-1 mt-0.5"><MapPin size={11} /> {b.address}</div>
                </div>
              </div>
              {!currentBranchId && (
                <button onClick={() => toggleActive(b.id)}
                  className={`relative w-11 h-6 rounded-full transition-colors ${b.active ? "bg-emerald-500" : "bg-stone-300"}`}>
                  <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${b.active ? "translate-x-5" : "translate-x-0"}`} />
                </button>
              )}
            </div>
            <div className="flex items-center gap-3 mt-3 pt-3 border-t border-stone-100 flex-wrap">
              <span className="text-xs text-stone-500">ส่วนต่างราคา (%)</span>
              <input type="number" value={b.priceAdjust} onChange={e => updateAdjust(b.id, e.target.value)}
                className="w-20 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-center" />
              {sample && (
                <span className="text-xs text-stone-400 font-mono">
                  ราคาเมนูตัวอย่าง ฿{fmtMoney(Math.round(sample.price * (1 + b.priceAdjust / 100)))}
                </span>
              )}
              <span className="text-xs text-stone-500 ml-3">รหัสสาขา (ต่อท้ายเลขที่ใบเสร็จ)</span>
              <input value={b.branchCode || ""} onChange={e => updateBranchCode(b.id, e.target.value)} placeholder="เช่น SKV"
                className="w-24 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-center font-mono uppercase" />
            </div>
            <div className="flex items-center gap-2 mt-3 pt-3 border-t border-stone-100 flex-wrap">
              <span className="text-xs text-stone-500 mr-1">สีประจำสาขา</span>
              {BRANCH_COLORS.map(c => (
                <button key={c} onClick={() => updateColor(b.id, c)}
                  className={`w-6 h-6 rounded-full border-2 ${b.color === c ? "border-stone-800" : "border-transparent"}`}
                  style={{ backgroundColor: c }} title={c} />
              ))}
              <input type="color" value={b.color || "#78716c"} onChange={e => updateColor(b.id, e.target.value)}
                className="w-7 h-7 rounded-full border border-stone-300 cursor-pointer p-0" title="เลือกสีเอง" />
              <input value={b.color || ""} onChange={e => updateColor(b.id, e.target.value)} placeholder="#รหัสสี"
                className="w-24 rounded-md border border-stone-300 px-2 py-1 text-xs font-mono uppercase" />
              <button onClick={() => openEditBranch(b)} className="text-xs text-sky-700 hover:text-sky-900 ml-auto flex items-center gap-1">
                <Pencil size={12} /> แก้ไขข้อมูลเพิ่มเติม (นิติบุคคล/ติดต่อ/GPS)
              </button>
              {!currentBranchId && (
                <button onClick={() => openDeleteBranch(b)} className="text-xs text-rose-500 hover:text-rose-700 flex items-center gap-1">
                  <Trash2 size={12} /> ลบสาขา
                </button>
              )}
            </div>
          </Card>
        ))}
      </div>

      {/* Add / edit branch popup */}
      {showAddForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowAddForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{editingBranchId ? "แก้ไขข้อมูลสาขา" : "เพิ่มสาขา"}</div>
              <button onClick={() => setShowAddForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="space-y-5">
              {/* Section 1 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-3"><StepBadge n={1} /><span className="text-sm font-semibold text-stone-700">ชื่อสาขาและเวลาทำการ</span></div>
                <div className="space-y-3 ml-8">
                  <Field label="ชื่อสาขา"><input className={inputCls} value={branchForm.name} onChange={e => setBF({ name: e.target.value })} placeholder="เช่น สาขาเอกมัย" autoFocus /></Field>
                  <div className="grid grid-cols-2 gap-3">
                    <Field label="เวลาเปิด"><input type="time" className={inputCls} value={branchForm.openTime} onChange={e => setBF({ openTime: e.target.value })} /></Field>
                    <Field label="เวลาปิด"><input type="time" className={inputCls} value={branchForm.closeTime} onChange={e => setBF({ closeTime: e.target.value })} /></Field>
                  </div>
                  <Field label="รหัสสาขา (ต่อท้ายเลขที่ใบเสร็จ)"><input className={`${inputCls} font-mono uppercase`} value={branchForm.branchCode} onChange={e => setBF({ branchCode: e.target.value })} placeholder="เช่น EKM" /></Field>
                  <div>
                    <div className="text-xs text-stone-500 mb-1.5">สีประจำสาขา</div>
                    <div className="flex items-center gap-2 flex-wrap">
                      {BRANCH_COLORS.map(c => (
                        <button key={c} onClick={() => setBF({ color: c })}
                          className={`w-7 h-7 rounded-full border-2 ${branchForm.color === c ? "border-stone-800" : "border-transparent"}`}
                          style={{ backgroundColor: c }} />
                      ))}
                      <input type="color" value={branchForm.color} onChange={e => setBF({ color: e.target.value })}
                        className="w-8 h-8 rounded-full border border-stone-300 cursor-pointer p-0" title="เลือกสีเอง" />
                      <input value={branchForm.color} onChange={e => setBF({ color: e.target.value })} placeholder="#รหัสสี"
                        className="w-24 rounded-md border border-stone-300 px-2 py-1.5 text-xs font-mono uppercase" />
                    </div>
                  </div>
                </div>
              </div>

              {/* Section 2 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-1"><StepBadge n={2} /><span className="text-sm font-semibold text-stone-700">ข้อมูลนิติบุคคล (สำหรับใบเสร็จ)</span></div>
                <p className="text-xs text-stone-400 ml-8 mb-3">ดึงมาจาก "ข้อมูลร้านค้า" ให้เบื้องต้น แก้ไขได้ถ้าสาขานี้จดทะเบียนเป็นคนละนิติบุคคล</p>
                <div className="space-y-3 ml-8">
                  <Field label="ชื่อบริษัท"><input className={inputCls} value={branchForm.companyName} onChange={e => setBF({ companyName: e.target.value })} /></Field>
                  <Field label="ที่อยู่"><textarea rows={2} className={inputCls} value={branchForm.companyAddress} onChange={e => setBF({ companyAddress: e.target.value })} /></Field>
                  <div className="grid grid-cols-2 gap-3">
                    <Field label="ประเภทสาขา"><input className={inputCls} value={branchForm.officeType} onChange={e => setBF({ officeType: e.target.value })} placeholder="สำนักงานใหญ่ หรือ สาขาที่ 001" /></Field>
                    <Field label="เลขประจำตัวผู้เสียภาษี"><input className={inputCls} value={branchForm.taxId} onChange={e => setBF({ taxId: e.target.value })} /></Field>
                  </div>
                </div>
              </div>

              {/* Section 3 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-3"><StepBadge n={3} /><span className="text-sm font-semibold text-stone-700">เบอร์โทรและช่องทางติดต่อ</span></div>
                <div className="space-y-3 ml-8">
                  <Field label="เบอร์โทร"><input className={inputCls} value={branchForm.phone} onChange={e => setBF({ phone: e.target.value })} /></Field>
                  <div className="space-y-2">
                    {branchForm.contactChannels.map(c => (
                      <div key={c.id} className="flex gap-2">
                        <select className={`${inputCls} max-w-[130px]`} value={c.type} onChange={e => updateContactChannel(c.id, { type: e.target.value })}>
                          <option value="Facebook">Facebook</option>
                          <option value="Instagram">Instagram</option>
                          <option value="Website">Website</option>
                          <option value="LINE">LINE</option>
                          <option value="TikTok">TikTok</option>
                          <option value="อื่นๆ">อื่นๆ</option>
                        </select>
                        <input className={`${inputCls} flex-1`} value={c.value} onChange={e => updateContactChannel(c.id, { value: e.target.value })} placeholder="ชื่อบัญชี/ลิงก์" />
                        <button onClick={() => removeContactChannel(c.id)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                      </div>
                    ))}
                  </div>
                  <button onClick={addContactChannel} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1"><Plus size={12} /> เพิ่มช่องทางติดต่อ</button>
                </div>
              </div>

              {/* Section 4 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-3"><StepBadge n={4} /><span className="text-sm font-semibold text-stone-700">QR Code LINE</span></div>
                <div className="ml-8 flex items-center gap-3">
                  <div className="w-16 h-16 rounded-lg border border-stone-200 bg-white flex items-center justify-center overflow-hidden flex-shrink-0">
                    {branchForm.lineQrDataUrl ? <img src={branchForm.lineQrDataUrl} alt="LINE QR" className="w-full h-full object-cover" /> : <QrCode size={24} className="text-stone-200" />}
                  </div>
                  <input ref={qrInputRef} type="file" accept="image/*" className="hidden" onChange={handleQrUpload} />
                  <Btn variant="ghost" onClick={() => qrInputRef.current?.click()}>อัปโหลดรูป QR LINE</Btn>
                  {branchForm.lineQrDataUrl && (
                    <button onClick={() => setBF({ lineQrDataUrl: null })} className="text-xs text-rose-500 hover:text-rose-700">ลบรูป</button>
                  )}
                </div>
              </div>

              {/* Section 5 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-3"><StepBadge n={5} /><span className="text-sm font-semibold text-stone-700">ตำแหน่ง GPS ของสาขา</span></div>
                <div className="ml-8 space-y-2">
                  <div className="text-xs text-stone-500">
                    {branchForm.gpsLat != null ? `พิกัด: ${branchForm.gpsLat.toFixed(5)}, ${branchForm.gpsLng.toFixed(5)}` : "ยังไม่ได้บันทึกตำแหน่ง"}
                  </div>
                  <Btn variant="ghost" className="w-full justify-center" disabled={capturingGps} onClick={captureBranchGps}>
                    {capturingGps ? "กำลังอ่านตำแหน่ง..." : "บันทึกตำแหน่งจากที่นี่ (ตำแหน่งปัจจุบัน)"}
                  </Btn>
                  {gpsError && <div className="text-xs text-rose-500">{gpsError}</div>}

                  <div className="flex items-center gap-2 text-xs text-stone-400">
                    <div className="flex-1 h-px bg-stone-200" /> หรือ <div className="flex-1 h-px bg-stone-200" />
                  </div>

                  <Field label="วางลิงก์ Google Maps ของสาขา">
                    <div className="flex gap-2">
                      <input className={`${inputCls} flex-1 min-w-0`} value={mapsLink} onChange={e => setMapsLink(e.target.value)} placeholder="https://www.google.com/maps/@13.7563,100.5018,17z" />
                      <Btn variant="ghost" onClick={useBranchMapsLink} className="flex-shrink-0">ดึงพิกัด</Btn>
                    </div>
                  </Field>
                  {mapsError && <div className="text-xs text-rose-500">{mapsError}</div>}
                  <p className="text-[11px] text-stone-400">
                    เปิด Google Maps ค้นหาที่ตั้งสาขา คลิกขวาที่หมุด หรือคัดลอก URL จากแถบที่อยู่ (ต้องมีตัวเลขพิกัดฝังอยู่ในลิงก์ เช่น "@13.75,100.50" หรือ "?q=13.75,100.50") แล้ววางที่นี่
                  </p>
                </div>
              </div>

              {/* Section 6 */}
              <div className="p-3 rounded-lg border border-stone-200">
                <div className="flex items-center gap-2 mb-1"><StepBadge n={6} /><span className="text-sm font-semibold text-stone-700">QR PromptPay ของสาขา</span></div>
                <p className="text-xs text-stone-400 ml-8 mb-3">ถ้าสาขานี้มีบัญชีพร้อมเพย์ของตัวเอง แยกจากบัญชีกลาง ตั้งค่าที่นี่ — ถ้าปิดไว้จะใช้ QR PromptPay กลางจากหน้า "การตั้งค่าการชำระเงิน" แทน</p>
                <div className="ml-8 space-y-3">
                  <label className="flex items-center justify-between cursor-pointer max-w-md">
                    <span className="text-sm text-stone-700">ใช้ QR PromptPay แยกเฉพาะสาขานี้</span>
                    <button onClick={() => setBF({ promptPayEnabled: !branchForm.promptPayEnabled })}
                      className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${branchForm.promptPayEnabled ? "bg-emerald-500" : "bg-stone-300"}`}>
                      <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${branchForm.promptPayEnabled ? "translate-x-5" : "translate-x-0"}`} />
                    </button>
                  </label>
                  {branchForm.promptPayEnabled && (
                    <>
                      <Field label="เบอร์พร้อมเพย์ (10 หลัก) หรือ เลขผู้เสียภาษี/บัตรประชาชน (13 หลัก)">
                        <input className={inputCls} value={branchForm.promptPayId} onChange={e => setBF({ promptPayId: e.target.value.replace(/[^0-9]/g, "").slice(0, 13) })} placeholder="เช่น 0812345678" />
                      </Field>
                      {branchForm.promptPayId && buildPromptPayPayload(branchForm.promptPayId, 100) ? (
                        <div className="flex items-center gap-3">
                          <img src={promptPayQrImageUrl(branchForm.promptPayId, 100, 100)} alt="ตัวอย่าง QR" className="rounded-lg border border-stone-200" />
                          <span className="text-xs text-stone-400">ตัวอย่าง QR (ยอด ฿100 สำหรับทดสอบ)</span>
                        </div>
                      ) : branchForm.promptPayId ? (
                        <p className="text-xs text-rose-500">ต้องมี 10 หลัก (เบอร์มือถือ) หรือ 13 หลัก (เลขผู้เสียภาษี/บัตรประชาชน)</p>
                      ) : null}
                    </>
                  )}
                </div>
              </div>
            </div>

            <div className="mt-4 pt-4 border-t border-stone-200">
              <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก) — ต้องกรอกก่อนบันทึก">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls}
                  value={savePin} onChange={e => { setSavePin(e.target.value.replace(/\D/g, "").slice(0, 6)); setSavePinError(""); }}
                  placeholder="••••••" />
              </Field>
              {savePinError && <div className="text-xs text-rose-500 mt-1">{savePinError}</div>}
            </div>

            <Btn className="w-full justify-center mt-4" disabled={!branchForm.name.trim() || savePin.length !== 6} onClick={saveBranchForm}>{editingBranchId ? "บันทึกการแก้ไข" : "เพิ่มสาขา"}</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete branch popup */}
      {deletingBranch && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setDeletingBranch(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">ลบสาขา "{deletingBranch.name}"?</div>
            <p className="text-sm text-stone-500 mb-4">การลบสาขาจะไม่ลบข้อมูลยอดขาย/ค่าใช้จ่ายที่เคยผูกกับสาขานี้ไว้ก่อนหน้า แต่จะไม่สามารถเลือกสาขานี้ได้อีกในระบบ</p>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} className={inputCls}
                value={deletePin} onChange={e => { setDeletePin(e.target.value.replace(/\D/g, "").slice(0, 6)); setDeletePinError(""); }}
                placeholder="••••••" />
            </Field>
            {deletePinError && <div className="text-xs text-rose-500 mt-1">{deletePinError}</div>}
            <div className="flex justify-end gap-2 mt-4">
              <Btn variant="ghost" onClick={() => setDeletingBranch(null)}>ยกเลิก</Btn>
              <Btn disabled={deletePin.length !== 6} onClick={confirmDeleteBranch}>ยืนยันลบสาขา</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: PAYMENT SETTINGS
   ========================================================================= */

/* Reusable delete-confirmation popup that requires a valid staff/owner PIN
   before calling onConfirm — used everywhere a destructive delete happens. */
/* Checks a PIN against the primary owner profile AND any additional owners
   (ownerProfile.owners[]) — used everywhere an "is this the owner's PIN?"
   check happens, now that there can be more than one owner. */
function isOwnerPin(ownerProfile, pin) {
  if (!pin) return false;
  if (ownerProfile?.pin && pin === ownerProfile.pin) return true;
  return (ownerProfile?.owners || []).some(o => o.pin === pin);
}
function matchingOwner(ownerProfile, pin) {
  if (ownerProfile?.pin && pin === ownerProfile.pin) return ownerProfile;
  return (ownerProfile?.owners || []).find(o => o.pin === pin) || null;
}

function ConfirmDeletePin({ message, staff, ownerProfile, onConfirm, onCancel, confirmLabel = "ยืนยันลบ", logActivity, activityLabel, activityCategory = "ลบข้อมูล" }) {
  const [pin, setPin] = useState("");
  const [error, setError] = useState("");
  function handleConfirm() {
    const isOwner = isOwnerPin(ownerProfile, pin);
    const isStaff = (staff || []).some(s => s.pin === pin && s.active);
    if (!isOwner && !isStaff) {
      setError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    if (logActivity) logActivity({ category: activityCategory, action: activityLabel || "ลบข้อมูล", detail: typeof message === "string" ? message : "" });
    onConfirm();
  }
  return (
    <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={onCancel}>
      <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
        <div className="text-sm text-stone-700 mb-3">{message}</div>
        <Field label="PIN ผู้จัดการ/เจ้าของร้าน (6 หลัก)">
          <input type="password" inputMode="numeric" maxLength={6} className={inputCls} autoFocus
            value={pin} onChange={e => { setPin(e.target.value.replace(/\D/g, "").slice(0, 6)); setError(""); }}
            onKeyDown={e => e.key === "Enter" && pin.length === 6 && handleConfirm()} placeholder="••••••" />
        </Field>
        {error && <div className="text-xs text-rose-500 mt-1">{error}</div>}
        <div className="flex justify-end gap-2 mt-4">
          <Btn variant="ghost" onClick={onCancel}>ยกเลิก</Btn>
          <Btn disabled={pin.length !== 6} onClick={handleConfirm}>{confirmLabel}</Btn>
        </div>
      </div>
    </div>
  );
}

function StepBadge({ n }) {
  return <span className="w-6 h-6 rounded-full bg-stone-900 text-white text-xs font-semibold flex items-center justify-center flex-shrink-0">{n}</span>;
}

function SettingsSwitch({ checked, onChange, label }) {
  return (
    <button onClick={() => onChange(!checked)} className="flex items-center gap-2.5">
      <span className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${checked ? "bg-stone-900" : "bg-stone-300"}`}>
        <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${checked ? "translate-x-5" : "translate-x-0"}`} />
      </span>
      <span className="text-sm font-medium text-stone-700">{label}</span>
    </button>
  );
}

function SegmentedChoice({ options, value, onChange }) {
  return (
    <div className="flex flex-wrap gap-2">
      {options.map(opt => (
        <button key={opt.value} onClick={() => onChange(opt.value)}
          className={`px-4 py-2.5 rounded-lg text-sm font-medium border transition-colors
          ${value === opt.value ? "bg-stone-900 text-white border-stone-900" : "bg-white text-stone-400 border-stone-200 hover:border-stone-300"}`}>
          {opt.label}
        </button>
      ))}
    </div>
  );
}

function PaymentSettingsPage({ settings, setSettings, financeAccounts, currentBranchId, branches }) {
  const [draft, setDraft] = useState(settings);
  const [saved, setSaved] = useState(false);
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings);
  useEffect(() => { setDraft(settings); }, [settings]);
  const set = (section, patch) => setDraft(prev => ({ ...prev, [section]: { ...prev[section], ...patch } }));
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;

  const payableAccounts = payableFinanceAccounts(financeAccounts)
    .filter(acc => !effectiveBranchId || !acc.ourBranchId || acc.ourBranchId === effectiveBranchId);
  const enabledIds = draft.enabledFinanceAccountIds || [];
  function toggleAccountEnabled(id) {
    setDraft(prev => {
      const cur = prev.enabledFinanceAccountIds || [];
      const next = cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id];
      return { ...prev, enabledFinanceAccountIds: next };
    });
  }
  function saveChanges() {
    setSettings(draft);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="การตั้งค่าการชำระเงิน" subtitle="กำหนดค่าบริการ ภาษี การปัดเศษ และวิธีการชำระเงิน" />

      {isDirty && (
        <div className="flex items-center gap-3 mb-4 p-3 rounded-lg bg-amber-50 border border-amber-200 max-w-2xl">
          <span className="text-sm text-amber-800 flex-1">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</span>
          <Btn variant="ghost" onClick={() => setDraft(settings)}>ยกเลิกการแก้ไข</Btn>
          <Btn onClick={saveChanges}>บันทึกการเปลี่ยนแปลง</Btn>
        </div>
      )}

      <div className="space-y-5 max-w-2xl">
        {/* 1. Service Charge */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-1">
            <StepBadge n={1} />
            <span className="font-semibold text-stone-800">ค่าบริการ (Service Charge)</span>
          </div>
          <p className="text-sm text-stone-400 mb-4 ml-8">ระบบจะไม่คิด Service Charge รวมไปในบิลเดลิเวอรี</p>
          <div className="ml-8 space-y-4">
            <SettingsSwitch checked={draft.serviceCharge.enabled} onChange={v => set("serviceCharge", { enabled: v })} label="เปิดใช้งานค่าบริการ" />
            {draft.serviceCharge.enabled && (
              <Field label="อัตราค่าบริการ (%)">
                <input type="number" className={`${inputCls} max-w-xs`} value={draft.serviceCharge.rate}
                  onChange={e => set("serviceCharge", { rate: Number(e.target.value) })} />
              </Field>
            )}
          </div>
        </Card>

        {/* 2. VAT */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-4">
            <StepBadge n={2} />
            <span className="font-semibold text-stone-800">ภาษี (VAT)</span>
          </div>
          <div className="ml-8 space-y-4">
            <SettingsSwitch checked={draft.vat.enabled} onChange={v => set("vat", { enabled: v })} label="เปิดใช้งานภาษีมูลค่าเพิ่ม" />
            {draft.vat.enabled && (
              <>
                <Field label="อัตราภาษี (%)">
                  <input type="number" className={`${inputCls} max-w-xs`} value={draft.vat.rate}
                    onChange={e => set("vat", { rate: Number(e.target.value) })} />
                </Field>
                <Field label="รูปแบบการคิดภาษี">
                  <SegmentedChoice value={draft.vat.mode} onChange={v => set("vat", { mode: v })}
                    options={[
                      { value: "included", label: "รวมในราคาอาหารแล้ว" },
                      { value: "added", label: "บวกเพิ่มจากราคา" },
                    ]} />
                </Field>
              </>
            )}
          </div>
        </Card>

        {/* 3. Rounding */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-1">
            <StepBadge n={3} />
            <span className="font-semibold text-stone-800">การปัดเศษ</span>
          </div>
          <p className="text-sm text-stone-400 mb-4 ml-8">ช่วยให้การทอนเงินคำนวณง่ายขึ้น โดยเฉพาะเมื่อมีการใช้โปรโมชั่นหรือส่วนลด</p>
          <div className="ml-8">
            <SegmentedChoice value={draft.rounding} onChange={v => setDraft(prev => ({ ...prev, rounding: v }))}
              options={[
                { value: "none", label: "ไม่ปัดเศษ" },
                { value: "toBaht", label: "ปัดถึงหลักบาท" },
                { value: "to5Baht", label: "ปัดถึงหลัก 5 บาท" },
              ]} />
          </div>
        </Card>

        {/* 4. Payment methods */}
        <Card className="p-5">
          <div className="flex items-center justify-between mb-1">
            <div className="flex items-center gap-2.5">
              <StepBadge n={4} />
              <span className="font-semibold text-stone-800">วิธีการชำระเงิน</span>
            </div>
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
          </div>
          <p className="text-sm text-stone-400 mb-4 ml-8">
            เลือกเปิดใช้ช่องทางรับชำระจากบัญชีที่มีอยู่ในหน้า "ช่องทางการเงิน" — จัดการเพิ่ม/แก้ไข/ลบบัญชีได้ที่หน้านั้น
          </p>

          <div className="ml-8 space-y-2">
            {payableAccounts.map(acc => {
              const Icon = ACCOUNT_TYPE_ICON[acc.type] || Banknote;
              const enabled = enabledIds.includes(acc.id);
              return (
                <div key={acc.id} className="flex items-center justify-between p-3 rounded-lg border border-stone-200">
                  <div className="flex items-center gap-3 min-w-0">
                    <span className="w-9 h-9 rounded-lg bg-stone-100 flex items-center justify-center text-stone-500 flex-shrink-0"><Icon size={16} /></span>
                    <div className="min-w-0">
                      <div className="text-sm font-medium text-stone-800 truncate">{financeAccountDisplayName(acc)}</div>
                      <div className="text-xs text-stone-400">
                        {FINANCE_ACCOUNT_TYPE_LABEL[acc.type]}
                        {!effectiveBranchId && (
                          <span className="ml-1.5 text-stone-400">· {branches?.find(b => b.id === acc.ourBranchId)?.name || "ทุกสาขา"}</span>
                        )}
                      </div>
                    </div>
                  </div>
                  <button onClick={() => toggleAccountEnabled(acc.id)}
                    className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${enabled ? "bg-emerald-500" : "bg-stone-300"}`}>
                    <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${enabled ? "translate-x-5" : "translate-x-0"}`} />
                  </button>
                </div>
              );
            })}
            {payableAccounts.length === 0 && (
              <div className="text-sm text-stone-400 text-center py-6 border border-dashed border-stone-300 rounded-lg">
                ยังไม่มีบัญชีในหน้า "ช่องทางการเงิน" — เพิ่มบัญชีที่นั่นก่อน แล้วจะมาปรากฏให้เปิดใช้งานที่นี่
              </div>
            )}
          </div>
        </Card>

        <div className="flex items-center gap-3">
          <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
          {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings)}>ยกเลิกการแก้ไข</Btn>}
          {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: PRINTER SETTINGS
   ========================================================================= */

function PrintAgentPortSettingsPage({ printAgentSettings, setPrintAgentSettings, currentBranchId, branches }) {
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const settingsKey = effectiveBranchId || "default";
  const currentSaved = printAgentSettings[settingsKey] || printAgentSettings.default || { host: "localhost", port: "9200" };

  const [draft, setDraft] = useState(currentSaved);
  const [saved, setSaved] = useState(false);
  const isDirty = JSON.stringify(draft) !== JSON.stringify(currentSaved);
  useEffect(() => { setDraft(currentSaved); }, [settingsKey, printAgentSettings]);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState(null); // { ok, message }

  function branchName(id) { return branches?.find(b => b.id === id)?.name; }

  function saveChanges() {
    setPrintAgentSettings(prev => ({ ...prev, [settingsKey]: draft }));
    setSaved(true);
    setTestResult(null);
    setTimeout(() => setSaved(false), 2000);
  }
  async function testConnection() {
    setTesting(true);
    setTestResult(null);
    try {
      const res = await fetch(`http://${draft.host || "localhost"}:${draft.port || "9200"}/health`);
      const data = await res.json().catch(() => null);
      if (res.ok && data) {
        setTestResult({ ok: true, message: `เชื่อมต่อสำเร็จ — พบเครื่องพิมพ์: ${(data.printers || []).join(", ") || "-"}` });
      } else {
        setTestResult({ ok: false, message: `เชื่อมต่อได้ แต่ได้รับข้อมูลไม่ถูกต้อง (HTTP ${res.status})` });
      }
    } catch (err) {
      setTestResult({ ok: false, message: "เชื่อมต่อไม่ได้ — ตรวจสอบว่า print agent กำลังรันอยู่ และ host/port ถูกต้อง" });
    } finally {
      setTesting(false);
    }
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ตั้งค่า Port" subtitle="กำหนด host/port ที่ใช้เชื่อมต่อ print agent สำหรับพิมพ์ตรงไปเครื่องพิมพ์"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ค่ากลาง (ทุกสาขาที่ไม่ได้ตั้งแยก)</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <Card className="p-5 max-w-md">
        <p className="text-xs text-stone-400 mb-1">
          แต่ละสาขาอาจมีเครื่องที่รัน print agent อยู่คนละเครื่อง/คนละเครือข่ายกัน — ตั้งค่าแยกได้ต่อสาขา
        </p>
        <div className="text-xs font-medium text-sky-600 mb-4">
          กำลังแก้ไขค่าของ: {effectiveBranchId ? branchName(effectiveBranchId) : "ค่ากลาง (สาขาที่ไม่ได้ตั้งแยกไว้จะใช้ค่านี้)"}
        </div>
        <p className="text-xs text-stone-400 mb-4">
          ค่านี้ต้องตรงกับที่ตั้งไว้ใน <code className="font-mono bg-stone-100 px-1 rounded">config.json</code> ของ print agent ที่รันอยู่ที่เครื่อง/อุปกรณ์ของสาขานั้น — ถ้าเปลี่ยนพอร์ตฝั่ง agent ต้องมาแก้ให้ตรงกันที่นี่ด้วย
        </p>
        <div className="space-y-4">
          <Field label="Host / IP ของเครื่องที่รัน print agent">
            <input className={inputCls} value={draft.host} onChange={e => setDraft(d => ({ ...d, host: e.target.value }))} placeholder="localhost หรือ 192.168.1.50" />
          </Field>
          <Field label="Port">
            <input className={inputCls} value={draft.port} onChange={e => setDraft(d => ({ ...d, port: e.target.value.replace(/\D/g, "").slice(0, 5) }))} placeholder="9200" />
          </Field>
        </div>
        <p className="text-[11px] text-stone-400 mt-2">
          ใช้ <code className="font-mono bg-stone-100 px-1 rounded">localhost</code> ถ้า print agent รันอยู่บนเครื่องเดียวกับที่เปิดเบราว์เซอร์ (คอมพิวเตอร์/Windows/Mac) — แต่ถ้าใช้ iPad ต้องใส่ IP ของอุปกรณ์แยก (เช่น Raspberry Pi) ที่รัน agent อยู่ในเครือข่ายเดียวกัน
        </p>

        {isDirty && <div className="text-xs text-amber-700 mt-3">มีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก</div>}
        <div className="flex items-center gap-3 mt-4">
          <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
          {isDirty && <Btn variant="ghost" onClick={() => setDraft(currentSaved)}>ยกเลิกการแก้ไข</Btn>}
          {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
        </div>

        <div className="mt-5 pt-4 border-t border-stone-100">
          <Btn variant="ghost" onClick={testConnection} disabled={testing}>
            {testing ? <RefreshCw size={14} className="animate-spin" /> : <Wifi size={14} />}
            {testing ? "กำลังทดสอบ..." : "ทดสอบการเชื่อมต่อ"}
          </Btn>
          {testResult && (
            <p className={`text-xs mt-2 ${testResult.ok ? "text-emerald-600" : "text-rose-500"}`}>{testResult.message}</p>
          )}
        </div>
      </Card>
    </div>
  );
}

function PrinterSettingsPage({ printers, setPrinters, categories, currentBranchId, branches }) {
  const [openSettingsId, setOpenSettingsId] = useState(printers.find(p => p.connected)?.id || null);
  const [saved, setSaved] = useState(false);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const [showIpForm, setShowIpForm] = useState(false);
  const emptyIpForm = { brand: "", model: "", ip: "", name: "" };
  const [ipForm, setIpForm] = useState(emptyIpForm);
  const [ipFormError, setIpFormError] = useState("");
  const PRINTER_BRANDS = ["Xprinter", "EPSON", "Star Micronics", "Gprinter", "SUNMI", "อื่นๆ"];
  const BRAND_MODELS = {
    Xprinter: ["XP-C300H", "XP-58C", "XP-Q200II", "XP-N160II"],
    EPSON: ["TM-T82", "TM-T88VII", "TM-m30"],
    "Star Micronics": ["SP700", "TSP143III", "mC-Print3"],
    Gprinter: ["GP-2120TU", "GP-U80300I"],
    SUNMI: ["NT311", "V2 Pro (built-in)"],
    อื่นๆ: [],
  };
  // Each printer is physically plugged in at one branch, so what shows here is
  // scoped to the branch you're logged into — a device connected at another
  // branch's computer is irrelevant here. Not-yet-connected/undiscovered
  // devices (branchId null) still show everywhere since they aren't tied down yet.
  const visiblePrinters = printers.filter(p => !effectiveBranchId || !p.branchId || p.branchId === effectiveBranchId);
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  const openPrinter = visiblePrinters.find(p => p.id === openSettingsId);

  function openIpForm() {
    setIpForm(emptyIpForm);
    setIpFormError("");
    setShowIpForm(true);
  }
  function submitIpForm() {
    const ipPattern = /^(\d{1,3}\.){3}\d{1,3}$/;
    if (!ipForm.ip.trim() || !ipPattern.test(ipForm.ip.trim())) {
      setIpFormError("กรุณากรอกที่อยู่ IP ให้ถูกต้อง เช่น 192.168.1.100");
      return;
    }
    if (!ipForm.name.trim()) {
      setIpFormError("กรุณาตั้งชื่อเครื่องพิมพ์");
      return;
    }
    const label = [ipForm.brand, ipForm.model].filter(Boolean).join(" ");
    setPrinters(prev => [...prev, {
      id: "pr" + Date.now(),
      name: ipForm.name.trim(),
      brand: ipForm.brand, model: ipForm.model, ip: ipForm.ip.trim(),
      connectionType: `IP (${ipForm.ip.trim()})`,
      connected: true, branchId: effectiveBranchId || null,
      receiptMode: "auto", kitchenEnabled: false, kitchenCategoryIds: [], drinkEnabled: false, drinkCategoryIds: [],
    }]);
    setShowIpForm(false);
  }
  function connect(id) {
    setPrinters(prev => prev.map(p => p.id === id ? { ...p, connected: true, branchId: p.branchId || effectiveBranchId || null } : p));
    setOpenSettingsId(id);
  }
  function disconnect(id) {
    setPrinters(prev => prev.map(p => p.id === id ? { ...p, connected: false, branchId: null } : p));
    if (openSettingsId === id) setOpenSettingsId(null);
  }
  function updatePrinter(id, patch) {
    setPrinters(prev => prev.map(p => p.id === id ? { ...p, ...patch } : p));
    setSaved(false);
  }
  function toggleKitchenCategory(catId) {
    if (!openPrinter) return;
    const cur = openPrinter.kitchenCategoryIds;
    const next = cur.includes(catId) ? cur.filter(id => id !== catId) : [...cur, catId];
    updatePrinter(openPrinter.id, { kitchenCategoryIds: next });
  }
  function toggleDrinkCategory(catId) {
    if (!openPrinter) return;
    const cur = openPrinter.drinkCategoryIds;
    const next = cur.includes(catId) ? cur.filter(id => id !== catId) : [...cur, catId];
    updatePrinter(openPrinter.id, { drinkCategoryIds: next });
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ตั้งค่าเครื่องพิมพ์" subtitle="ค้นหา เชื่อมต่อ และตั้งค่าเครื่องพิมพ์ใบเสร็จ/ใบออเดอร์"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <div className="max-w-2xl space-y-5">
        {/* 1. Discover & connect */}
        <Card className="p-5">
          <div className="flex items-center gap-2.5 mb-1">
            <StepBadge n={1} />
            <span className="font-semibold text-stone-800">ค้นหาจาก IP (เชื่อมได้หลายเครื่อง)</span>
          </div>
          <p className="text-sm text-stone-400 mb-4 ml-8">เพิ่มเครื่องพิมพ์ด้วยที่อยู่ IP แบบ Fix IP ของเครื่อง — เชื่อมต่อได้มากกว่า 1 เครื่องพร้อมกัน</p>
          <div className="ml-8">
            <Btn onClick={openIpForm}><Search size={14} /> ค้นหาผ่าน IP</Btn>

            <div className="mt-4 divide-y divide-stone-100">
              {visiblePrinters.map(p => (
                <div key={p.id} className="py-3 first:pt-0">
                  <div className="flex items-center justify-between gap-3">
                    <div className="flex items-center gap-2.5 min-w-0">
                      <Printer size={16} className="text-stone-400 flex-shrink-0" />
                      <span className="font-medium text-stone-800 text-sm truncate">{p.name}</span>
                      {p.ip && <span className="text-[10px] px-1.5 py-0.5 rounded bg-stone-100 text-stone-500 font-mono flex-shrink-0">{p.ip}</span>}
                      {!effectiveBranchId && p.branchId && (
                        <span className="text-[10px] px-1.5 py-0.5 rounded bg-sky-50 text-sky-700 border border-sky-200 flex-shrink-0">{branchNameFor(p.branchId)}</span>
                      )}
                    </div>
                    <div className="flex items-center gap-3 flex-shrink-0">
                      {p.connected ? (
                        <>
                          <span className="text-xs text-emerald-600 font-medium">เชื่อมต่อแล้ว</span>
                          <Btn variant="ghost" onClick={() => setOpenSettingsId(openSettingsId === p.id ? null : p.id)}>
                            {openSettingsId === p.id ? "ซ่อนการตั้งค่า" : "ตั้งค่า"}
                          </Btn>
                          <button onClick={() => disconnect(p.id)} className="text-xs text-stone-400 hover:text-rose-500">ยกเลิกเชื่อมต่อ</button>
                        </>
                      ) : (
                        <Btn variant="ghost" onClick={() => connect(p.id)}>เชื่อมต่อ</Btn>
                      )}
                    </div>
                  </div>
                  {p.connected && (
                    <div className="text-xs text-stone-400 mt-1 ml-[26px]">
                      ใบเสร็จ: {p.receiptMode === "auto" ? "อัตโนมัติ" : "พิมพ์ซ้ำ 2 ใบ"} · ครัว: {p.kitchenEnabled ? "เปิด" : "ปิด"} · เครื่องดื่ม: {p.drinkEnabled ? "เปิด" : "ปิด"}
                    </div>
                  )}
                </div>
              ))}
            </div>

            <p className="text-[11px] text-stone-400 mt-4 pt-3 border-t border-stone-100">
              หมายเหตุ: ระบบนี้เป็นหน้าเว็บ เก็บข้อมูล IP/ยี่ห้อ/รุ่นไว้เป็นข้อมูลอ้างอิงเท่านั้น — <strong>ไม่ได้เปิดการเชื่อมต่อไปยัง IP นั้นจริงจากเบราว์เซอร์</strong> (เว็บเบราว์เซอร์ทำแบบนั้นไม่ได้ด้วยเหตุผลด้านความปลอดภัย) การพิมพ์จริงยังคงเรียกผ่าน `window.print()` ไปยังเครื่องพิมพ์ที่ติดตั้ง driver ไว้ในเครื่องคอมพิวเตอร์/แท็บเล็ตนั้นแล้วเท่านั้น
            </p>
          </div>
        </Card>

        {openPrinter && (
          <>
            {/* 2. Name & receipt mode */}
            <Card className="p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <StepBadge n={2} />
                <span className="font-semibold text-stone-800">ตั้งชื่อเครื่องพิมพ์ และโหมดใบเสร็จ — {openPrinter.name}</span>
              </div>
              <div className="ml-8 space-y-4">
                <Field label="ชื่อเครื่องพิมพ์">
                  <input className={inputCls} value={openPrinter.name} onChange={e => updatePrinter(openPrinter.id, { name: e.target.value })} />
                </Field>
                <div>
                  <div className="text-xs font-medium text-stone-500 mb-2">โหมดในการพิมพ์</div>
                  <div className="space-y-2">
                    <label className="flex items-center gap-2 text-sm text-stone-700 cursor-pointer">
                      <input type="radio" checked={openPrinter.receiptMode === "auto"} onChange={() => updatePrinter(openPrinter.id, { receiptMode: "auto" })} />
                      พิมพ์ใบเสร็จอัตโนมัติ (ออกทุกครั้งที่ปิดบิล)
                    </label>
                    <label className="flex items-center gap-2 text-sm text-stone-700 cursor-pointer">
                      <input type="radio" checked={openPrinter.receiptMode === "duplicate2"} onChange={() => updatePrinter(openPrinter.id, { receiptMode: "duplicate2" })} />
                      พิมพ์ใบเสร็จซ้ำ 2 ใบ (เก็บสำเนา)
                    </label>
                  </div>
                </div>
              </div>
            </Card>

            {/* 3. Kitchen / drink order printing */}
            <Card className="p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <StepBadge n={3} />
                <span className="font-semibold text-stone-800">ตั้งค่าการพิมพ์ใบออเดอร์ภายในครัว/เครื่องดื่ม</span>
              </div>
              <div className="ml-8 space-y-4">
                <ToggleRow label="เปิดใช้งานใบออเดอร์ครัว" checked={openPrinter.kitchenEnabled} onChange={v => updatePrinter(openPrinter.id, { kitchenEnabled: v })} />

                {openPrinter.kitchenEnabled && (
                  <div>
                    <div className="text-xs font-medium text-stone-500 mb-2">เลือกหมวดหมู่ที่จะพิมพ์เข้าเครื่องพิมพ์นี้</div>
                    <div className="flex flex-wrap gap-2">
                      {categories.map(c => (
                        <button key={c.id} onClick={() => toggleKitchenCategory(c.id)}
                          className={`px-3 py-1.5 rounded-full text-xs border ${openPrinter.kitchenCategoryIds.includes(c.id) ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>
                          {c.name}
                        </button>
                      ))}
                    </div>
                  </div>
                )}

                <ToggleRow label="เปิดใช้งานใบออเดอร์เครื่องดื่ม" checked={openPrinter.drinkEnabled} onChange={v => updatePrinter(openPrinter.id, { drinkEnabled: v })} />

                {openPrinter.drinkEnabled && (
                  <div>
                    <div className="text-xs font-medium text-stone-500 mb-2">เลือกหมวดหมู่ที่จะพิมพ์ใบออเดอร์เครื่องดื่ม</div>
                    <div className="flex flex-wrap gap-2">
                      {categories.map(c => (
                        <button key={c.id} onClick={() => toggleDrinkCategory(c.id)}
                          className={`px-3 py-1.5 rounded-full text-xs border ${openPrinter.drinkCategoryIds.includes(c.id) ? "bg-sky-600 text-white border-sky-600" : "border-stone-300 text-stone-500"}`}>
                          {c.name}
                        </button>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            </Card>

            {/* 4. QR order table-tent printing */}
            <Card className="p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <StepBadge n={4} />
                <span className="font-semibold text-stone-800">ตั้งค่าการพิมพ์ใบ QR Code สั่งอาหาร</span>
              </div>
              <div className="ml-8 space-y-2">
                <ToggleRow label="เปิดใช้งานพิมพ์ใบ QR Code สั่งอาหาร" checked={!!openPrinter.qrOrderEnabled} onChange={v => updatePrinter(openPrinter.id, { qrOrderEnabled: v })} />
                <p className="text-xs text-stone-400">เมื่อเปิดใช้งาน เครื่องพิมพ์นี้จะพิมพ์ใบตั้งโต๊ะ (table-tent) ที่มี QR Code ให้ลูกค้าสแกนสั่งอาหารเองได้จากหน้า "ตั้งค่า QR Code สั่งอาหาร"</p>
              </div>
            </Card>

            {/* 5. Reprint receipt settings */}
            <Card className="p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <StepBadge n={5} />
                <span className="font-semibold text-stone-800">ตั้งค่าพิมพ์ใบเสร็จซ้ำ</span>
              </div>
              <div className="ml-8 space-y-2">
                <ToggleRow label="เปิดใช้งานพิมพ์ใบเสร็จซ้ำจากหน้า &quot;ประวัติใบเสร็จ&quot;" checked={!!openPrinter.reprintEnabled} onChange={v => updatePrinter(openPrinter.id, { reprintEnabled: v })} />
                <p className="text-xs text-stone-400">เมื่อเปิดใช้งาน เครื่องพิมพ์นี้จะรับคำสั่งพิมพ์ซ้ำเมื่อกดปุ่ม "พิมพ์" ที่หน้า "หน้าร้าน → ประวัติใบเสร็จ" — ถ้าปิดไว้ (หรือไม่มีเครื่องพิมพ์ไหนเปิดเลย) จะข้ามไปใช้ print dialog ของเบราว์เซอร์แทนทันที</p>
              </div>
            </Card>

            {/* 6. Precheck bill printing */}
            <Card className="p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <StepBadge n={6} />
                <span className="font-semibold text-stone-800">ตั้งค่าพิมพ์ใบแจ้งยอด</span>
              </div>
              <div className="ml-8 space-y-2">
                <ToggleRow label="เปิดใช้งานพิมพ์ใบแจ้งยอด" checked={!!openPrinter.precheckEnabled} onChange={v => updatePrinter(openPrinter.id, { precheckEnabled: v })} />
                <p className="text-xs text-stone-400">เมื่อเปิดใช้งาน เครื่องพิมพ์นี้จะรับคำสั่งพิมพ์เมื่อกดปุ่ม "พิมพ์ใบสรุปยอด" ที่หน้าชำระเงินใน POS — ถ้าปิดไว้ (หรือไม่มีเครื่องพิมพ์ไหนเปิดเลย) จะข้ามไปใช้ print dialog ของเบราว์เซอร์แทนทันที</p>
              </div>
            </Card>
          </>
        )}

        <div>
          <Btn onClick={() => setSaved(true)}>บันทึกการตั้งค่าเครื่องพิมพ์นี้</Btn>
          {saved && <span className="text-emerald-600 text-xs ml-3">บันทึกเรียบร้อย ✓</span>}
        </div>
      </div>

      {/* Find new printer by IP popup */}
      {showIpForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowIpForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">ค้นหาเครื่องพิมพ์ใหม่</div>
              <button onClick={() => setShowIpForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <div className="grid grid-cols-2 gap-3">
                <Field label="ยี่ห้อของเครื่องพิมพ์">
                  <select className={inputCls} value={ipForm.brand} onChange={e => setIpForm(f => ({ ...f, brand: e.target.value, model: "" }))}>
                    <option value="">ยี่ห้อของเครื่องพิมพ์</option>
                    {PRINTER_BRANDS.map(b => <option key={b} value={b}>{b}</option>)}
                  </select>
                </Field>
                <Field label="รุ่นของเครื่องพิมพ์">
                  <select className={inputCls} value={ipForm.model} onChange={e => setIpForm(f => ({ ...f, model: e.target.value }))} disabled={!ipForm.brand}>
                    <option value="">Select model</option>
                    {(BRAND_MODELS[ipForm.brand] || []).map(m => <option key={m} value={m}>{m}</option>)}
                  </select>
                </Field>
              </div>
              <Field label="ที่อยู่ IP">
                <input className={`${inputCls} font-mono`} value={ipForm.ip} onChange={e => { setIpForm(f => ({ ...f, ip: e.target.value })); setIpFormError(""); }} placeholder="ตั้งที่อยู่ IP" />
              </Field>
              <p className="text-[11px] text-stone-400 -mt-1">ที่อยู่ IP สามารถดูได้จากการ FEED IP ของเครื่องพิมพ์ หากต้องการความช่วยเหลือติดต่อฝ่ายบริการลูกค้า</p>
              <Field label="ชื่อเครื่องพิมพ์">
                <input className={inputCls} value={ipForm.name} onChange={e => { setIpForm(f => ({ ...f, name: e.target.value })); setIpFormError(""); }} placeholder="ตั้งชื่อเครื่องพิมพ์" />
              </Field>
              {ipFormError && <div className="text-xs text-rose-500">{ipFormError}</div>}
            </div>
            <Btn className="w-full justify-center mt-5" onClick={submitIpForm}>ค้นหา</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: NOTIFICATION SOUND SETTINGS
   ========================================================================= */

// One event's sound-source editor (source picker + preview/upload + test +
// save). Pulled out so SoundSettingsPage can render one of these per alert
// event (new kitchen order, customer calling staff, ...) without duplicating
// the whole file-upload/YouTube/TTS UI for each one.
// Fallback shape used if a saved settings object is ever missing this
// event's key entirely (e.g. it was saved before this event existed) — keeps
// this component from crashing the whole page with "Cannot read properties
// of undefined" the way a bare settings[eventKey] would.
const SOUND_EVENT_FALLBACK = { source: "tts", fileName: "", fileDataUrl: null, youtubeUrl: "", positionIds: null };

function SoundEventEditor({ eventKey, stepNumber, title, description, ttsText, testFrameId, settings, setSettings, positions }) {
  const [draft, setDraft] = useState(settings[eventKey] || SOUND_EVENT_FALLBACK);
  const [saved, setSaved] = useState(false);
  const fileInputRef = useRef(null);
  const s = draft;
  const isDirty = JSON.stringify(draft) !== JSON.stringify(settings[eventKey] || SOUND_EVENT_FALLBACK);
  useEffect(() => { setDraft(settings[eventKey] || SOUND_EVENT_FALLBACK); }, [settings[eventKey]]);

  function set(patch) {
    setDraft(prev => ({ ...prev, ...patch }));
  }
  // positionIds === null means "not restricted" (every position hears this
  // alert — the default, same behavior as before this setting existed).
  // Switching the toggle off starts from an empty selection rather than
  // pre-filling every position, so the checkboxes always reflect exactly
  // who's currently chosen instead of looking pre-selected while meaning
  // something different underneath.
  const allPositionsMode = s.positionIds == null;
  function togglePosition(posId) {
    const current = s.positionIds || [];
    set({ positionIds: current.includes(posId) ? current.filter(id => id !== posId) : [...current, posId] });
  }
  function handleFile(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => set({ fileName: file.name, fileDataUrl: reader.result });
    reader.readAsDataURL(file);
  }
  function testSound() {
    if (s.source === "tts") {
      speakOrderAlert(ttsText);
    } else if (s.source === "file" && s.fileDataUrl) {
      new Audio(s.fileDataUrl).play().catch(() => {});
    } else if (s.source === "youtube") {
      const id = getYouTubeId(s.youtubeUrl);
      if (id) {
        const frame = document.getElementById(testFrameId);
        if (frame) frame.src = `https://www.youtube.com/embed/${id}?autoplay=1`;
      }
    }
  }
  function saveChanges() {
    setSettings(prev => ({ ...prev, [eventKey]: draft }));
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  return (
    <Card className="p-5 max-w-2xl">
      <div className="flex items-center gap-2.5 mb-1">
        <StepBadge n={stepNumber} />
        <span className="font-semibold text-stone-800">{title}</span>
      </div>
      <p className="text-sm text-stone-400 mb-4 ml-8">{description}</p>

      <div className="ml-8 space-y-4">
        <div>
          <div className="text-xs font-medium text-stone-500 mb-2">แหล่งเสียง</div>
          <SegmentedChoice value={s.source} onChange={v => set({ source: v })}
            options={[
              { value: "tts", label: "เสียงพูดอัตโนมัติ" },
              { value: "file", label: "อัปโหลดไฟล์เสียง" },
              { value: "youtube", label: "ลิงก์ YouTube" },
            ]} />
        </div>

        {s.source === "tts" && (
          <div className="text-sm text-stone-500 p-3 rounded-lg border border-stone-200 bg-stone-50">
            ใช้เสียงพูดของระบบพูดว่า <span className="font-medium text-stone-700">"{ttsText}"</span> โดยอัตโนมัติ ไม่ต้องอัปโหลดไฟล์ — ระบบจะเลือกเสียงผู้หญิงที่มีอยู่ในเครื่องโดยอัตโนมัติ พร้อมปรับโทนเสียงให้ฟังดูสดใส/ดีใจ
          </div>
        )}

        <div>
          <div className="text-xs font-medium text-stone-500 mb-2">แจ้งเตือนให้ตำแหน่งไหนบ้าง</div>
          <label className="flex items-center gap-2 text-sm text-stone-600 cursor-pointer mb-2">
            <input type="checkbox" checked={allPositionsMode} onChange={e => set({ positionIds: e.target.checked ? null : [] })} />
            ทุกตำแหน่ง (ค่าเริ่มต้น)
          </label>
          {!allPositionsMode && (
            <>
              <div className="flex flex-wrap gap-2">
                {(positions || []).map(p => {
                  const checked = (s.positionIds || []).includes(p.id);
                  return (
                    <label key={p.id}
                      className={`text-xs px-2.5 py-1.5 rounded-full border cursor-pointer transition-colors ${checked ? "bg-stone-800 text-white border-stone-800" : "bg-white text-stone-600 border-stone-200"}`}>
                      <input type="checkbox" className="hidden" checked={checked} onChange={() => togglePosition(p.id)} />
                      {p.name}
                    </label>
                  );
                })}
              </div>
              {(!positions || !positions.length) && (
                <p className="text-xs text-stone-400">ยังไม่มีตำแหน่งในระบบ — เพิ่มตำแหน่งได้ที่เมนู "พนักงาน → ตำแหน่ง" ก่อน</p>
              )}
              <p className="text-[11px] text-stone-400 mt-1.5">เจ้าของร้านจะได้ยินเสียงแจ้งเตือนนี้เสมอ ไม่ว่าจะเลือกตำแหน่งใดก็ตาม{(s.positionIds || []).length === 0 && " — ตอนนี้ยังไม่ได้เลือกตำแหน่งใดเลย พนักงานตำแหน่งอื่นจะไม่ได้ยินเสียงนี้"}</p>
            </>
          )}
        </div>

        {s.source === "file" && (
          <div className="p-3 rounded-lg border border-stone-200">
            <div className="text-xs text-stone-400 mb-2">รองรับไฟล์เสียง/วิดีโอ เช่น .mp3, .mp4, .wav</div>
            <div className="flex items-center gap-2">
              <input ref={fileInputRef} type="file" accept="audio/*,video/mp4" className="hidden" onChange={handleFile} />
              <Btn variant="ghost" onClick={() => fileInputRef.current?.click()}>เลือกไฟล์เสียง</Btn>
              {s.fileName && <span className="text-sm text-stone-600">{s.fileName}</span>}
            </div>
          </div>
        )}

        {s.source === "youtube" && (
          <div className="p-3 rounded-lg border border-stone-200">
            <Field label="ลิงก์ YouTube">
              <input className={inputCls} value={s.youtubeUrl} onChange={e => set({ youtubeUrl: e.target.value })} placeholder="https://www.youtube.com/watch?v=..." />
            </Field>
            {s.youtubeUrl && !getYouTubeId(s.youtubeUrl) && <div className="text-[11px] text-rose-500 mt-1.5">ไม่พบรหัสวิดีโอ ตรวจสอบลิงก์อีกครั้ง</div>}
            <iframe id={testFrameId} title="ทดสอบเสียง YouTube" width="0" height="0" style={{ border: 0, display: "none" }} allow="autoplay" />
          </div>
        )}

        <div className="flex items-center gap-3">
          <Btn variant="subtle" onClick={testSound}><Volume2 size={14} /> ทดสอบเสียง</Btn>
          <Btn onClick={saveChanges} disabled={!isDirty}>บันทึกการตั้งค่า</Btn>
          {isDirty && <Btn variant="ghost" onClick={() => setDraft(settings[eventKey])}>ยกเลิกการแก้ไข</Btn>}
          {saved && !isDirty && <span className="text-emerald-600 text-xs">บันทึกเรียบร้อย ✓</span>}
        </div>
      </div>
    </Card>
  );
}

function SoundSettingsPage({ settings, setSettings, positions }) {
  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ตั้งค่าเสียงแจ้งเตือน" subtitle="กำหนดเสียงแจ้งเตือนเมื่อมีออเดอร์ใหม่เข้าครัว หรือลูกค้าเรียกพนักงานจากมือถือ" />

      <div className="space-y-5">
        <SoundEventEditor eventKey="newOrder" stepNumber={1} title="เสียงรับออเดอร์ใหม่"
          description={`เล่นอัตโนมัติที่หน้า "ครัวอาหาร" และ "ครัวเครื่องดื่ม" ทุกครั้งที่มีออเดอร์ใหม่เข้ามา`}
          ttsText="Order เข้าแล้ว" testFrameId="sound-test-yt-frame-neworder" settings={settings} setSettings={setSettings} positions={positions} />

        <SoundEventEditor eventKey="callStaff" stepNumber={2} title="เสียงลูกค้าเรียกพนักงาน"
          description={`เล่นอัตโนมัติทั่วทั้งระบบ (ไม่ว่ากำลังเปิดหน้าไหนอยู่) ทันทีที่ลูกค้ากด "เรียกพนักงาน" จากมือถือของตัวเอง — เช็คทุก 7 วินาทีเหมือนกับที่ตรวจออเดอร์ใหม่จากลูกค้า`}
          ttsText="ลูกค้าเรียกพนักงาน" testFrameId="sound-test-yt-frame-callstaff" settings={settings} setSettings={setSettings} positions={positions} />
      </div>

      <p className="text-xs text-stone-400 mt-4 max-w-2xl">
        หมายเหตุ: เบราว์เซอร์บางตัวอาจบล็อกเสียงอัตโนมัติจนกว่าจะมีการคลิกในหน้าเว็บก่อน 1 ครั้ง (เช่น กดปุ่มทดสอบเสียงนี้) หลังจากนั้นเสียงแจ้งเตือนจะเล่นอัตโนมัติได้ตามปกติ
      </p>
    </div>
  );
}

/* =========================================================================
   PAGE: STAFF LIST
   ========================================================================= */

function generatePin() {
  return String(Math.floor(100000 + Math.random() * 900000));
}

/* Random token identifying one table's current open session for the customer
   self-order QR code. Regenerated every time a table is (re)opened, and
   cleared when the bill is paid — so a QR scanned/saved from a previous
   customer can never be used to keep ordering after that table has closed out. */
function generateQrToken() {
  return Math.random().toString(36).slice(2, 10) + Date.now().toString(36).slice(-4);
}

/* Used by the staff-side "check for new customer self-orders" poll (see the
   posSessions poll effect in RestaurantBackOffice) to fold in a table's
   latest server state without reverting anything this browser tab already
   knows locally. Only ever ADOPTS fields that the server has "more of" than
   the local copy (a longer sentItems list, a call-staff request or payment
   slip the local copy doesn't have yet) — it never removes or replaces
   local data with something older, so it's safe even if this tab's own
   edit for the same table is still mid-flight to the server. */
function mergeSessionFromServer(local, remote) {
  if (!remote) return local;
  if (!local) return remote;
  let next = local;
  const remoteSentLen = (remote.sentItems || []).length;
  const localSentLen = (local.sentItems || []).length;
  if (remoteSentLen > localSentLen) {
    next = { ...next, sentItems: remote.sentItems, billTotal: remote.billTotal };
  }
  if (remote.callStaffRequested && !local.callStaffRequested) {
    next = { ...next, callStaffRequested: true, callStaffReason: remote.callStaffReason, callStaffAt: remote.callStaffAt };
  }
  if (remote.paymentSlipDataUrl && !local.paymentSlipDataUrl) {
    next = { ...next, paymentSlipDataUrl: remote.paymentSlipDataUrl, paymentStatus: remote.paymentStatus, slipVerification: remote.slipVerification || null };
  }
  // Customer links their own member account from the mobile payment page
  // (MobileOrderPage's "ผูกสมาชิก" field, PATCH .../link-member) — adopt it
  // here so the staff POS screen shows the same linked member automatically
  // within one poll cycle, without staff having to type the phone number in
  // again. Only adopts when the local copy doesn't already have a member
  // linked, matching this function's "only add, never remove/replace" rule —
  // if staff already linked a (possibly different) member locally, that
  // local choice wins and isn't silently swapped out.
  if (remote.memberId && !local.memberId) {
    next = { ...next, memberId: remote.memberId };
  }
  return next;
}

const DILIGENCE_CONDITIONS = [
  { key: "noAbsent", label: "ไม่ขาด" },
  { key: "noLeave", label: "ไม่ลา" },
  { key: "noLate", label: "ไม่มาสาย" },
];

function StaffListPage({ staff, setStaff, positions, categories, currentBranchId, branches }) {
  const [showForm, setShowForm] = useState(false);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleStaff = staff.filter(s => !effectiveBranchId || !s.branchIds?.length || s.branchIds.includes(effectiveBranchId));
  const emptyForm = { name: "", displayName: "", branchIds: effectiveBranchId ? [effectiveBranchId] : [], phone: "", positionId: positions[0]?.id || "", pin: generatePin(), startDate: new Date().toISOString().slice(0, 10), compensation: emptyCompensation(), bankInfo: { bankName: "", accountNumber: "", accountName: "" } };
  const [form, setForm] = useState(emptyForm);
  const [visiblePins, setVisiblePins] = useState({});
  const [viewing, setViewing] = useState(null);

  function openForm() {
    setForm({ ...emptyForm, pin: generatePin() });
    setShowForm(true);
  }
  function startEdit(s) {
    setForm({ ...s, displayName: s.displayName || "", branchIds: s.branchIds || [], compensation: s.compensation || emptyCompensation(), bankInfo: s.bankInfo || { bankName: "", accountNumber: "", accountName: "" } });
    setShowForm(true);
  }
  function toggleFormBranch(branchId) {
    setForm(f => ({ ...f, branchIds: f.branchIds.includes(branchId) ? f.branchIds.filter(id => id !== branchId) : [...f.branchIds, branchId] }));
  }
  function submit() {
    if (!form.name || !form.phone || !/^\d{6}$/.test(form.pin)) return;
    if (form.id) {
      setStaff(prev => prev.map(s => s.id === form.id ? { ...s, ...form } : s));
    } else {
      setStaff(prev => [...prev, { id: "st" + Date.now(), ...form, active: true }]);
    }
    setShowForm(false);
  }
  function toggleActive(id) {
    setStaff(prev => prev.map(s => s.id === id ? { ...s, active: !s.active } : s));
  }
  function removeStaff(id) {
    setStaff(prev => prev.filter(s => s.id !== id));
  }
  function togglePinVisible(id) {
    setVisiblePins(prev => ({ ...prev, [id]: !prev[id] }));
  }
  function resetPin(id) {
    const newPin = generatePin();
    setStaff(prev => prev.map(s => s.id === id ? { ...s, pin: newPin } : s));
    setViewing(prev => prev && prev.id === id ? { ...prev, pin: newPin } : prev);
    setVisiblePins(prev => ({ ...prev, [id]: true }));
  }

  function setComp(patch) {
    setForm(prev => ({ ...prev, compensation: { ...prev.compensation, ...patch } }));
  }
  function setBankInfo(patch) {
    setForm(prev => ({ ...prev, bankInfo: { ...prev.bankInfo, ...patch } }));
  }
  function setCommission(patch) {
    setForm(prev => ({ ...prev, compensation: { ...prev.compensation, commission: { ...prev.compensation.commission, ...patch } } }));
  }
  function toggleCommissionCategory(catId) {
    setForm(prev => {
      const cur = prev.compensation.commission.excludedCategoryIds || [];
      const next = cur.includes(catId) ? cur.filter(id => id !== catId) : [...cur, catId];
      return { ...prev, compensation: { ...prev.compensation, commission: { ...prev.compensation.commission, excludedCategoryIds: next } } };
    });
  }
  function setDiligence(patch) {
    setForm(prev => ({ ...prev, compensation: { ...prev.compensation, diligenceBonus: { ...prev.compensation.diligenceBonus, ...patch } } }));
  }
  function toggleDiligenceCondition(key) {
    setForm(prev => {
      const cur = prev.compensation.diligenceBonus.conditions;
      const next = cur.includes(key) ? cur.filter(k => k !== key) : [...cur, key];
      return { ...prev, compensation: { ...prev.compensation, diligenceBonus: { ...prev.compensation.diligenceBonus, conditions: next } } };
    });
  }

  return (
    <div>
      <PageHeader eyebrow="พนักงาน" title="รายชื่อพนักงาน" subtitle="รายชื่อพนักงานทั้งหมดและตำแหน่งที่รับผิดชอบ"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มพนักงาน</Btn>
          </div>
        } />
      <Card>
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
              <th className="px-4 py-3 font-medium">ชื่อพนักงาน</th>
              <th className="px-4 py-3 font-medium">เบอร์โทร</th>
              <th className="px-4 py-3 font-medium">ตำแหน่ง</th>
              <th className="px-4 py-3 font-medium">สาขา</th>
              <th className="px-4 py-3 font-medium">PIN</th>
              <th className="px-4 py-3 font-medium">วันเริ่มงาน</th>
              <th className="px-4 py-3 font-medium">สถานะ</th>
              <th className="px-4 py-3 font-medium"></th>
            </tr>
          </thead>
          <tbody>
            {visibleStaff.map(s => {
              const pos = positions.find(p => p.id === s.positionId);
              return (
                <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 font-medium text-stone-800">{s.name}</td>
                  <td className="px-4 py-3 text-stone-500">{s.phone}</td>
                  <td className="px-4 py-3"><span className="text-xs px-2 py-0.5 rounded border border-stone-300 bg-stone-100 text-stone-600 font-medium">{pos?.name || "-"}</span></td>
                  <td className="px-4 py-3 text-stone-500">{s.branchIds?.length ? s.branchIds.map(id => branches?.find(b => b.id === id)?.name).filter(Boolean).join(", ") : "ทุกสาขา"}</td>
                  <td className="px-4 py-3">
                    <button onClick={() => togglePinVisible(s.id)} className="flex items-center gap-1.5 font-mono text-stone-600 hover:text-stone-900">
                      {visiblePins[s.id] ? s.pin : "••••••"}
                      <Eye size={13} className="text-stone-300" />
                    </button>
                  </td>
                  <td className="px-4 py-3 text-stone-400">{fmtDate(s.startDate)}</td>
                  <td className="px-4 py-3">
                    <button onClick={() => toggleActive(s.id)}
                      className={`relative w-11 h-6 rounded-full transition-colors ${s.active ? "bg-emerald-500" : "bg-stone-300"}`}>
                      <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${s.active ? "translate-x-5" : "translate-x-0"}`} />
                    </button>
                  </td>
                  <td className="px-4 py-3 text-right">
                    <div className="flex items-center justify-end gap-3">
                      <button onClick={() => startEdit(s)} className="text-stone-400 hover:text-amber-700 flex items-center gap-1 text-xs font-medium"><Pencil size={13} /> แก้ไขข้อมูล</button>
                      <Btn variant="ghost" onClick={() => setViewing(s)}>ดูข้อมูลพนักงาน</Btn>
                      <button onClick={() => removeStaff(s.id)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
        </div>
      </Card>

      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-2xl p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขข้อมูลพนักงาน" : "เพิ่มพนักงาน"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
              <Field label="ชื่อพนักงาน"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="ชื่อ-นามสกุล" autoFocus /></Field>
              <Field label="Display (ชื่อที่แสดงในใบเสร็จ)"><input className={inputCls} value={form.displayName} onChange={e => setForm({ ...form, displayName: e.target.value })} placeholder="เช่น ชื่อเล่น หรือรหัสพนักงาน" /></Field>
              <Field label="เบอร์โทร"><input className={inputCls} value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} placeholder="08x-xxx-xxxx" /></Field>
              <Field label="ตำแหน่ง">
                <select className={inputCls} value={form.positionId} onChange={e => setForm({ ...form, positionId: e.target.value })}>
                  {positions.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
                </select>
              </Field>
              {branches && branches.length > 0 && (
                <div>
                  <div className="text-xs text-stone-500 mb-1.5">สาขาที่ปฏิบัติงาน (เลือกได้มากกว่า 1 สาขา)</div>
                  <div className="flex flex-wrap gap-2">
                    {branches.filter(b => b.active).map(b => (
                      <label key={b.id} className={`flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border cursor-pointer ${form.branchIds.includes(b.id) ? "bg-amber-50 border-amber-300 text-amber-800" : "border-stone-300 text-stone-600"}`}>
                        <input type="checkbox" className="hidden" checked={form.branchIds.includes(b.id)} onChange={() => toggleFormBranch(b.id)} />
                        {b.name}
                      </label>
                    ))}
                  </div>
                  {form.branchIds.length === 0 && <p className="text-[11px] text-stone-400 mt-1">ไม่เลือกสาขาใดเลย = ทำงานได้ทุกสาขา</p>}
                </div>
              )}
              <Field label="วันเริ่มงาน"><input type="date" className={inputCls} value={form.startDate} onChange={e => setForm({ ...form, startDate: e.target.value })} /></Field>
              <div className="col-span-1 sm:col-span-2">
                <Field label="PIN เข้าใช้งานระบบ (6 หลัก)">
                  <div className="flex items-center gap-2">
                    <input className={`${inputCls} font-mono max-w-[160px]`} value={form.pin} maxLength={6} inputMode="numeric"
                      onChange={e => setForm({ ...form, pin: e.target.value.replace(/\D/g, "").slice(0, 6) })} placeholder="เช่น 194720" />
                    <button type="button" onClick={() => setForm({ ...form, pin: generatePin() })} className="text-xs text-amber-700 hover:text-amber-900 whitespace-nowrap flex items-center gap-1">
                      <RefreshCw size={12} /> สุ่มใหม่
                    </button>
                  </div>
                  {form.pin && !/^\d{6}$/.test(form.pin) && <div className="text-[11px] text-rose-500 mt-1">PIN ต้องเป็นตัวเลข 6 หลัก</div>}
                </Field>
              </div>
            </div>

            {/* Compensation section */}
            <div className="border-t border-stone-200 mt-5 pt-4">
              <div className="text-sm font-semibold text-stone-700 mb-3">อัตราค่าตอบแทน</div>

              <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-3">
                <Field label="ฐานเงินเดือน (บาท)"><input type="number" className={inputCls} value={form.compensation.baseSalary} onChange={e => setComp({ baseSalary: e.target.value })} /></Field>
                <Field label="ค่าตำแหน่ง (บาท)"><input type="number" className={inputCls} value={form.compensation.positionAllowance} onChange={e => setComp({ positionAllowance: e.target.value })} /></Field>
                <Field label="ค่าเดินทาง (บาท)"><input type="number" className={inputCls} value={form.compensation.travelAllowance} onChange={e => setComp({ travelAllowance: e.target.value })} /></Field>
                <Field label="ค่าน้ำมัน (บาท)"><input type="number" className={inputCls} value={form.compensation.fuelAllowance} onChange={e => setComp({ fuelAllowance: e.target.value })} /></Field>
              </div>

              <div className="p-3 rounded-lg border border-stone-200 mb-3">
                <div className="text-xs font-medium text-stone-600 mb-2">ค่าคอมมิชชั่น (คำนวณจากยอดขายไม่รวม VAT)</div>
                <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
                  <Field label="ยอดขายขั้นต่ำที่รับค่าคอม (บาท)"><input type="number" className={inputCls} value={form.compensation.commission.minSales} onChange={e => setCommission({ minSales: e.target.value })} /></Field>
                  <Field label="รูปแบบค่าคอม">
                    <SegmentedChoice value={form.compensation.commission.type} onChange={v => setCommission({ type: v })}
                      options={[{ value: "percent", label: "%" }, { value: "amount", label: "บาท" }]} />
                  </Field>
                  <Field label={form.compensation.commission.type === "percent" ? "อัตรา (%)" : "จำนวน (บาท)"}>
                    <input type="number" className={inputCls} value={form.compensation.commission.value} onChange={e => setCommission({ value: e.target.value })} />
                  </Field>
                </div>
                <div className="mt-3">
                  <div className="text-xs text-stone-400 mb-1.5">หมวดหมู่ที่ไม่นับรวมเป็นยอดขาย (เช่น เครื่องดื่ม)</div>
                  <div className="flex flex-wrap gap-2">
                    {categories.map(c => (
                      <button key={c.id} type="button" onClick={() => toggleCommissionCategory(c.id)}
                        className={`px-3 py-1.5 rounded-full text-xs border ${(form.compensation.commission.excludedCategoryIds || []).includes(c.id) ? "bg-rose-50 text-rose-600 border-rose-300" : "border-stone-300 text-stone-500"}`}>
                        {c.name}
                      </button>
                    ))}
                  </div>
                </div>
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-3">
                <Field label="OT ทำงานล่วงเวลา (เท่าของเงินเดือน)"><input type="number" step="0.1" className={inputCls} value={form.compensation.otMultiplier} onChange={e => setComp({ otMultiplier: e.target.value })} /></Field>
                <Field label="โบนัส (เดือน) เมื่อทำงานครบปี"><input type="number" step="0.1" className={inputCls} value={form.compensation.annualBonusMonths} onChange={e => setComp({ annualBonusMonths: e.target.value })} /></Field>
              </div>

              <div className="p-3 rounded-lg border border-stone-200">
                <div className="text-xs font-medium text-stone-600 mb-2">เบี้ยขยัน</div>
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                  <Field label="จำนวนเบี้ยขยัน (บาท)"><input type="number" className={inputCls} value={form.compensation.diligenceBonus.amount} onChange={e => setDiligence({ amount: e.target.value })} /></Field>
                  <Field label="เงื่อนไข">
                    <div className="flex flex-wrap gap-2">
                      {DILIGENCE_CONDITIONS.map(c => (
                        <button key={c.key} type="button" onClick={() => toggleDiligenceCondition(c.key)}
                          className={`px-3 py-1.5 rounded-md text-xs border ${form.compensation.diligenceBonus.conditions.includes(c.key) ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>
                          {c.label}
                        </button>
                      ))}
                    </div>
                  </Field>
                </div>
              </div>

              <div className="p-3 rounded-lg border border-stone-200 mt-3">
                <label className="flex items-center justify-between cursor-pointer mb-2">
                  <span className="text-xs font-medium text-stone-600">หักประกันสังคม</span>
                  <input type="checkbox" checked={form.compensation.socialSecurityEnabled} onChange={e => setComp({ socialSecurityEnabled: e.target.checked })} />
                </label>
                {form.compensation.socialSecurityEnabled && (
                  <Field label="จำนวนที่หัก (บาท/เดือน) — เว้นว่างให้คำนวณอัตโนมัติ 5% (เพดานปรับตามปีตามตารางที่ประกาศไว้)">
                    <input type="number" className={inputCls} value={form.compensation.socialSecurityAmount} onChange={e => setComp({ socialSecurityAmount: e.target.value })} placeholder="เช่น 750" />
                  </Field>
                )}
              </div>

              <div className="p-3 rounded-lg border border-stone-200 mt-3">
                <div className="text-xs font-medium text-stone-600 mb-2 flex items-center gap-1.5"><CreditCard size={13} /> บัญชีธนาคาร (สำหรับโอนเงินเดือน)</div>
                <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                  <Field label="ธนาคาร"><input className={inputCls} value={form.bankInfo.bankName} onChange={e => setBankInfo({ bankName: e.target.value })} placeholder="เช่น ธนาคารกสิกรไทย" /></Field>
                  <Field label="เลขที่บัญชี"><input className={inputCls} value={form.bankInfo.accountNumber} onChange={e => setBankInfo({ accountNumber: e.target.value.replace(/[^\d-]/g, "") })} placeholder="เช่น 123-4-56789-0" /></Field>
                </div>
                <div className="mt-3">
                  <Field label="ชื่อบัญชี"><input className={inputCls} value={form.bankInfo.accountName} onChange={e => setBankInfo({ accountName: e.target.value })} placeholder="ชื่อ-นามสกุลตามหน้าบัญชี" /></Field>
                </div>
              </div>
            </div>

            <Btn className="w-full justify-center mt-5" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "เพิ่มพนักงาน"}</Btn>
          </div>
          </div>
        </div>
      )}

      {/* View employee detail modal */}
      {viewing && (() => {
        const pos = positions.find(p => p.id === viewing.positionId);
        return (
          <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setViewing(null)}>
            <div className="min-h-full flex items-start justify-center py-8">
            <div className="bg-white rounded-xl w-full max-w-md p-6" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800 text-lg">{viewing.name}</div>
                <button onClick={() => setViewing(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm mb-4">
                <div><span className="text-stone-400">เบอร์โทร:</span> {viewing.phone}</div>
                <div><span className="text-stone-400">วันเริ่มงาน:</span> {fmtDate(viewing.startDate)}</div>
                <div><span className="text-stone-400">ตำแหน่ง:</span> {pos?.name || "-"}</div>
                <div><span className="text-stone-400">PIN:</span> <span className="font-mono">{visiblePins[viewing.id] ? viewing.pin : "••••••"}</span>{" "}
                  <button onClick={() => togglePinVisible(viewing.id)} className="text-amber-700 hover:text-amber-900 text-xs">{visiblePins[viewing.id] ? "ซ่อน" : "แสดง"}</button>{" "}
                  <button onClick={() => resetPin(viewing.id)} className="text-stone-400 hover:text-rose-500 text-xs">รีเซ็ต PIN</button>
                </div>
                <div className="col-span-1 sm:col-span-2 flex items-center gap-1.5">
                  <span className="text-stone-400">สถานะ:</span>
                  <span className={`text-xs px-2 py-0.5 rounded border font-medium ${viewing.active ? "bg-emerald-50 text-emerald-700 border-emerald-300" : "bg-stone-100 text-stone-500 border-stone-300"}`}>
                    {viewing.active ? "ทำงานอยู่" : "ปิดใช้งาน"}
                  </span>
                </div>
              </div>

              <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5">สิทธิ์เข้าถึงเมนู (ตามตำแหน่ง)</div>
              <div className="flex flex-wrap gap-1 mb-4">
                {(pos?.permissions || []).length === 0 && <span className="text-sm text-stone-400">ไม่มีสิทธิ์เข้าถึง</span>}
                {(pos?.permissions || []).map(key => {
                  const opt = PERMISSION_OPTIONS.find(o => o.key === key);
                  return <span key={key} className="text-[10px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">{opt?.label || key}</span>;
                })}
              </div>

              {viewing.compensation && (
                <>
                  <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5">อัตราค่าตอบแทน</div>
                  <div className="text-sm text-stone-600 divide-y divide-stone-100">
                    <div className="flex items-center justify-between py-1.5">
                      <span>ฐานเงินเดือน</span>
                      <span className="font-mono">{fmtMoney(viewing.compensation.baseSalary)} บาท</span>
                    </div>
                    <div className="flex items-center justify-between py-1.5">
                      <span>ค่าตำแหน่ง</span>
                      <span className="font-mono">{fmtMoney(viewing.compensation.positionAllowance)} บาท</span>
                    </div>
                    <div className="flex items-center justify-between py-1.5">
                      <span>ค่าเดินทาง</span>
                      <span className="font-mono">{fmtMoney(viewing.compensation.travelAllowance)} บาท</span>
                    </div>
                    <div className="flex items-center justify-between py-1.5">
                      <span>ค่าน้ำมัน</span>
                      <span className="font-mono">{fmtMoney(viewing.compensation.fuelAllowance)} บาท</span>
                    </div>
                    <div className="py-1.5">
                      <div className="flex items-center justify-between">
                        <span>ค่าคอม (ยอดขายขั้นต่ำ)</span>
                        <span className="font-mono">{fmtMoney(viewing.compensation.commission?.minSales)} บาท</span>
                      </div>
                      <div className="flex items-center justify-between">
                        <span className="text-stone-400">ได้รับ</span>
                        <span className="font-mono">
                          {viewing.compensation.commission?.type === "percent"
                            ? `${viewing.compensation.commission?.value || 0}%`
                            : `${fmtMoney(viewing.compensation.commission?.value)} บาท`}
                        </span>
                      </div>
                      {viewing.compensation.commission?.excludedCategoryIds?.length > 0 && (
                        <div className="text-stone-400 text-xs mt-0.5">ไม่รวม {viewing.compensation.commission.excludedCategoryIds.map(id => categories.find(c => c.id === id)?.name).filter(Boolean).join(", ")}</div>
                      )}
                    </div>
                    <div className="flex items-center justify-between py-1.5">
                      <span>OT (ทำงานล่วงเวลา)</span>
                      <span className="font-mono">{viewing.compensation.otMultiplier || 0} เท่า</span>
                    </div>
                    <div className="flex items-center justify-between py-1.5">
                      <span>โบนัสประจำปี</span>
                      <span className="font-mono">{viewing.compensation.annualBonusMonths || 0} เดือน</span>
                    </div>
                    <div className="py-1.5">
                      <div className="flex items-center justify-between">
                        <span>เบี้ยขยัน</span>
                        <span className="font-mono">{fmtMoney(viewing.compensation.diligenceBonus?.amount)} บาท</span>
                      </div>
                      {viewing.compensation.diligenceBonus?.conditions?.length > 0 && (
                        <div className="text-stone-400 text-xs mt-0.5">
                          เงื่อนไข: {viewing.compensation.diligenceBonus.conditions.map(k => DILIGENCE_CONDITIONS.find(c => c.key === k)?.label).join(", ")}
                        </div>
                      )}
                    </div>
                  </div>
                </>
              )}

              {(viewing.bankInfo?.bankName || viewing.bankInfo?.accountNumber) && (
                <>
                  <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5 mt-4">บัญชีธนาคาร</div>
                  <div className="text-sm text-stone-600 space-y-1">
                    <div><span className="text-stone-400">ธนาคาร:</span> {viewing.bankInfo.bankName || "-"}</div>
                    <div><span className="text-stone-400">เลขที่บัญชี:</span> <span className="font-mono">{viewing.bankInfo.accountNumber || "-"}</span></div>
                    {viewing.bankInfo.accountName && <div><span className="text-stone-400">ชื่อบัญชี:</span> {viewing.bankInfo.accountName}</div>}
                  </div>
                </>
              )}
            </div>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

/* =========================================================================
   PAGE: STAFF POSITIONS (PERMISSIONS)
   ========================================================================= */

function StaffPositionsPage({ positions, setPositions }) {
  const [showForm, setShowForm] = useState(false);
  const emptyForm = { name: "", permissions: [], pinPermissions: [] };
  const [form, setForm] = useState(emptyForm);

  const groupedOptions = PERMISSION_OPTIONS.reduce((acc, opt) => {
    (acc[opt.group] ||= []).push(opt);
    return acc;
  }, {});

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }
  function startEdit(p) {
    setForm({ id: p.id, name: p.name, permissions: [...p.permissions], pinPermissions: [...(p.pinPermissions || [])] });
    setShowForm(true);
  }
  function togglePermission(key) {
    setForm(prev => ({ ...prev, permissions: prev.permissions.includes(key) ? prev.permissions.filter(k => k !== key) : [...prev.permissions, key] }));
  }
  function togglePinPermission(key) {
    setForm(prev => ({ ...prev, pinPermissions: prev.pinPermissions.includes(key) ? prev.pinPermissions.filter(k => k !== key) : [...prev.pinPermissions, key] }));
  }
  function toggleGroup(group) {
    const keys = groupedOptions[group].map(o => o.key);
    const allOn = keys.every(k => form.permissions.includes(k));
    setForm(prev => ({
      ...prev,
      permissions: allOn ? prev.permissions.filter(k => !keys.includes(k)) : [...new Set([...prev.permissions, ...keys])],
    }));
  }
  function submit() {
    if (!form.name) return;
    if (form.id) {
      setPositions(prev => prev.map(p => p.id === form.id ? { ...p, name: form.name, permissions: form.permissions, pinPermissions: form.pinPermissions } : p));
    } else {
      setPositions(prev => [...prev, { id: "pos" + Date.now(), name: form.name, permissions: form.permissions, pinPermissions: form.pinPermissions }]);
    }
    setShowForm(false);
  }
  function removePosition(id) {
    setPositions(prev => prev.filter(p => p.id !== id));
  }

  return (
    <div>
      <PageHeader eyebrow="พนักงาน" title="กำหนดตำแหน่ง" subtitle="กำหนดตำแหน่งงานและสิทธิ์เข้าถึงเมนูต่างๆ"
        right={<Btn onClick={openForm}><Plus size={14} /> เพิ่มตำแหน่ง</Btn>} />
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
        {positions.map(p => (
          <Card key={p.id} className="p-5">
            <div className="flex items-center justify-between mb-3">
              <span className="px-2.5 py-1 rounded border border-stone-300 bg-stone-100 text-sm font-semibold text-stone-700">{p.name}</span>
              <ShieldCheck size={18} className="text-stone-300" />
            </div>
            <div className="text-xs text-stone-400 mb-3">เข้าถึงได้ {p.permissions.length} / {PERMISSION_OPTIONS.length} เมนู</div>
            {(p.pinPermissions || []).length > 0 && (
              <div className="text-[11px] text-amber-600 mb-2 flex items-center gap-1"><ShieldCheck size={11} /> อนุมัติ PIN ได้ {p.pinPermissions.length} รายการ</div>
            )}
            <div className="flex flex-wrap gap-1">
              {p.permissions.slice(0, 6).map(key => {
                const opt = PERMISSION_OPTIONS.find(o => o.key === key);
                return <span key={key} className="text-[10px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">{opt?.label || key}</span>;
              })}
              {p.permissions.length > 6 && <span className="text-[10px] px-1.5 py-0.5 rounded bg-stone-100 text-stone-500">+{p.permissions.length - 6}</span>}
            </div>
            <div className="flex items-center gap-3 mt-4">
              <button onClick={() => startEdit(p)} className="text-xs text-stone-400 hover:text-amber-700 flex items-center gap-1"><Pencil size={11} /> แก้ไข</button>
              <button onClick={() => removePosition(p.id)} className="text-xs text-stone-400 hover:text-rose-500 flex items-center gap-1"><Trash2 size={11} /> ลบ</button>
            </div>
          </Card>
        ))}
      </div>

      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขตำแหน่ง" : "เพิ่มตำแหน่ง"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <Field label="ชื่อตำแหน่ง"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น ผู้ช่วยผู้จัดการ" autoFocus /></Field>

            <div className="mt-4">
              <div className="text-xs font-medium text-stone-500 mb-2">สิทธิ์เข้าถึงเมนู</div>
              <div className="space-y-3">
                {Object.entries(groupedOptions).map(([group, opts]) => (
                  <div key={group} className="border border-stone-200 rounded-lg p-3">
                    <label className="flex items-center gap-2 text-sm font-medium text-stone-700 mb-2 cursor-pointer">
                      <input type="checkbox" checked={opts.every(o => form.permissions.includes(o.key))} onChange={() => toggleGroup(group)} />
                      {group}
                    </label>
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-1 pl-6">
                      {opts.map(o => (
                        <label key={o.key} className="flex items-center gap-2 text-xs text-stone-600 cursor-pointer py-0.5">
                          <input type="checkbox" checked={form.permissions.includes(o.key)} onChange={() => togglePermission(o.key)} />
                          {o.label}
                        </label>
                      ))}
                    </div>
                  </div>
                ))}
              </div>
            </div>

            <div className="mt-4">
              <div className="text-xs font-medium text-stone-500 mb-2 flex items-center gap-1.5"><ShieldCheck size={13} className="text-amber-600" /> สิทธิ์การลบข้อมูล (ต้องใส่ PIN)</div>
              <p className="text-[11px] text-stone-400 mb-2">เลือกว่าตำแหน่งนี้สามารถใช้ PIN ของตัวเองอนุมัติการลบ/ยกเลิกจุดใดได้บ้าง</p>
              <div className="border border-stone-200 rounded-lg p-3 space-y-1">
                {PIN_DELETE_ACTIONS.map(a => (
                  <label key={a.key} className="flex items-center gap-2 text-xs text-stone-600 cursor-pointer py-0.5">
                    <input type="checkbox" checked={form.pinPermissions.includes(a.key)} onChange={() => togglePinPermission(a.key)} />
                    {a.label}
                  </label>
                ))}
              </div>
            </div>

            <Btn className="w-full justify-center mt-4" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "เพิ่มตำแหน่ง"}</Btn>
          </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: STAFF RECRUITMENT
   ========================================================================= */

function StaffRecruitmentPage({ jobs, setJobs, storeInfo, setApplicants, currentBranchId, branches }) {
  const [showForm, setShowForm] = useState(false);
  const emptyForm = { title: "", branchId: currentBranchId || "", workLocation: "", mapUrl: "", qualifications: [""], salaryMin: "", salaryMax: "", salaryUnit: "บาท/เดือน", contactChannels: [{ type: "โทรศัพท์", value: "" }] };
  const [form, setForm] = useState(emptyForm);
  const [previewJob, setPreviewJob] = useState(null);
  const [copiedId, setCopiedId] = useState(null);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleJobs = jobs.filter(j => !effectiveBranchId || !j.branchId || j.branchId === effectiveBranchId);
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  function openForm() {
    setForm({ ...emptyForm, branchId: currentBranchId || "" });
    setShowForm(true);
  }
  function updateQual(i, value) {
    setForm(prev => ({ ...prev, qualifications: prev.qualifications.map((q, idx) => idx === i ? value : q) }));
  }
  function addQual() {
    setForm(prev => ({ ...prev, qualifications: [...prev.qualifications, ""] }));
  }
  function removeQual(i) {
    setForm(prev => ({ ...prev, qualifications: prev.qualifications.filter((_, idx) => idx !== i) }));
  }
  function updateChannel(i, patch) {
    setForm(prev => ({ ...prev, contactChannels: prev.contactChannels.map((c, idx) => idx === i ? { ...c, ...patch } : c) }));
  }
  function addChannel() {
    setForm(prev => ({ ...prev, contactChannels: [...prev.contactChannels, { type: "โทรศัพท์", value: "" }] }));
  }
  function removeChannel(i) {
    setForm(prev => ({ ...prev, contactChannels: prev.contactChannels.filter((_, idx) => idx !== i) }));
  }
  function submit() {
    if (!form.title) return;
    setJobs(prev => [...prev, {
      id: "job" + Date.now(),
      title: form.title,
      branchId: form.branchId || null,
      workLocation: form.workLocation.trim(), mapUrl: form.mapUrl.trim(),
      qualifications: form.qualifications.map(q => q.trim()).filter(Boolean),
      salaryMin: form.salaryMin, salaryMax: form.salaryMax, salaryUnit: form.salaryUnit,
      contactChannels: form.contactChannels.filter(c => c.value.trim()),
      active: true,
    }]);
    setShowForm(false);
  }
  function toggleActive(id) {
    setJobs(prev => prev.map(j => j.id === id ? { ...j, active: !j.active } : j));
  }
  function removeJob(id) {
    setJobs(prev => prev.filter(j => j.id !== id));
  }
  function applyLink() {
    return `https://thenuar.com/job`;
  }
  function copyLink(id) {
    const link = applyLink();
    if (navigator.clipboard) navigator.clipboard.writeText(link).catch(() => {});
    setCopiedId(id);
    setTimeout(() => setCopiedId(null), 1500);
  }

  return (
    <div>
      <PageHeader eyebrow="พนักงาน" title="รับสมัครพนักงาน" subtitle="เปิดรับสมัครตำแหน่งงานและแชร์ลิงก์ใบสมัคร"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มตำแหน่งที่เปิดรับ</Btn>
          </div>
        } />

      <div className="space-y-3">
        {visibleJobs.map(j => (
          <Card key={j.id} className="p-4">
            <div className="flex items-start justify-between gap-3">
              <div className="min-w-0">
                <div className="font-medium text-stone-800">{j.title}</div>
                {j.branchId && (
                  <div className="text-xs text-sky-600 mt-0.5 flex items-center gap-1"><Building2 size={11} /> {branchNameFor(j.branchId) || "-"}</div>
                )}
                <div className="text-xs text-stone-500 mt-1 flex items-center gap-1"><Banknote size={12} /> {j.salaryMin}{j.salaryMax ? `–${j.salaryMax}` : ""} {j.salaryUnit}</div>
                <ul className="mt-2 space-y-0.5">
                  {j.qualifications.map((q, i) => (
                    <li key={i} className="text-xs text-stone-500 flex items-start gap-1.5"><Star size={10} className="text-amber-500 mt-0.5 flex-shrink-0" /> {q}</li>
                  ))}
                </ul>
              </div>
              <button onClick={() => toggleActive(j.id)}
                className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ${j.active ? "bg-emerald-500" : "bg-stone-300"}`}>
                <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${j.active ? "translate-x-5" : "translate-x-0"}`} />
              </button>
            </div>
            <div className="flex flex-wrap items-center gap-2 mt-3 pt-3 border-t border-stone-100">
              <Btn variant="ghost" onClick={() => copyLink(j.id)}><Copy size={13} /> {copiedId === j.id ? "คัดลอกแล้ว ✓" : "คัดลอกลิงก์สมัคร"}</Btn>
              <Btn variant="ghost" onClick={() => setPreviewJob(j)}><Eye size={13} /> ดูตัวอย่างฟอร์มสมัคร</Btn>
              <button onClick={() => removeJob(j.id)} className="text-stone-300 hover:text-rose-500 ml-auto"><Trash2 size={15} /></button>
            </div>
          </Card>
        ))}
      </div>

      {/* Add job popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มตำแหน่งที่เปิดรับ</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-4">
              <Field label="ชื่อตำแหน่ง"><input className={inputCls} value={form.title} onChange={e => setForm({ ...form, title: e.target.value })} placeholder="เช่น พนักงานเสิร์ฟ (Part-time)" autoFocus /></Field>
              <Field label="สถานที่ปฏิบัติงาน">
                <input className={inputCls} value={form.workLocation} onChange={e => setForm({ ...form, workLocation: e.target.value })} placeholder="เช่น สาขาสุขุมวิท 200 ถ.สุขุมวิท กรุงเทพฯ" />
              </Field>
              <Field label="แผนที่ Google Map (ลิงก์)">
                <input className={inputCls} value={form.mapUrl} onChange={e => setForm({ ...form, mapUrl: e.target.value })} placeholder="วางลิงก์จาก Google Maps ที่นี่" />
              </Field>

              <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
                <Field label="เงินเดือนเริ่มต้น"><input type="number" className={inputCls} value={form.salaryMin} onChange={e => setForm({ ...form, salaryMin: e.target.value })} /></Field>
                <Field label="สูงสุด (ถ้ามี)"><input type="number" className={inputCls} value={form.salaryMax} onChange={e => setForm({ ...form, salaryMax: e.target.value })} /></Field>
                <Field label="หน่วย">
                  <select className={inputCls} value={form.salaryUnit} onChange={e => setForm({ ...form, salaryUnit: e.target.value })}>
                    <option>บาท/วัน</option>
                    <option>บาท/เดือน</option>
                    <option>บาท/ชั่วโมง</option>
                  </select>
                </Field>
              </div>

              <div>
                <div className="text-xs font-medium text-stone-500 mb-2">คุณสมบัติ</div>
                <div className="space-y-2">
                  {form.qualifications.map((q, i) => (
                    <div key={i} className="flex items-center gap-2">
                      <input className={inputCls} value={q} onChange={e => updateQual(i, e.target.value)} placeholder="เช่น อายุ 18 ปีขึ้นไป" />
                      <button onClick={() => removeQual(i)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                    </div>
                  ))}
                </div>
                <button onClick={addQual} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2"><Plus size={12} /> เพิ่มคุณสมบัติ</button>
              </div>

              <div>
                <div className="text-xs font-medium text-stone-500 mb-2">ช่องทางติดต่อ</div>
                <div className="space-y-2">
                  {form.contactChannels.map((c, i) => (
                    <div key={i} className="flex items-center gap-2">
                      <select className={`${inputCls} max-w-[140px]`} value={c.type} onChange={e => updateChannel(i, { type: e.target.value })}>
                        {["โทรศัพท์", "LINE", "Facebook", "อีเมล"].map(t => <option key={t}>{t}</option>)}
                      </select>
                      <input className={inputCls} value={c.value} onChange={e => updateChannel(i, { value: e.target.value })} placeholder="ข้อมูลติดต่อ" />
                      <button onClick={() => removeChannel(i)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={16} /></button>
                    </div>
                  ))}
                </div>
                <button onClick={addChannel} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2"><Plus size={12} /> เพิ่มช่องทางติดต่อ</button>
              </div>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submit}>เปิดรับสมัคร</Btn>
          </div>
          </div>
        </div>
      )}

      {/* Application form preview */}
      {previewJob && <JobApplicationPreview job={previewJob} storeInfo={storeInfo} setApplicants={setApplicants} onClose={() => setPreviewJob(null)} />}
    </div>
  );
}

/* =========================================================================
   PAGE: STAFF APPLICANTS
   ========================================================================= */

const APPLICANT_STATUS_STYLE = {
  "รอพิจารณา": "bg-stone-100 text-stone-600 border-stone-300",
  "นัดสัมภาษณ์": "bg-sky-50 text-sky-700 border-sky-300",
  "รับเข้าทำงาน": "bg-emerald-50 text-emerald-700 border-emerald-300",
  "ไม่ผ่าน": "bg-rose-50 text-rose-600 border-rose-300",
};

const STATUS_TABS = ["ทั้งหมด", "รอพิจารณา", "นัดสัมภาษณ์", "รับเข้าทำงาน", "ไม่ผ่าน"];

function ApplicantDecisionPanel({ applicant, positions, onSave, onConvertToStaff }) {
  const [status, setStatusLocal] = useState(applicant.status);
  const [interviewDate, setInterviewDate] = useState(applicant.interviewDate || "");
  const [interviewTime, setInterviewTime] = useState(applicant.interviewTime || "");
  const [interviewNote, setInterviewNote] = useState(applicant.interviewNote || "");
  const [startDate, setStartDate] = useState(applicant.startDate || "");
  const [positionId, setPositionId] = useState(applicant.positionId || positions[0]?.id || "");
  const [salary, setSalary] = useState(applicant.salary || "");
  const [hireNote, setHireNote] = useState(applicant.hireNote || "");
  const [saved, setSaved] = useState(false);

  function save() {
    onSave({ status, interviewDate, interviewTime, interviewNote, startDate, positionId, salary, hireNote });
    setSaved(true);
    setTimeout(() => setSaved(false), 1500);
  }

  return (
    <div className="border-t border-stone-200 mt-4 pt-4">
      <div className="text-sm font-semibold text-stone-700 mb-2">พิจารณาประวัติ</div>
      <div className="flex flex-wrap gap-2 mb-3">
        {Object.keys(APPLICANT_STATUS_STYLE).map(s => (
          <button key={s} onClick={() => { setStatusLocal(s); setSaved(false); }}
            className={`px-3 py-1.5 rounded-md text-xs border font-medium ${status === s ? "bg-stone-900 text-white border-stone-900" : "border-stone-300 text-stone-500"}`}>
            {s}
          </button>
        ))}
      </div>

      {status === "นัดสัมภาษณ์" && (
        <div className="mb-3 space-y-3">
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Field label="วันที่นัดสัมภาษณ์"><input type="date" className={inputCls} value={interviewDate} onChange={e => { setInterviewDate(e.target.value); setSaved(false); }} /></Field>
            <Field label="เวลานัด"><input type="time" className={inputCls} value={interviewTime} onChange={e => { setInterviewTime(e.target.value); setSaved(false); }} /></Field>
          </div>
          <Field label="หมายเหตุ"><input className={inputCls} value={interviewNote} onChange={e => { setInterviewNote(e.target.value); setSaved(false); }} placeholder="เช่น นัดที่ร้าน" /></Field>
        </div>
      )}

      {status === "รับเข้าทำงาน" && (
        <div className="mb-3 space-y-3">
          <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
            <Field label="วันที่เริ่มงาน"><input type="date" className={inputCls} value={startDate} onChange={e => { setStartDate(e.target.value); setSaved(false); }} /></Field>
            <Field label="ตำแหน่ง">
              <select className={inputCls} value={positionId} onChange={e => { setPositionId(e.target.value); setSaved(false); }}>
                {positions.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </Field>
            <Field label="เงินเดือน"><input className={inputCls} value={salary} onChange={e => { setSalary(e.target.value); setSaved(false); }} placeholder="เช่น 12000" /></Field>
          </div>
          <Field label="หมายเหตุ"><input className={inputCls} value={hireNote} onChange={e => { setHireNote(e.target.value); setSaved(false); }} /></Field>
        </div>
      )}

      <div className="flex items-center gap-3 flex-wrap">
        <Btn onClick={save}>บันทึกผลการพิจารณา</Btn>
        {saved && <span className="text-emerald-600 text-xs">บันทึกแล้ว ✓</span>}
      </div>

      {status === "รับเข้าทำงาน" && (
        <div className="mt-4 pt-4 border-t border-stone-200">
          {applicant.hiredStaffId ? (
            <div className="text-sm text-emerald-700 bg-emerald-50 rounded-lg px-3 py-2.5 flex items-center gap-2">
              <CheckCircle2 size={15} /> เพิ่มเป็นพนักงานในระบบแล้ว{applicant.hiredPin ? ` (PIN: ${applicant.hiredPin})` : ""}
            </div>
          ) : (
            <>
              <p className="text-xs text-stone-400 mb-2">เมื่อพร้อมรับเข้าทำงานจริง กดปุ่มนี้เพื่อสร้างบัญชีพนักงาน (พร้อม PIN สำหรับลงเวลา/อนุมัติรายการ) โดยอัตโนมัติจากข้อมูลด้านบน</p>
              <Btn onClick={() => onConvertToStaff({ startDate, positionId, salary })} disabled={!startDate || !positionId}>
                <Users size={14} /> เพิ่มเป็นพนักงานในระบบ
              </Btn>
            </>
          )}
        </div>
      )}
    </div>
  );
}

function StaffApplicantsPage({ applicants, setApplicants, positions, staff, setStaff, ownerProfile }) {
  const [query, setQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState("ทั้งหมด");
  const [viewing, setViewing] = useState(null);
  const [deleteApproval, setDeleteApproval] = useState(null); // { applicantId, applicantName, pin, error }

  const counts = STATUS_TABS.reduce((acc, s) => {
    acc[s] = s === "ทั้งหมด" ? applicants.length : applicants.filter(a => a.status === s).length;
    return acc;
  }, {});

  const filtered = applicants.filter(a => {
    const matchesQuery = a.fullName.includes(query) || a.phone.includes(query) || a.jobTitle.includes(query);
    const matchesStatus = statusFilter === "ทั้งหมด" || a.status === statusFilter;
    return matchesQuery && matchesStatus;
  });

  function saveDecision(id, patch) {
    setApplicants(prev => prev.map(a => a.id === id ? { ...a, ...patch } : a));
    setViewing(prev => prev && prev.id === id ? { ...prev, ...patch } : prev);
  }
  function convertToStaff(applicantId, { startDate, positionId, salary }) {
    const applicant = applicants.find(a => a.id === applicantId);
    if (!applicant) return;
    const newStaffId = "st" + Date.now();
    const pin = generatePin();
    setStaff(prev => [...prev, {
      id: newStaffId, name: applicant.fullName, phone: applicant.phone, positionId,
      pin, startDate: startDate || new Date().toISOString().slice(0, 10), active: true,
      scheduleId: "", weeklyDayOff: "",
      compensation: { ...emptyCompensation(), baseSalary: salary || "" },
    }]);
    setApplicants(prev => prev.map(a => a.id === applicantId ? { ...a, hiredStaffId: newStaffId, hiredPin: pin } : a));
    setViewing(prev => prev && prev.id === applicantId ? { ...prev, hiredStaffId: newStaffId, hiredPin: pin } : prev);
  }
  function requestRemoveApplicant(applicant) {
    setDeleteApproval({ applicantId: applicant.id, applicantName: applicant.fullName, pin: "", error: "" });
  }
  function confirmRemoveApplicant() {
    const manager = (staff || []).find(s => s.pin === deleteApproval.pin && s.active);
    const isOwner = isOwnerPin(ownerProfile, deleteApproval.pin);
    if (!manager && !isOwner) {
      setDeleteApproval(prev => ({ ...prev, error: "PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่" }));
      return;
    }
    if (manager && !isOwner) {
      const position = (positions || []).find(p => p.id === manager.positionId);
      if (!position?.pinPermissions?.includes("applicantDelete")) {
        setDeleteApproval(prev => ({ ...prev, error: `ตำแหน่ง "${position?.name || "-"}" ไม่มีสิทธิ์อนุมัติรายการนี้` }));
        return;
      }
    }
    setApplicants(prev => prev.filter(a => a.id !== deleteApproval.applicantId));
    if (viewing?.id === deleteApproval.applicantId) setViewing(null);
    setDeleteApproval(null);
  }
  function formatAddress(addr) {
    if (!addr) return "-";
    const parts = [addr.houseNo, addr.village, addr.moo ? `หมู่ ${addr.moo}` : "", addr.road, addr.subdistrict, addr.district, addr.province, addr.zipcode].filter(Boolean);
    return parts.length ? parts.join(" ") : "-";
  }

  return (
    <div>
      <PageHeader eyebrow="พนักงาน" title="รายชื่อผู้สมัคร" subtitle="รายชื่อผู้สมัครงานทั้งหมดที่ส่งใบสมัครเข้ามา" />

      <div className="flex gap-2 mb-4 border-b border-stone-200 overflow-x-auto">
        {STATUS_TABS.map(s => (
          <button key={s} onClick={() => setStatusFilter(s)}
            className={`px-3 py-2 text-sm font-medium border-b-2 -mb-px transition-colors
            ${statusFilter === s ? "border-amber-600 text-amber-800" : "border-transparent text-stone-500 hover:text-stone-700"}`}>
            {s} <span className="text-xs text-stone-400">({counts[s]})</span>
          </button>
        ))}
      </div>

      <div className="relative mb-4 max-w-lg">
        <Search size={18} className="absolute left-3.5 top-3 text-stone-400" />
        <input className={`${inputCls} pl-10 py-2.5 text-base`} placeholder="ค้นหาชื่อ, เบอร์โทร หรือตำแหน่งที่สมัคร" value={query} onChange={e => setQuery(e.target.value)} />
      </div>

      <Card>
        <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
              <th className="px-4 py-3 font-medium">{statusFilter === "นัดสัมภาษณ์" ? "วันที่นัด / เวลานัด" : "วันที่สมัคร"}</th>
              <th className="px-4 py-3 font-medium">ชื่อผู้สมัคร</th>
              <th className="px-4 py-3 font-medium">ตำแหน่งที่สมัคร</th>
              <th className="px-4 py-3 font-medium">เบอร์โทร</th>
              <th className="px-4 py-3 font-medium">สถานะ</th>
              <th className="px-4 py-3 font-medium"></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && (
              <tr><td colSpan={6} className="px-4 py-10 text-center text-stone-400">ไม่มีผู้สมัครงานในหมวดนี้</td></tr>
            )}
            {filtered.map(a => (
              <tr key={a.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                <td className="px-4 py-3 text-stone-400">
                  {statusFilter === "นัดสัมภาษณ์"
                    ? (a.interviewDate ? `${fmtDate(a.interviewDate)}${a.interviewTime ? ` / ${a.interviewTime} น.` : ""}` : "-")
                    : fmtDate(a.appliedDate)}
                </td>
                <td className="px-4 py-3 font-medium text-stone-800">{a.fullName}{a.nickname ? <span className="text-stone-400 font-normal"> ({a.nickname})</span> : ""}</td>
                <td className="px-4 py-3 text-stone-600">{a.jobTitle}</td>
                <td className="px-4 py-3 text-stone-500">{a.phone}</td>
                <td className="px-4 py-3">
                  <span className={`text-xs px-2 py-0.5 rounded border font-medium ${APPLICANT_STATUS_STYLE[a.status] || APPLICANT_STATUS_STYLE["รอพิจารณา"]}`}>{a.status}</span>
                </td>
                <td className="px-4 py-3 text-right">
                  <div className="flex items-center justify-end gap-3">
                    <button onClick={() => setViewing(a)} className="text-stone-400 hover:text-amber-700"><Eye size={15} /></button>
                    <button onClick={() => requestRemoveApplicant(a)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        </div>
      </Card>

      {/* Applicant detail modal */}
      {viewing && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setViewing(null)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800 text-lg">{viewing.fullName} {viewing.nickname && <span className="text-stone-400 text-sm font-normal">({viewing.nickname})</span>}</div>
              <button onClick={() => setViewing(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="text-sm text-stone-500 mb-4">สมัครตำแหน่ง: <span className="font-medium text-stone-700">{viewing.jobTitle}</span></div>

            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm mb-4">
              <div><span className="text-stone-400">วันเดือนปีเกิด:</span> {viewing.birthday ? fmtDate(viewing.birthday) : "-"}</div>
              <div><span className="text-stone-400">เลขบัตรประชาชน:</span> {viewing.nationalId || "-"}</div>
              <div><span className="text-stone-400">เบอร์โทร:</span> {viewing.phone}</div>
              <div><span className="text-stone-400">E-mail:</span> {viewing.email || "-"}</div>
              <div><span className="text-stone-400">LINE ID:</span> {viewing.lineId || "-"}</div>
              <div><span className="text-stone-400">วันที่สมัคร:</span> {fmtDate(viewing.appliedDate)}</div>
            </div>

            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1">ที่อยู่ปัจจุบัน</div>
            <div className="text-sm text-stone-600 mb-3">{formatAddress(viewing.currentAddress)}</div>

            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1">ที่อยู่ตามทะเบียนบ้าน</div>
            <div className="text-sm text-stone-600 mb-3">{formatAddress(viewing.houseRegAddress)}</div>

            <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5">ประวัติการทำงาน</div>
            <div className="space-y-2 mb-4">
              {(viewing.workHistory || []).filter(w => w.company).length === 0 && <div className="text-sm text-stone-400">ไม่มีข้อมูล</div>}
              {(viewing.workHistory || []).filter(w => w.company).map((w, i) => (
                <div key={i} className="p-2.5 rounded-lg border border-stone-200 text-sm">
                  <div className="font-medium text-stone-800">{w.company} · {w.position}</div>
                  <div className="text-xs text-stone-400">{fmtDate(w.startDate)} ถึง {w.endDate ? fmtDate(w.endDate) : "ปัจจุบัน"} · เงินเดือน {w.salary}</div>
                  {w.description && <div className="text-xs text-stone-500 mt-1">{w.description}</div>}
                </div>
              ))}
            </div>

            <ApplicantDecisionPanel key={viewing.id} applicant={viewing} positions={positions} onSave={patch => saveDecision(viewing.id, patch)} onConvertToStaff={payload => convertToStaff(viewing.id, payload)} />
          </div>
          </div>
        </div>
      )}

      {/* PIN approval required to delete an applicant */}
      {deleteApproval && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setDeleteApproval(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 flex items-center gap-2"><ShieldCheck size={17} className="text-amber-600" /> ขออนุมัติลบผู้สมัคร</div>
              <button onClick={() => setDeleteApproval(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-500 mt-2 mb-4">ลบ "{deleteApproval.applicantName}" ออกจากรายชื่อผู้สมัคร</div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} autoFocus className={inputCls}
                value={deleteApproval.pin} onChange={e => setDeleteApproval(prev => ({ ...prev, pin: e.target.value.replace(/\D/g, "").slice(0, 6), error: "" }))}
                placeholder="••••••" />
            </Field>
            {deleteApproval.error && <div className="text-xs text-rose-500 mt-1.5">{deleteApproval.error}</div>}
            <Btn className="w-full justify-center mt-4" disabled={deleteApproval.pin.length !== 6} onClick={confirmRemoveApplicant}>ยืนยันลบ</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   SHARED: THAI ADDRESS FIELDS
   ========================================================================= */

function emptyThaiAddress() {
  return { houseNo: "", village: "", moo: "", road: "", province: "", district: "", subdistrict: "", zipcode: "" };
}

function AddressFields({ value, onChange, addressData, loading, disabled }) {
  function set(patch) { onChange({ ...value, ...patch }); }

  const provinceNames = addressData ? addressData.map(p => p.name_th) : THAI_PROVINCES;
  const provinceObj = addressData?.find(p => p.name_th === value.province);
  const liveDistricts = provinceObj?.districts || [];
  const districtObj = liveDistricts.find(d => d.name_th === value.district);
  const liveSubdistricts = districtObj?.sub_districts || [];

  // Fall back to the small static sample if the live dataset hasn't loaded (e.g. offline)
  const districts = addressData ? liveDistricts.map(d => d.name_th) : (value.province ? (THAI_DISTRICTS[value.province] || []) : []);
  const subdistricts = addressData ? liveSubdistricts.map(s => s.name_th) : (value.district ? (THAI_SUBDISTRICTS[value.district] || []) : []);

  function selectSubdistrict(name) {
    const match = liveSubdistricts.find(s => s.name_th === name);
    set({ subdistrict: name, zipcode: match?.zip_code ? String(match.zip_code) : value.zipcode });
  }

  return (
    <div className={`space-y-3 ${disabled ? "opacity-60" : ""}`}>
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
        <Field label="เลขที่"><input className={inputCls} value={value.houseNo} onChange={e => set({ houseNo: e.target.value })} disabled={disabled} /></Field>
        <Field label="หมู่บ้าน / อาคาร"><input className={inputCls} value={value.village} onChange={e => set({ village: e.target.value })} disabled={disabled} /></Field>
        <Field label="หมู่ที่"><input className={inputCls} value={value.moo} onChange={e => set({ moo: e.target.value })} disabled={disabled} /></Field>
      </div>
      <Field label="ถนน"><input className={inputCls} value={value.road} onChange={e => set({ road: e.target.value })} disabled={disabled} /></Field>
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
        <Field label="จังหวัด">
          <select className={inputCls} value={value.province} onChange={e => set({ province: e.target.value, district: "", subdistrict: "", zipcode: "" })} disabled={disabled}>
            <option value="">เลือกจังหวัด</option>
            {provinceNames.map(p => <option key={p} value={p}>{p}</option>)}
          </select>
        </Field>
        <Field label="เขต / อำเภอ">
          <select className={inputCls} value={value.district} onChange={e => set({ district: e.target.value, subdistrict: "", zipcode: "" })} disabled={disabled || !value.province}>
            <option value="">{!value.province ? "เลือกจังหวัดก่อน" : loading && !addressData ? "กำลังโหลดข้อมูล..." : "เลือกเขต/อำเภอ"}</option>
            {districts.map(d => <option key={d} value={d}>{d}</option>)}
          </select>
        </Field>
        <Field label="แขวง / ตำบล">
          {subdistricts.length > 0 ? (
            <select className={inputCls} value={value.subdistrict} onChange={e => selectSubdistrict(e.target.value)} disabled={disabled}>
              <option value="">เลือกแขวง/ตำบล</option>
              {subdistricts.map(s => <option key={s} value={s}>{s}</option>)}
            </select>
          ) : (
            <input className={inputCls} value={value.subdistrict} onChange={e => set({ subdistrict: e.target.value })}
              placeholder={value.district ? "พิมพ์แขวง/ตำบล" : "เลือกเขต/อำเภอก่อน"} disabled={disabled || !value.district} />
          )}
        </Field>
      </div>
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
        <Field label="รหัสไปรษณีย์">
          <input className={inputCls} value={value.zipcode} onChange={e => set({ zipcode: e.target.value.replace(/\D/g, "").slice(0, 5) })} placeholder="เช่น 10110" inputMode="numeric" disabled={disabled} />
        </Field>
      </div>
    </div>
  );
}

/* =========================================================================
   JOB APPLICATION FORM PREVIEW
   ========================================================================= */

function JobApplicationPreview({ job, storeInfo, setApplicants, onClose, isPreview = true }) {
  const [fullName, setFullName] = useState("");
  const [nickname, setNickname] = useState("");
  const [birthday, setBirthday] = useState("");
  const [nationalId, setNationalId] = useState("");
  const [phone, setPhone] = useState("");
  const [email, setEmail] = useState("");
  const [lineId, setLineId] = useState("");
  const [currentAddress, setCurrentAddress] = useState(emptyThaiAddress());
  const [sameAsCurrent, setSameAsCurrent] = useState(false);
  const [houseRegAddress, setHouseRegAddress] = useState(emptyThaiAddress());
  const [workHistory, setWorkHistory] = useState([{ startDate: "", endDate: "", company: "", position: "", salary: "", description: "" }]);
  const [submitted, setSubmitted] = useState(false);
  const [addressData, setAddressData] = useState(null);
  const [addressLoading, setAddressLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    fetch("https://raw.githubusercontent.com/kongvut/thai-province-data/master/api/latest/province_with_district_and_sub_district.json")
      .then(r => r.json())
      .then(data => { if (!cancelled) { setAddressData(data); setAddressLoading(false); } })
      .catch(() => { if (!cancelled) setAddressLoading(false); }); // falls back to the small static sample
    return () => { cancelled = true; };
  }, []);

  function toggleSameAsCurrent(checked) {
    setSameAsCurrent(checked);
    if (checked) setHouseRegAddress({ ...currentAddress });
  }
  function submitApplication() {
    if (!fullName.trim() || !phone.trim()) return;
    setApplicants(prev => [{
      id: "app" + Date.now(),
      jobTitle: job.title,
      fullName: fullName.trim(), nickname: nickname.trim(), birthday, nationalId,
      phone: phone.trim(), email: email.trim(), lineId: lineId.trim(),
      currentAddress, houseRegAddress, workHistory,
      appliedDate: new Date().toISOString().slice(0, 10), status: "รอพิจารณา",
    }, ...prev]);
    setSubmitted(true);
  }
  function updateWork(i, patch) {
    setWorkHistory(prev => prev.map((w, idx) => idx === i ? { ...w, ...patch } : w));
  }
  function addWork() {
    setWorkHistory(prev => [...prev, { startDate: "", endDate: "", company: "", position: "", salary: "", description: "" }]);
  }
  function removeWork(i) {
    setWorkHistory(prev => prev.filter((_, idx) => idx !== i));
  }

  return (
    <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={onClose}>
      <div className="min-h-full flex items-start justify-center py-8">
      <div className="bg-white rounded-xl w-full max-w-2xl p-6" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          {isPreview ? (
            <span className="text-[10px] px-2 py-0.5 rounded-full bg-stone-100 text-stone-400 uppercase tracking-wide">ตัวอย่างหน้าที่ผู้สมัครเห็น</span>
          ) : <span />}
          <button onClick={onClose} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
        </div>

        <div className="flex items-center gap-3 mb-4">
          <img src={storeInfo.logoDataUrl || LOGO_DATA_URI} alt="logo" className="w-12 h-12 rounded-full object-cover" />
          <div>
            <div className="font-serif text-lg text-stone-900">{storeInfo.name}</div>
            <div className="text-xs text-stone-400">{storeInfo.tagline}</div>
          </div>
        </div>

        <div className="font-semibold text-stone-800 text-lg">{job.title}</div>
        <div className="text-sm text-stone-500 mt-1 flex items-center gap-1"><Banknote size={13} /> {job.salaryMin}{job.salaryMax ? `–${job.salaryMax}` : ""} {job.salaryUnit}</div>

        <div className="mt-3">
          <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5">คุณสมบัติ</div>
          <ul className="space-y-1">
            {job.qualifications.map((q, i) => (
              <li key={i} className="text-sm text-stone-600 flex items-start gap-1.5"><Star size={12} className="text-amber-500 mt-1 flex-shrink-0" /> {q}</li>
            ))}
          </ul>
        </div>

        <div className="border-t border-stone-100 mt-4 pt-4 space-y-4">
          <div className="text-sm font-semibold text-stone-700">ข้อมูลผู้สมัคร</div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <Field label="ชื่อ-นามสกุล"><input className={inputCls} value={fullName} onChange={e => setFullName(e.target.value)} placeholder="ชื่อ นามสกุล" /></Field>
            <Field label="ชื่อเล่น"><input className={inputCls} value={nickname} onChange={e => setNickname(e.target.value)} /></Field>
            <Field label="วันเดือนปีเกิด"><input type="date" className={inputCls} value={birthday} onChange={e => setBirthday(e.target.value)} /></Field>
            <Field label="เลขบัตรประจำตัวประชาชน"><input className={inputCls} value={nationalId} onChange={e => setNationalId(e.target.value.replace(/\D/g, "").slice(0, 13))} placeholder="เลข 13 หลัก" /></Field>
            <Field label="เบอร์โทรศัพท์"><input className={inputCls} value={phone} onChange={e => setPhone(e.target.value)} placeholder="08x-xxx-xxxx" /></Field>
            <Field label="E-mail"><input type="email" className={inputCls} value={email} onChange={e => setEmail(e.target.value)} placeholder="name@email.com" /></Field>
            <Field label="LINE ID"><input className={inputCls} value={lineId} onChange={e => setLineId(e.target.value)} placeholder="เช่น @yourline" /></Field>
          </div>

          <div>
            <div className="text-sm font-semibold text-stone-700 mb-2">ที่อยู่ปัจจุบัน{addressLoading && <span className="text-xs font-normal text-stone-400 ml-2">(กำลังโหลดข้อมูลจังหวัด/อำเภอ/ตำบล...)</span>}</div>
            <AddressFields value={currentAddress} onChange={v => { setCurrentAddress(v); if (sameAsCurrent) setHouseRegAddress(v); }} addressData={addressData} loading={addressLoading} />
          </div>

          <div>
            <div className="flex items-center justify-between mb-2">
              <div className="text-sm font-semibold text-stone-700">ที่อยู่ตามทะเบียนบ้าน</div>
              <label className="flex items-center gap-1.5 text-xs font-medium text-amber-700 cursor-pointer select-none">
                <input type="checkbox" checked={sameAsCurrent} onChange={e => toggleSameAsCurrent(e.target.checked)} />
                ใช้ที่อยู่เดียวกับที่อยู่ปัจจุบัน
              </label>
            </div>
            <AddressFields value={houseRegAddress} onChange={v => { setHouseRegAddress(v); if (!sameAsCurrent) { /* editing independently */ } }} addressData={addressData} loading={addressLoading} disabled={sameAsCurrent} />
          </div>

          <div>
            <div className="text-sm font-semibold text-stone-700 mb-2">ประวัติการทำงาน</div>
            <div className="space-y-3">
              {workHistory.map((w, i) => (
                <div key={i} className="p-3 rounded-lg border border-stone-200 space-y-2">
                  <div className="flex items-center justify-between">
                    <span className="text-xs font-medium text-stone-500">งานที่ {i + 1}</span>
                    {workHistory.length > 1 && <button onClick={() => removeWork(i)} className="text-stone-300 hover:text-rose-500"><X size={14} /></button>}
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                    <Field label="วันที่เริ่มงาน"><input type="date" className={inputCls} value={w.startDate} onChange={e => updateWork(i, { startDate: e.target.value })} /></Field>
                    <Field label="วันทำงานวันสุดท้าย"><input type="date" className={inputCls} value={w.endDate} onChange={e => updateWork(i, { endDate: e.target.value })} /></Field>
                    <Field label="บริษัท"><input className={inputCls} value={w.company} onChange={e => updateWork(i, { company: e.target.value })} /></Field>
                    <Field label="ตำแหน่ง"><input className={inputCls} value={w.position} onChange={e => updateWork(i, { position: e.target.value })} /></Field>
                    <Field label="เงินเดือน"><input className={inputCls} value={w.salary} onChange={e => updateWork(i, { salary: e.target.value })} /></Field>
                  </div>
                  <Field label="รายละเอียดงาน"><textarea rows={2} className={inputCls} value={w.description} onChange={e => updateWork(i, { description: e.target.value })} /></Field>
                </div>
              ))}
            </div>
            <button onClick={addWork} className="text-xs font-medium text-amber-700 hover:text-amber-900 flex items-center gap-1 mt-2"><Plus size={12} /> เพิ่มประวัติการทำงาน</button>
          </div>

          <Field label="แนบเรซูเม่ (ถ้ามี)"><input type="file" className={`${inputCls} py-1.5`} /></Field>

          {submitted ? (
            <div className="text-center py-4">
              <CheckCircle2 size={32} className="text-emerald-500 mx-auto mb-2" />
              <div className="text-sm font-medium text-stone-800">ส่งใบสมัครเรียบร้อยแล้ว</div>
              <div className="text-xs text-stone-400 mt-1">ทางร้านจะติดต่อกลับตามช่องทางที่ให้ไว้เร็วๆ นี้</div>
            </div>
          ) : (
            <Btn className="w-full justify-center" disabled={!fullName.trim() || !phone.trim()} onClick={submitApplication}>ส่งใบสมัคร</Btn>
          )}
        </div>

        <div className="text-xs text-stone-400 mt-4">
          <div className="font-medium text-stone-500 mb-1">ช่องทางติดต่อสอบถาม</div>
          {job.contactChannels.map((c, i) => <div key={i}>{c.type}: {c.value}</div>)}
        </div>
      </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: STOCK MANAGEMENT — หมวดหมู่สินค้า
   ========================================================================= */

function StockCategoriesPage({ stockCategories, setStockCategories, stockUnits, setStockUnits, stockItems, setStockItems }) {
  const [catName, setCatName] = useState("");
  const [editingCatId, setEditingCatId] = useState(null);
  const [unitName, setUnitName] = useState("");
  const [editingUnitId, setEditingUnitId] = useState(null);
  const [showCatForm, setShowCatForm] = useState(false);
  const [showUnitForm, setShowUnitForm] = useState(false);

  function openAddCategory() {
    setCatName("");
    setEditingCatId(null);
    setShowCatForm(true);
  }
  function startEditCategory(cat) {
    setCatName(cat.name);
    setEditingCatId(cat.id);
    setShowCatForm(true);
  }
  function saveCategory() {
    if (!catName.trim()) return;
    if (editingCatId) {
      const oldCat = stockCategories.find(c => c.id === editingCatId);
      setStockCategories(prev => prev.map(c => c.id === editingCatId ? { ...c, name: catName.trim() } : c));
      if (oldCat && oldCat.name !== catName.trim() && setStockItems) {
        setStockItems(prev => prev.map(s => s.category === oldCat.name ? { ...s, category: catName.trim() } : s));
      }
    } else {
      setStockCategories(prev => [...prev, { id: "sc" + Date.now(), name: catName.trim() }]);
    }
    setShowCatForm(false);
  }
  function removeCategory(cat) {
    setStockCategories(prev => prev.filter(c => c.id !== cat.id));
  }
  function countCategoryInUse(cat) {
    return stockItems.filter(s => s.category === cat.name).length;
  }

  function openAddUnit() {
    setUnitName("");
    setEditingUnitId(null);
    setShowUnitForm(true);
  }
  function startEditUnit(u) {
    setUnitName(u.name);
    setEditingUnitId(u.id);
    setShowUnitForm(true);
  }
  function saveUnit() {
    if (!unitName.trim()) return;
    if (editingUnitId) {
      const oldUnit = stockUnits.find(u => u.id === editingUnitId);
      setStockUnits(prev => prev.map(u => u.id === editingUnitId ? { ...u, name: unitName.trim() } : u));
      if (oldUnit && oldUnit.name !== unitName.trim() && setStockItems) {
        setStockItems(prev => prev.map(s => s.unit === oldUnit.name ? { ...s, unit: unitName.trim() } : s));
      }
    } else {
      setStockUnits(prev => [...prev, { id: "su" + Date.now(), name: unitName.trim() }]);
    }
    setShowUnitForm(false);
  }
  function removeUnit(u) {
    setStockUnits(prev => prev.filter(x => x.id !== u.id));
  }
  function countUnitInUse(u) {
    return stockItems.filter(s => s.unit === u.name).length;
  }

  return (
    <div>
      <PageHeader eyebrow="การจัดการสต๊อก" title="หมวดหมู่สินค้า" subtitle="จัดกลุ่มหมวดหมู่สินค้าและวัตถุดิบ" />
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
        {/* Left: categories */}
        <div>
          <div className="flex items-center justify-between mb-3">
            <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase">หมวดหมู่ที่มี ({stockCategories.length})</div>
            <Btn onClick={openAddCategory}><Plus size={14} /> เพิ่มหมวดหมู่</Btn>
          </div>
          <div className="space-y-2">
            {stockCategories.map(c => {
              const inUse = countCategoryInUse(c);
              return (
                <div key={c.id} className="flex items-center justify-between p-3 rounded-lg border border-stone-200 bg-white">
                  <div className="flex items-center gap-2 min-w-0">
                    <Boxes size={15} className="text-amber-600 flex-shrink-0" />
                    <span className="text-sm font-medium text-stone-800 truncate">{c.name}</span>
                    <span className="text-[11px] text-stone-400 flex-shrink-0">{inUse} รายการ</span>
                  </div>
                  <div className="flex items-center gap-3 flex-shrink-0">
                    <button onClick={() => startEditCategory(c)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
                    <button onClick={() => removeCategory(c)} disabled={inUse > 0} title={inUse > 0 ? "ยังมีสินค้าใช้หมวดหมู่นี้อยู่" : "ลบหมวดหมู่"}
                      className={inUse > 0 ? "text-stone-200 cursor-not-allowed" : "text-stone-300 hover:text-rose-500"}>
                      <Trash2 size={14} />
                    </button>
                  </div>
                </div>
              );
            })}
            {stockCategories.length === 0 && (
              <div className="text-sm text-stone-400 text-center py-10 border border-dashed border-stone-300 rounded-lg">ยังไม่มีหมวดหมู่สินค้า</div>
            )}
          </div>
        </div>

        {/* Right: units */}
        <div>
          <div className="flex items-center justify-between mb-3">
            <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase">หน่วยนับที่มี ({stockUnits.length})</div>
            <Btn onClick={openAddUnit}><Plus size={14} /> เพิ่มหน่วยนับ</Btn>
          </div>
          <div className="grid grid-cols-2 gap-2">
            {stockUnits.map(u => {
              const inUse = countUnitInUse(u);
              return (
                <div key={u.id} className="flex items-center justify-between p-3 rounded-lg border border-stone-200 bg-white">
                  <div className="flex items-center gap-2 min-w-0">
                    <span className="text-sm font-medium text-stone-800 truncate">{u.name}</span>
                    <span className="text-[11px] text-stone-400 flex-shrink-0">{inUse}</span>
                  </div>
                  <div className="flex items-center gap-3 flex-shrink-0">
                    <button onClick={() => startEditUnit(u)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
                    <button onClick={() => removeUnit(u)} disabled={inUse > 0} title={inUse > 0 ? "ยังมีสินค้าใช้หน่วยนับนี้อยู่" : "ลบหน่วยนับ"}
                      className={inUse > 0 ? "text-stone-200 cursor-not-allowed" : "text-stone-300 hover:text-rose-500"}>
                      <Trash2 size={14} />
                    </button>
                  </div>
                </div>
              );
            })}
            {stockUnits.length === 0 && (
              <div className="col-span-2 text-sm text-stone-400 text-center py-10 border border-dashed border-stone-300 rounded-lg">ยังไม่มีหน่วยนับ</div>
            )}
          </div>
        </div>
      </div>

      {/* Add category popup */}
      {showCatForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowCatForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{editingCatId ? "แก้ไขหมวดหมู่" : "เพิ่มหมวดหมู่"}</div>
              <button onClick={() => setShowCatForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <Field label="ชื่อหมวดหมู่"><input className={inputCls} placeholder="เช่น เนื้อสัตว์" value={catName} onChange={e => setCatName(e.target.value)} onKeyDown={e => e.key === "Enter" && saveCategory()} autoFocus /></Field>
            <Btn className="w-full justify-center mt-4" onClick={saveCategory}>{editingCatId ? "บันทึกการแก้ไข" : <><Plus size={14} /> เพิ่มหมวดหมู่</>}</Btn>
          </div>
        </div>
      )}

      {/* Add unit popup */}
      {showUnitForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowUnitForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{editingUnitId ? "แก้ไขหน่วยนับ" : "เพิ่มหน่วยนับ"}</div>
              <button onClick={() => setShowUnitForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <Field label="ชื่อหน่วยนับ"><input className={inputCls} placeholder="เช่น ลูก" value={unitName} onChange={e => setUnitName(e.target.value)} onKeyDown={e => e.key === "Enter" && saveUnit()} autoFocus /></Field>
            <Btn className="w-full justify-center mt-4" onClick={saveUnit}>{editingUnitId ? "บันทึกการแก้ไข" : <><Plus size={14} /> เพิ่มหน่วยนับ</>}</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: STOCK MANAGEMENT — สินค้า
   ========================================================================= */

function StockItemsPage({ stockItems, setStockItems, stockCategories, stockUnits, currentBranchId, branches, vendors, staff, ownerProfile, logActivity }) {
  const [query, setQuery] = useState("");
  const [categoryFilter, setCategoryFilter] = useState("");
  const [showForm, setShowForm] = useState(false);
  const [deletingItem, setDeletingItem] = useState(null);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const emptyForm = { name: "", category: stockCategories[0]?.name || "", unit: stockUnits[0]?.name || "", currentStock: "", minStock: "", costPerUnit: "", supplier: "" };
  const [form, setForm] = useState(emptyForm);

  const branchName = branches?.find(b => b.id === effectiveBranchId)?.name;

  const filtered = stockItems
    .filter(s => {
      const matchesQuery = s.name.includes(query) || s.supplier.includes(query);
      const matchesCategory = !categoryFilter || s.category === categoryFilter;
      return matchesQuery && matchesCategory;
    })
    .sort((a, b) => {
      const aLow = stockQtyFor(a, effectiveBranchId) <= stockMinFor(a, effectiveBranchId) ? 0 : 1;
      const bLow = stockQtyFor(b, effectiveBranchId) <= stockMinFor(b, effectiveBranchId) ? 0 : 1;
      return aLow - bLow;
    });
  const lowStockCount = stockItems.filter(s => stockQtyFor(s, effectiveBranchId) <= stockMinFor(s, effectiveBranchId)).length;

  function openForm() {
    setForm(emptyForm);
    setShowForm(true);
  }
  function startEdit(s) {
    setForm({
      id: s.id, name: s.name, category: s.category, unit: s.unit,
      currentStock: String(stockQtyFor(s, effectiveBranchId)), minStock: String(stockMinFor(s, effectiveBranchId)),
      costPerUnit: String(s.costPerUnit), supplier: s.supplier,
    });
    setShowForm(true);
  }
  function submit() {
    if (!form.name) return;
    const qty = Number(form.currentStock) || 0;
    const min = Number(form.minStock) || 0;
    if (form.id) {
      setStockItems(prev => prev.map(s => {
        if (s.id !== form.id) return s;
        const shared = { name: form.name, category: form.category, unit: form.unit, costPerUnit: Number(form.costPerUnit) || 0, supplier: form.supplier };
        if (!effectiveBranchId) return { ...s, ...shared, currentStock: qty, minStock: min };
        return { ...s, ...shared, branchStock: { ...s.branchStock, [effectiveBranchId]: { currentStock: qty, minStock: min } } };
      }));
    } else {
      const payload = {
        id: "st" + Date.now(), name: form.name, category: form.category, unit: form.unit,
        costPerUnit: Number(form.costPerUnit) || 0, supplier: form.supplier,
        currentStock: effectiveBranchId ? 0 : qty, minStock: effectiveBranchId ? 0 : min,
        branchStock: effectiveBranchId ? { [effectiveBranchId]: { currentStock: qty, minStock: min } } : {},
      };
      setStockItems(prev => [...prev, payload]);
    }
    setShowForm(false);
  }
  function removeItem(id) {
    setStockItems(prev => prev.filter(s => s.id !== id));
  }

  const exportRows = stockItems.map(s => ({
    "หมวดหมู่": s.category, "ชื่อสินค้า": s.name, "จำนวนคงเหลือ": stockQtyFor(s, effectiveBranchId), "หน่วยนับ": s.unit,
    "จำนวนขั้นต่ำ": stockMinFor(s, effectiveBranchId), "ต้นทุนต่อหน่วย": s.costPerUnit, "มูลค่ารวม": stockQtyFor(s, effectiveBranchId) * s.costPerUnit, "ผู้จำหน่าย": s.supplier,
  }));

  return (
    <div>
      <PageHeader eyebrow="การจัดการสต๊อก" title="สินค้า" subtitle={branchName ? `รายการสินค้าและวัตถุดิบคงคลังของสาขา${branchName}` : "รายการสินค้าและวัตถุดิบคงคลังทั้งหมด (เลือกสาขาเพื่อดู/แก้ไขจำนวนเฉพาะสาขา)"}
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา (ค่ากลาง)</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <ExportButton data={exportRows} filename="รายการสินค้า" sheetName="Stock" />
            <Btn onClick={openForm}><Plus size={14} /> เพิ่มสินค้าใหม่</Btn>
          </div>
        } />

      <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mb-5">
        <Card className="p-4">
          <div className="text-xs text-stone-400">สินค้าทั้งหมด</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{stockItems.length}</div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center gap-1.5 text-xs text-stone-400">
            <AlertTriangle size={13} className={lowStockCount > 0 ? "text-rose-500" : "text-stone-300"} />
            ใกล้หมด / ต้องสั่งเพิ่ม
          </div>
          <div className={`text-2xl font-serif mt-1 ${lowStockCount > 0 ? "text-rose-600" : "text-stone-900"}`}>{lowStockCount}</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">มูลค่าสต๊อกรวมโดยประมาณ</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(stockItems.reduce((s, it) => s + stockQtyFor(it, effectiveBranchId) * it.costPerUnit, 0))}</div>
        </Card>
      </div>

      <div className="flex flex-wrap items-center gap-3 mb-4">
        <div className="relative max-w-md flex-1">
          <Search size={18} className="absolute left-3.5 top-3 text-stone-400" />
          <input className={`${inputCls} pl-10 py-2.5 text-base`} placeholder="ค้นหาชื่อสินค้า หรือผู้จำหน่าย" value={query} onChange={e => setQuery(e.target.value)} />
        </div>
        <select className={`${inputCls} max-w-[220px] py-2.5 text-base`} value={categoryFilter} onChange={e => setCategoryFilter(e.target.value)}>
          <option value="">ทุกหมวดหมู่</option>
          {stockCategories.map(c => <option key={c.id} value={c.name}>{c.name}</option>)}
        </select>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">หมวดหมู่อาหาร</th>
                <th className="px-4 py-3 font-medium">ชื่อสินค้า</th>
                <th className="px-4 py-3 font-medium">จำนวนคงเหลือ{branchName ? ` (${branchName})` : ""}</th>
                <th className="px-4 py-3 font-medium">หน่วยนับ</th>
                <th className="px-4 py-3 font-medium">ต้นทุนต่อหน่วย</th>
                <th className="px-4 py-3 font-medium">มูลค่ารวม</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(s => {
                const qty = stockQtyFor(s, effectiveBranchId);
                const min = stockMinFor(s, effectiveBranchId);
                const isLow = qty <= min;
                return (
                  <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 text-stone-500">{s.category}</td>
                    <td className="px-4 py-3 font-medium text-stone-800">
                      <div className="flex items-center gap-2">
                        {s.name}
                        {isLow && (
                          <span className="text-[10px] px-1.5 py-0.5 rounded bg-rose-50 text-rose-600 border border-rose-200 flex items-center gap-1 flex-shrink-0">
                            <AlertTriangle size={10} /> ใกล้หมด
                          </span>
                        )}
                      </div>
                    </td>
                    <td className={`px-4 py-3 font-mono ${isLow ? "text-rose-600 font-semibold" : "text-stone-700"}`}>{qty}</td>
                    <td className="px-4 py-3 text-stone-500">{s.unit}</td>
                    <td className="px-4 py-3 font-mono text-stone-600">฿{fmtMoney(s.costPerUnit)}</td>
                    <td className="px-4 py-3 font-mono text-stone-800">฿{fmtMoney(qty * s.costPerUnit)}</td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-2">
                        <button onClick={() => startEdit(s)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                        <button onClick={() => setDeletingItem(s)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {filtered.length === 0 && (
                <tr><td colSpan={7} className="px-4 py-10 text-center text-stone-400">ไม่พบสินค้าที่ค้นหา</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Add / edit stock item popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขสินค้า" : "เพิ่มสินค้าใหม่"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อสินค้า"><input className={inputCls} value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="เช่น หมูสับ" autoFocus /></Field>

              <div className="grid grid-cols-2 gap-3">
                <Field label="หมวดหมู่">
                  <select className={inputCls} value={form.category} onChange={e => setForm({ ...form, category: e.target.value })}>
                    {stockCategories.map(c => <option key={c.id} value={c.name}>{c.name}</option>)}
                  </select>
                </Field>
                <Field label="หน่วยนับ">
                  <select className={inputCls} value={form.unit} onChange={e => setForm({ ...form, unit: e.target.value })}>
                    {stockUnits.map(u => <option key={u.id} value={u.name}>{u.name}</option>)}
                  </select>
                </Field>
              </div>

              <div className="grid grid-cols-2 gap-3">
                <Field label={`จำนวนคงเหลือ${branchName ? ` (${branchName})` : ""}`}><input type="number" step="any" className={inputCls} value={form.currentStock} onChange={e => setForm({ ...form, currentStock: e.target.value })} placeholder="0" /></Field>
                <Field label="จำนวนขั้นต่ำ (แจ้งเตือน)"><input type="number" step="any" className={inputCls} value={form.minStock} onChange={e => setForm({ ...form, minStock: e.target.value })} placeholder="0" /></Field>
              </div>
              {branchName && <p className="text-[11px] text-stone-400 -mt-1">ชื่อ/หน่วย/ต้นทุน/ผู้จำหน่ายใช้ร่วมกันทุกสาขา ส่วนจำนวนคงเหลือ/ขั้นต่ำแยกเฉพาะสาขานี้</p>}

              <div className="grid grid-cols-2 gap-3">
                <Field label="ต้นทุนต่อหน่วย (บาท)"><input type="number" className={inputCls} value={form.costPerUnit} onChange={e => setForm({ ...form, costPerUnit: e.target.value })} placeholder="0" /></Field>
                <Field label="ผู้จำหน่าย">
                  {vendors && vendors.length > 0 ? (
                    <select className={inputCls} value={form.supplier} onChange={e => setForm({ ...form, supplier: e.target.value })}>
                      <option value="">-- เลือกผู้จำหน่าย --</option>
                      {vendors.map(v => <option key={v.id} value={v.businessName || v.contactPersonName}>{v.businessName || v.contactPersonName}</option>)}
                    </select>
                  ) : (
                    <input className={inputCls} value={form.supplier} onChange={e => setForm({ ...form, supplier: e.target.value })} placeholder="ชื่อร้าน/ผู้ขาย" />
                  )}
                </Field>
              </div>
            </div>
            <div className="flex gap-2 mt-4">
              <Btn onClick={submit}>{form.id ? "บันทึกการแก้ไข" : <><Plus size={14} /> เพิ่มสินค้า</>}</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingItem && (
        <ConfirmDeletePin
          message={`ลบ "${deletingItem.name}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingItem(null)}
          onConfirm={() => { removeItem(deletingItem.id); setDeletingItem(null); }}
          logActivity={logActivity} activityLabel={`ลบสินค้า ${deletingItem.name}`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: STOCK MANAGEMENT — ผู้ขาย
   ========================================================================= */

function VendorsPage({ vendors, setVendors, staff, ownerProfile, logActivity }) {
  const [query, setQuery] = useState("");
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(emptyVendorForm());
  const [deletingVendor, setDeletingVendor] = useState(null);
  const qrInputRef = useRef(null);

  const filtered = vendors.filter(v =>
    (v.businessName || v.contactPersonName).includes(query) ||
    v.mobile.includes(query) ||
    v.contactCode.includes(query)
  );

  function openForm() {
    setForm(emptyVendorForm());
    setShowForm(true);
  }
  function startEdit(v) {
    setForm({ ...emptyVendorForm(), ...v });
    setShowForm(true);
  }
  function submit() {
    if (!form.businessName && !form.contactPersonName) return;
    if (form.id) {
      setVendors(prev => prev.map(v => v.id === form.id ? { ...form } : v));
    } else {
      setVendors(prev => [...prev, { ...form, id: "vd" + Date.now() }]);
    }
    setShowForm(false);
  }
  function removeVendor(id) {
    setVendors(prev => prev.filter(v => v.id !== id));
    setDeletingVendor(null);
  }
  function set(patch) {
    setForm(prev => ({ ...prev, ...patch }));
  }
  function handleQrUpload(e) {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => set({ qrPaymentImage: reader.result });
    reader.readAsDataURL(file);
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="สมุดรายชื่อ" subtitle="รายชื่อผู้ขาย/ผู้จำหน่ายวัตถุดิบและข้อมูลติดต่อ"
        right={<Btn onClick={openForm}><Plus size={14} /> เพิ่มรายชื่อใหม่</Btn>} />

      <div className="relative max-w-md mb-4">
        <Search size={18} className="absolute left-3.5 top-3 text-stone-400" />
        <input className={`${inputCls} pl-10 py-2.5 text-base`} placeholder="ค้นหาชื่อ, รหัสผู้ติดต่อ หรือเบอร์โทร" value={query} onChange={e => setQuery(e.target.value)} />
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">รหัส</th>
                <th className="px-4 py-3 font-medium">ชื่อผู้ขาย</th>
                <th className="px-4 py-3 font-medium">ผู้ติดต่อ</th>
                <th className="px-4 py-3 font-medium">เบอร์โทร</th>
                <th className="px-4 py-3 font-medium">เครดิต (วัน)</th>
                <th className="px-4 py-3 font-medium">ธนาคาร</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(v => (
                <tr key={v.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 text-stone-400 font-mono">{v.contactCode || "-"}</td>
                  <td className="px-4 py-3 font-medium text-stone-800">{v.businessName || v.contactPersonName}</td>
                  <td className="px-4 py-3 text-stone-500">{v.contactPersonName}</td>
                  <td className="px-4 py-3 text-stone-500">{v.mobile}</td>
                  <td className="px-4 py-3 text-stone-500">{v.creditDays || 0}</td>
                  <td className="px-4 py-3 text-stone-500">{v.bank || "-"}</td>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-3">
                      <button onClick={() => startEdit(v)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                      <button onClick={() => setDeletingVendor(v)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                    </div>
                  </td>
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr><td colSpan={7} className="px-4 py-10 text-center text-stone-400">ยังไม่มีผู้ขายในระบบ</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Add / edit vendor popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-4xl p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-5">
              <div className="font-semibold text-stone-800 text-lg">{form.id ? "แก้ไขผู้ขาย" : "สร้างรายชื่อผู้ขาย"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
              {/* Left column: ข้อมูลผู้ติดต่อ */}
              <div>
                <div className="text-sm font-semibold text-amber-700 border-b border-stone-200 pb-2 mb-4">ข้อมูลผู้ติดต่อ</div>
                <div className="space-y-3">
                  <Field label="ประเภทผู้ติดต่อ">
                    <SegmentedChoice value={form.contactType} onChange={v => set({ contactType: v })}
                      options={[{ value: "corporate", label: "นิติบุคคล" }, { value: "individual", label: "บุคคลธรรมดา" }]} />
                  </Field>

                  <div>
                    <div className="text-xs font-medium text-stone-500 mb-1.5">ประเภท</div>
                    <div className="flex gap-4">
                      <label className="flex items-center gap-1.5 text-sm text-stone-700 cursor-pointer">
                        <input type="checkbox" checked={form.isCustomer} onChange={e => set({ isCustomer: e.target.checked })} /> ลูกค้า
                      </label>
                      <label className="flex items-center gap-1.5 text-sm text-stone-700 cursor-pointer">
                        <input type="checkbox" checked={form.isVendor} onChange={e => set({ isVendor: e.target.checked })} /> ผู้จำหน่าย
                      </label>
                    </div>
                  </div>

                  <Field label="เครดิต (วัน)"><input type="number" className={inputCls} value={form.creditDays} onChange={e => set({ creditDays: e.target.value })} placeholder="0" /></Field>

                  <Field label="ที่ตั้งธุรกิจ">
                    <SegmentedChoice value={form.location} onChange={v => set({ location: v })}
                      options={[{ value: "thailand", label: "ไทย" }, { value: "foreign", label: "ต่างประเทศ" }]} />
                  </Field>

                  <Field label="รหัสผู้ติดต่อ"><input className={inputCls} value={form.contactCode} onChange={e => set({ contactCode: e.target.value })} placeholder="เช่น V001" /></Field>

                  {form.contactType === "corporate" && (
                    <>
                      <Field label="ชื่อธุรกิจ"><input className={inputCls} value={form.businessName} onChange={e => set({ businessName: e.target.value })} placeholder="ตัวอย่างการกรอก: บริษัท โฟลว์แอคเคาท์ จำกัด" /></Field>
                      <Field label="เลขผู้เสียภาษี"><input className={inputCls} value={form.taxId} onChange={e => set({ taxId: e.target.value.replace(/\D/g, "").slice(0, 13) })} placeholder="ระบุเลขผู้เสียภาษี 10 - 13 หลัก" /></Field>
                      <Field label="สำนักงาน/สาขา">
                        <SegmentedChoice value={form.officeType} onChange={v => set({ officeType: v })}
                          options={[{ value: "hq", label: "สำนักงานใหญ่" }, { value: "branch", label: "สาขา" }]} />
                      </Field>
                    </>
                  )}

                  <Field label="ที่อยู่"><textarea rows={3} className={inputCls} value={form.address} onChange={e => set({ address: e.target.value })} /></Field>
                  <Field label="รหัสไปรษณีย์"><input className={`${inputCls} max-w-[160px]`} value={form.zipcode} onChange={e => set({ zipcode: e.target.value.replace(/\D/g, "").slice(0, 5) })} /></Field>
                  <Field label="ข้อมูลจัดส่ง"><textarea rows={2} className={inputCls} value={form.shippingInfo} onChange={e => set({ shippingInfo: e.target.value })} placeholder="เช่น วันและเวลาที่จัดส่งเป็นประจำ" /></Field>

                  <div className="grid grid-cols-2 gap-3">
                    <Field label="เบอร์สำนักงาน"><input className={inputCls} value={form.officePhone} onChange={e => set({ officePhone: e.target.value })} /></Field>
                    <Field label="เบอร์โทรสาร"><input className={inputCls} value={form.faxNumber} onChange={e => set({ faxNumber: e.target.value })} /></Field>
                  </div>
                  <Field label="เว็บไซต์"><input className={inputCls} value={form.website} onChange={e => set({ website: e.target.value })} /></Field>
                </div>
              </div>

              {/* Right column: รายละเอียดผู้ติดต่อ + ข้อมูลธนาคาร + ข้อมูลเพิ่มเติม */}
              <div>
                <div className="text-sm font-semibold text-amber-700 border-b border-stone-200 pb-2 mb-4">รายละเอียดผู้ติดต่อ</div>
                <div className="space-y-3 mb-6">
                  <Field label="ชื่อผู้ติดต่อ"><input className={inputCls} value={form.contactPersonName} onChange={e => set({ contactPersonName: e.target.value })} /></Field>
                  <Field label="อีเมล"><input type="email" className={inputCls} value={form.email} onChange={e => set({ email: e.target.value })} /></Field>
                  <Field label="เบอร์มือถือ"><input className={inputCls} value={form.mobile} onChange={e => set({ mobile: e.target.value })} placeholder="08x-xxx-xxxx" /></Field>
                </div>

                <div className="text-sm font-semibold text-amber-700 border-b border-stone-200 pb-2 mb-4">ข้อมูลธนาคาร</div>
                <div className="space-y-3">
                  <Field label="ธนาคาร">
                    <select className={inputCls} value={form.bank} onChange={e => set({ bank: e.target.value })}>
                      <option value="">กรุณาเลือกธนาคาร</option>
                      {THAI_BANKS.map(b => <option key={b} value={b}>{b}</option>)}
                    </select>
                  </Field>
                  <Field label="ชื่อบัญชี"><input className={inputCls} value={form.accountName} onChange={e => set({ accountName: e.target.value })} /></Field>
                  <Field label="เลขที่บัญชี"><input className={inputCls} value={form.accountNumber} onChange={e => set({ accountNumber: e.target.value })} /></Field>
                  <div className="grid grid-cols-2 gap-3">
                    <Field label="รหัสสาขา"><input className={inputCls} value={form.branchCode} onChange={e => set({ branchCode: e.target.value })} /></Field>
                    <Field label="ชื่อสาขา"><input className={inputCls} value={form.branchName} onChange={e => set({ branchName: e.target.value })} /></Field>
                  </div>
                  <Field label="ประเภทบัญชี">
                    <SegmentedChoice value={form.accountType} onChange={v => set({ accountType: v })}
                      options={[{ value: "savings", label: "ออมทรัพย์" }, { value: "current", label: "กระแสรายวัน" }]} />
                  </Field>

                  <div>
                    <div className="text-xs font-medium text-stone-500 mb-1.5">คิวอาร์ชำระเงิน</div>
                    <input ref={qrInputRef} type="file" accept="image/*" className="hidden" onChange={handleQrUpload} />
                    <button type="button" onClick={() => qrInputRef.current?.click()}
                      className="w-28 h-28 rounded-lg border-2 border-dashed border-stone-300 flex flex-col items-center justify-center text-center gap-1 text-stone-400 hover:border-stone-400 overflow-hidden">
                      {form.qrPaymentImage ? (
                        <img src={form.qrPaymentImage} alt="QR ชำระเงิน" className="w-full h-full object-cover" />
                      ) : (
                        <>
                          <ImageIcon size={22} />
                          <span className="text-[11px] leading-tight px-1">คลิกเพื่ออัปโหลดรูป QR code ที่นี่</span>
                        </>
                      )}
                    </button>
                  </div>

                  <label className="flex items-center gap-1.5 text-sm text-amber-700 cursor-pointer pt-2">
                    <input type="checkbox" checked={form.foreignBankInfo} onChange={e => set({ foreignBankInfo: e.target.checked })} />
                    ข้อมูลเพิ่มเติมสำหรับธนาคารต่างประเทศ
                  </label>
                  {form.foreignBankInfo && (
                    <div className="space-y-3 pt-1">
                      <Field label="Swift Code"><input className={inputCls} value={form.swiftCode} onChange={e => set({ swiftCode: e.target.value })} /></Field>
                      <Field label="ที่อยู่ธนาคาร"><textarea rows={2} className={inputCls} value={form.bankAddress} onChange={e => set({ bankAddress: e.target.value })} /></Field>
                    </div>
                  )}
                </div>

                <div className="text-sm font-semibold text-amber-700 border-b border-stone-200 pb-2 mb-4 mt-6">ข้อมูลเพิ่มเติม</div>
                <div className="space-y-3">
                  <Field label="แนบไฟล์">
                    <label className="inline-flex items-center gap-1.5 text-sm text-stone-600 border border-stone-300 rounded-md px-3 py-2 cursor-pointer hover:border-stone-400 w-fit">
                      <input type="file" className="hidden" onChange={e => set({ attachmentName: e.target.files?.[0]?.name || "" })} />
                      <Copy size={13} /> แนบไฟล์
                    </label>
                    {form.attachmentName && <div className="text-xs text-stone-400 mt-1">{form.attachmentName}</div>}
                  </Field>
                  <Field label="โน้ต"><textarea rows={3} className={inputCls} value={form.note} onChange={e => set({ note: e.target.value })} /></Field>
                </div>
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-6 pt-5 border-t border-stone-200">
              <Btn variant="ghost" onClick={() => setShowForm(false)}>ปิดหน้าต่าง</Btn>
              <Btn onClick={submit}>บันทึกแล้วปิด</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingVendor && (
        <ConfirmDeletePin
          message={`ลบ "${deletingVendor.businessName || deletingVendor.contactPersonName}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingVendor(null)}
          onConfirm={() => removeVendor(deletingVendor.id)}
          logActivity={logActivity} activityLabel={`ลบผู้จำหน่าย ${deletingVendor.businessName || deletingVendor.contactPersonName}`}
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: STOCK MANAGEMENT — ใบสั่งซื้อ
   ========================================================================= */

function nextPoNumber(purchaseOrders) {
  const now = new Date();
  const prefix = `PO${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}`;
  const seq = purchaseOrders.filter(p => p.poNumber.startsWith(prefix)).length + 1;
  return `${prefix}${String(seq).padStart(4, "0")}`;
}

function PurchaseOrdersPage({ purchaseOrders, setPurchaseOrders, vendors, stockItems, financeAccounts, setFinanceAccounts, currentBranchId, branches, storeInfo }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(emptyPurchaseOrder());
  const [showShareMenu, setShowShareMenu] = useState(false);
  const [printChoiceMode, setPrintChoiceMode] = useState(null); // "print" | "download" | null
  const [docCopyLabel, setDocCopyLabel] = useState("ต้นฉบับ");
  const [pendingAction, setPendingAction] = useState(null); // "print" | "download" | null
  const [payingPo, setPayingPo] = useState(null);
  const [confirmingCancelPo, setConfirmingCancelPo] = useState(null);
  const [paymentForm, setPaymentForm] = useState(null);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visiblePOs = purchaseOrders.filter(po => !effectiveBranchId || !po.branchId || po.branchId === effectiveBranchId);
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  const WHT_RATES = [1, 2, 3, 5, 10, 15];

  function handlePaymentStatusChange(po, status) {
    if (status === "pending") {
      if (po.paymentStatus === "paid") {
        setConfirmingCancelPo(po);
        return;
      }
      setPurchaseOrders(prev => prev.map(p => p.id === po.id ? { ...p, paymentStatus: "pending" } : p));
      return;
    }
    const grand = poComputeTotals(po).grand;
    setPayingPo(po);
    setPaymentForm({
      paymentDate: new Date().toISOString().slice(0, 10),
      netPaid: String(grand),
      whtEnabled: false, whtPercent: 3,
      paymentMethods: [{ id: "pm" + Date.now(), accountId: financeAccounts[0]?.id || "", amount: String(grand) }],
      note: "",
    });
  }
  function setPF(patch) { setPaymentForm(prev => ({ ...prev, ...patch })); }
  function addPaymentMethodRow() {
    setPaymentForm(prev => ({ ...prev, paymentMethods: [...prev.paymentMethods, { id: "pm" + Date.now() + Math.random().toString(36).slice(2, 5), accountId: financeAccounts[0]?.id || "", amount: "" }] }));
  }
  function updatePaymentMethodRow(id, patch) {
    setPaymentForm(prev => ({ ...prev, paymentMethods: prev.paymentMethods.map(m => m.id === id ? { ...m, ...patch } : m) }));
  }
  function removePaymentMethodRow(id) {
    setPaymentForm(prev => ({ ...prev, paymentMethods: prev.paymentMethods.filter(m => m.id !== id) }));
  }
  function savePayment() {
    if (!payingPo || !paymentForm) return;
    setPurchaseOrders(prev => prev.map(p => p.id === payingPo.id ? { ...p, paymentStatus: "paid", payment: { ...paymentForm } } : p));
    if (setFinanceAccounts) {
      setFinanceAccounts(prev => prev.map(acc => {
        const paidFromThis = paymentForm.paymentMethods
          .filter(pm => pm.accountId === acc.id)
          .reduce((s, pm) => s + (Number(pm.amount) || 0), 0);
        return paidFromThis > 0 ? { ...acc, currentBalance: acc.currentBalance - paidFromThis } : acc;
      }));
    }
    setPayingPo(null);
    setPaymentForm(null);
  }
  function confirmCancelPayment() {
    if (!confirmingCancelPo) return;
    setPurchaseOrders(prev => prev.map(p => p.id === confirmingCancelPo.id ? { ...p, paymentStatus: "pending" } : p));
    if (setFinanceAccounts && confirmingCancelPo.payment?.paymentMethods) {
      setFinanceAccounts(prev => prev.map(acc => {
        const paidFromThis = confirmingCancelPo.payment.paymentMethods
          .filter(pm => pm.accountId === acc.id)
          .reduce((s, pm) => s + (Number(pm.amount) || 0), 0);
        return paidFromThis > 0 ? { ...acc, currentBalance: acc.currentBalance + paidFromThis } : acc;
      }));
    }
    setConfirmingCancelPo(null);
  }

  useEffect(() => {
    if (pendingAction === "print") {
      printA4Page();
      setPendingAction(null);
    } else if (pendingAction === "download") {
      downloadPrintTemplate(".print-po", `ใบสั่งซื้อ-${form.poNumber}-${docCopyLabel}.html`);
      setPendingAction(null);
    }
  }, [pendingAction]);

  function openCreate() {
    setForm({ ...emptyPurchaseOrder(), poNumber: nextPoNumber(purchaseOrders), branchId: effectiveBranchId || "" });
    setShowForm(true);
  }
  function openEdit(po) {
    setForm({ ...po, lines: po.lines.length ? po.lines.map(l => ({ ...l })) : [emptyPOLine()] });
    setShowForm(true);
  }
  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }
  function setVendor(vendorId) {
    const v = vendors.find(x => x.id === vendorId);
    set({
      vendorId,
      address: v ? [v.address, v.zipcode].filter(Boolean).join(" ") : "",
      zipcode: v?.zipcode || "",
      taxId: v?.taxId || "",
      creditDays: v?.creditDays || "0",
    });
  }
  function updateLine(idx, patch) {
    setForm(prev => ({ ...prev, lines: prev.lines.map((l, i) => i === idx ? { ...l, ...patch } : l) }));
  }
  function setLineStockItem(idx, stockItemId) {
    const item = stockItems.find(s => s.id === stockItemId);
    updateLine(idx, { stockItemId, description: item?.name || "", unit: item?.unit || "", unitPrice: item ? String(item.costPerUnit) : "" });
  }
  function addLine() {
    setForm(prev => ({ ...prev, lines: [...prev.lines, emptyPOLine()] }));
  }
  function removeLine(idx) {
    setForm(prev => ({ ...prev, lines: prev.lines.filter((_, i) => i !== idx) }));
  }
  function save() {
    const cleanLines = form.lines.filter(l => l.stockItemId && Number(l.qty) > 0);
    if (!form.vendorId || cleanLines.length === 0) return;
    const payload = { ...form, lines: cleanLines };
    if (form.id) {
      setPurchaseOrders(prev => prev.map(p => p.id === form.id ? payload : p));
    } else {
      const newId = "po" + Date.now();
      setPurchaseOrders(prev => [...prev, { ...payload, id: newId }]);
      setForm(prev => ({ ...prev, id: newId }));
      return; // keep the popup open so the share/print/download buttons (which need a saved id) appear
    }
    setShowForm(false);
  }
  function poShareText() {
    const v = vendors.find(x => x.id === form.vendorId);
    const t = poComputeTotals(form);
    const lines = form.lines.filter(l => l.stockItemId).map(l => `- ${l.description} x${l.qty} ${l.unit} = ฿${fmtMoney(poLineTotal(l))}`).join("\n");
    return `ใบสั่งซื้อ ${form.poNumber}\nผู้จำหน่าย: ${v?.businessName || v?.contactPersonName || "-"}\nวันที่: ${fmtDate(form.date)}\n\n${lines}\n\nยอดรวมทั้งสิ้น: ฿${fmtMoney(t.grand)}`;
  }
  function shareCopyText() {
    if (navigator.clipboard) navigator.clipboard.writeText(poShareText()).catch(() => {});
    setShowShareMenu(false);
  }
  function shareEmailToVendor() {
    const v = vendors.find(x => x.id === form.vendorId);
    const subject = encodeURIComponent(`ใบสั่งซื้อ ${form.poNumber}`);
    const body = encodeURIComponent(poShareText());
    window.open(`mailto:${v?.email || ""}?subject=${subject}&body=${body}`, "_blank");
    setShowShareMenu(false);
  }
  function chooseCopyAndRun(type) {
    setDocCopyLabel(type);
    const action = printChoiceMode;
    setPrintChoiceMode(null);
    setPendingAction(action);
  }

  const totals = poComputeTotals(form);
  const vendor = vendors.find(v => v.id === form.vendorId);

  const exportRows = visiblePOs.map(po => {
    const v = vendors.find(x => x.id === po.vendorId);
    const t = poComputeTotals(po);
    return {
      "เลขที่": po.poNumber, "ผู้จำหน่าย": v?.businessName || v?.contactPersonName || "-",
      "สาขา": branchNameFor(po.branchId) || "-",
      "วันที่": fmtDate(po.date), "ครบกำหนด": fmtDate(poDueDate(po)), "ยอดรวม": t.grand,
      "สถานะรับสินค้า": PO_STATUS_LABEL[poReceiveStatus(po)], "สถานะการเงิน": po.paymentStatus === "paid" ? "ชำระเงินแล้ว" : "รอชำระ",
    };
  });

  return (
    <div>
      <PageHeader eyebrow="การจัดการสต๊อก" title="ใบสั่งซื้อ" subtitle="สร้างและจัดการใบสั่งซื้อวัตถุดิบ"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <ExportButton data={exportRows} filename="ใบสั่งซื้อ" sheetName="PurchaseOrders" />
            <Btn onClick={openCreate}><Plus size={14} /> สร้างใบสั่งซื้อ</Btn>
          </div>
        } />

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">เลขที่</th>
                <th className="px-4 py-3 font-medium">ผู้จำหน่าย</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                <th className="px-4 py-3 font-medium">วันที่</th>
                <th className="px-4 py-3 font-medium">ครบกำหนด</th>
                <th className="px-4 py-3 font-medium">ยอดรวม</th>
                <th className="px-4 py-3 font-medium">การเงิน</th>
                <th className="px-4 py-3 font-medium">สถานะ</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {visiblePOs.map(po => {
                const v = vendors.find(x => x.id === po.vendorId);
                const t = poComputeTotals(po);
                const status = poReceiveStatus(po);
                const paymentStatus = po.paymentStatus || "pending";
                return (
                  <tr key={po.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 font-mono text-stone-700">{po.poNumber}</td>
                    <td className="px-4 py-3 font-medium text-stone-800">{v?.businessName || v?.contactPersonName || "-"}</td>
                    {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchNameFor(po.branchId) || "-"}</td>}
                    <td className="px-4 py-3 text-stone-400">{fmtDate(po.date)}</td>
                    <td className="px-4 py-3 text-stone-400">{fmtDate(poDueDate(po))}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(t.grand)}</td>
                    <td className="px-4 py-3">
                      <select value={paymentStatus} onChange={e => handlePaymentStatusChange(po, e.target.value)}
                        className={`text-xs px-2 py-1 rounded border font-medium ${paymentStatus === "paid" ? "bg-emerald-50 text-emerald-700 border-emerald-300" : "bg-amber-50 text-amber-700 border-amber-300"}`}>
                        <option value="pending">รอชำระ</option>
                        <option value="paid">ชำระเงิน</option>
                      </select>
                    </td>
                    <td className="px-4 py-3"><span className={`text-xs px-2 py-0.5 rounded border font-medium ${PO_STATUS_STYLE[status]}`}>{PO_STATUS_LABEL[status]}</span></td>
                    <td className="px-4 py-3">
                      <button onClick={() => openEdit(po)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                    </td>
                  </tr>
                );
              })}
              {visiblePOs.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 7 : 8} className="px-4 py-10 text-center text-stone-400">ยังไม่มีใบสั่งซื้อ</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* PO form */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-5xl p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-5 pb-4 border-b border-stone-200">
              <div className="flex items-center gap-2">
                <ClipboardList size={20} className="text-sky-600" />
                <div>
                  <div className="text-xs text-stone-400">{form.id ? "แก้ไขใบสั่งซื้อ" : "สร้างใบสั่งซื้อ"}</div>
                  <div className="font-semibold text-stone-800 text-lg font-mono">{form.poNumber}</div>
                </div>
                {currentBranchId ? (
                  <span className="text-xs px-2.5 py-1 rounded-full border font-medium ml-2 bg-amber-50 text-amber-700 border-amber-200">
                    {form.id ? "บันทึกไว้สำหรับสาขา" : "กำลังบันทึกสำหรับสาขา"}: {branches?.find(b => b.id === currentBranchId)?.name || "-"}
                  </span>
                ) : branches && branches.length > 0 ? (
                  <div className="flex items-center gap-1.5 ml-2">
                    <span className="text-xs text-stone-400">สาขา:</span>
                    <select className={`${inputCls} py-1 text-xs max-w-[160px]`} value={form.branchId || ""} onChange={e => set({ branchId: e.target.value || null })}>
                      <option value="">ไม่ผูกกับสาขาใด</option>
                      {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
                    </select>
                  </div>
                ) : null}
              </div>
              <div className="flex items-center gap-2">
                {form.id && (
                  <>
                    <div className="relative">
                      <Btn variant="ghost" onClick={() => setShowShareMenu(v => !v)}><Copy size={14} /> แชร์ใบสั่งซื้อ</Btn>
                      {showShareMenu && (
                        <div className="absolute right-0 top-full mt-1 bg-white border border-stone-200 rounded-lg shadow-lg z-10 w-56 overflow-hidden">
                          <button onClick={shareEmailToVendor} className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2">
                            <Truck size={14} className="text-stone-400" /> ส่งอีเมลถึงผู้ขาย
                          </button>
                          <button onClick={shareCopyText} className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2 border-t border-stone-100">
                            <Copy size={14} className="text-stone-400" /> คัดลอกเป็นข้อความ
                          </button>
                        </div>
                      )}
                    </div>
                    <Btn variant="ghost" onClick={() => setPrintChoiceMode("print")}><Printer size={14} /> พิมพ์ใบสั่งซื้อ</Btn>
                    <Btn variant="ghost" onClick={() => setPrintChoiceMode("download")}><ReceiptText size={14} /> ดาวน์โหลด</Btn>
                  </>
                )}
                <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600 ml-2"><X size={18} /></button>
              </div>
            </div>

            {!form.id && (
              <div className="text-xs text-amber-600 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2 mb-4">
                บันทึกเอกสารก่อน จึงจะแชร์ พิมพ์ หรือดาวน์โหลดใบสั่งซื้อนี้ได้
              </div>
            )}

            <div className="mb-5">
              <div className="space-y-0 mb-5">
                <div className="flex items-center justify-between py-2 border-b border-stone-100">
                  <span className="text-sm text-stone-500 flex-shrink-0">วันที่:</span>
                  <input type="date" className="text-sm text-right border-0 focus:outline-none focus:ring-0 text-stone-700 w-40" value={form.date} onChange={e => set({ date: e.target.value })} />
                </div>
                <div className="flex items-center justify-between py-2 border-b border-stone-100">
                  <span className="text-sm text-stone-500 flex-shrink-0">เครดิต (วัน):</span>
                  <input type="number" className="text-sm text-right border-0 focus:outline-none focus:ring-0 text-stone-700 w-40" value={form.creditDays} onChange={e => set({ creditDays: e.target.value })} />
                </div>
                <div className="flex items-center justify-between py-2 border-b border-stone-100">
                  <span className="text-sm text-stone-500 flex-shrink-0">วันครบกำหนด:</span>
                  <span className="text-sm text-stone-400 w-40 text-right">{fmtDate(poDueDate(form))}</span>
                </div>
                <div className="flex items-center justify-between py-2 border-b border-stone-100">
                  <span className="text-sm text-stone-500 flex-shrink-0">ผู้สั่งซื้อ:</span>
                  <input className="text-sm text-right border-0 focus:outline-none focus:ring-0 text-stone-700 w-40" value={form.purchaser} onChange={e => set({ purchaser: e.target.value })} placeholder="ชื่อผู้สั่งซื้อ" />
                </div>
                <div className="flex items-center justify-between py-2">
                  <span className="text-sm text-stone-500 flex-shrink-0">สกุลเงิน:</span>
                  <span className="text-sm text-stone-500 w-40 text-right">THB - ไทย</span>
                </div>
              </div>

              <div className="space-y-3">
                <Field label="ชื่อผู้จำหน่าย">
                  <select className={inputCls} value={form.vendorId} onChange={e => setVendor(e.target.value)}>
                    <option value="">เลือกผู้จำหน่าย</option>
                    {vendors.map(v => <option key={v.id} value={v.id}>{v.businessName || v.contactPersonName}</option>)}
                  </select>
                </Field>
                <Field label="ที่อยู่"><textarea rows={5} className={inputCls} value={form.address} onChange={e => set({ address: e.target.value })} placeholder="ที่อยู่ผู้จำหน่าย (ดึงอัตโนมัติเมื่อเลือกผู้จำหน่าย)" /></Field>
              </div>
            </div>

            <div className="pt-4 border-t border-stone-200 space-y-3 mb-3">
              <Field label="รายละเอียด"><input className={inputCls} value={form.reference2 || ""} onChange={e => set({ reference2: e.target.value })} /></Field>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขที่อ้างอิง"><input className={inputCls} value={form.reference} onChange={e => set({ reference: e.target.value })} /></Field>
                <Field label="ราคาสินค้า">
                  <select className={inputCls} value={form.priceMode} onChange={e => set({ priceMode: e.target.value })}>
                    <option value="excl">ราคาไม่รวมภาษี</option>
                    <option value="incl">ราคารวมภาษี</option>
                  </select>
                </Field>
              </div>
            </div>

            <Card className="p-0 overflow-hidden mb-2">
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="bg-blue-950 text-white text-xs uppercase tracking-wide">
                      <th className="px-3 py-2.5 font-medium text-left w-12">ลำดับ</th>
                      <th className="px-3 py-2.5 font-medium text-left">ชื่อสินค้า / รายละเอียด</th>
                      <th className="px-3 py-2.5 font-medium text-right w-20">จำนวน</th>
                      <th className="px-3 py-2.5 font-medium text-left w-24">หน่วย</th>
                      <th className="px-3 py-2.5 font-medium text-right w-28">ราคาต่อหน่วย</th>
                      <th className="px-3 py-2.5 font-medium text-right w-28">ราคารวม</th>
                      <th className="px-2 py-2.5 w-8"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {form.lines.map((l, i) => (
                      <tr key={l.id} className="border-b border-stone-100 last:border-0">
                        <td className="px-3 py-2 text-stone-400 align-top">{i + 1}</td>
                        <td className="px-3 py-2 align-top">
                          <select className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm mb-1" value={l.stockItemId} onChange={e => setLineStockItem(i, e.target.value)}>
                            <option value="">— เลือกสินค้า —</option>
                            {stockItems.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
                          </select>
                        </td>
                        <td className="px-3 py-2 align-top">
                          <input type="number" step="any" className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={l.qty} onChange={e => updateLine(i, { qty: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top text-stone-500">{l.unit || "-"}</td>
                        <td className="px-3 py-2 align-top">
                          <input type="number" step="any" className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={l.unitPrice} onChange={e => updateLine(i, { unitPrice: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top text-right font-mono text-stone-700">{fmtMoney(poLineTotal(l))}</td>
                        <td className="px-2 py-2 align-top text-center">
                          <button onClick={() => removeLine(i)} className="text-stone-300 hover:text-rose-500"><X size={14} /></button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </Card>
            <button onClick={addLine} className="text-xs font-medium text-sky-700 hover:text-sky-900 flex items-center gap-1 mb-5">
              <Plus size={12} /> เพิ่มแถวรายการ
            </button>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
              <div className="space-y-3">
                <Field label="หมายเหตุ"><textarea rows={3} className={inputCls} value={form.note} onChange={e => set({ note: e.target.value })} /></Field>
                <Field label="โน้ตภายในบริษัท"><textarea rows={3} className={inputCls} value={form.internalNote} onChange={e => set({ internalNote: e.target.value })} /></Field>
              </div>
              <div className="space-y-1.5 text-sm">
                <div className="flex items-center justify-between"><span className="text-stone-500">รวมเป็นเงิน</span><span className="font-mono">{fmtMoney(totals.subtotal)}</span></div>
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">ส่วนลด</span>
                  <span className="flex items-center gap-2">
                    <input type="number" className="w-16 rounded-md border border-stone-300 px-2 py-1 text-sm text-right" value={form.discountPercent} onChange={e => set({ discountPercent: e.target.value })} /> %
                    <span className="font-mono w-20 text-right">-{fmtMoney(totals.discountAmt)}</span>
                  </span>
                </div>
                <div className="flex items-center justify-between"><span className="text-stone-500">ราคาหลังหักส่วนลด</span><span className="font-mono">{fmtMoney(totals.afterDiscount)}</span></div>

                {form.priceMode === "incl" ? (
                  <>
                    <div className="flex items-center justify-between pt-2 border-t border-stone-200 font-semibold text-stone-800">
                      <span>จำนวนเงินรวมทั้งสิ้น</span><span className="font-mono text-lg text-sky-700">฿{fmtMoney(totals.grand)}</span>
                    </div>
                    <div className="h-2" />
                    <label className="flex items-center justify-between cursor-pointer">
                      <span className="flex items-center gap-1.5 text-stone-500"><input type="checkbox" checked={form.vatEnabled} onChange={e => set({ vatEnabled: e.target.checked })} /> ภาษีมูลค่าเพิ่ม {form.vatRate}%</span>
                      <span className="font-mono">{fmtMoney(totals.vatAmt)}</span>
                    </label>
                    <div className="flex items-center justify-between"><span className="text-stone-500">ราคาไม่รวมภาษีมูลค่าเพิ่ม</span><span className="font-mono">{fmtMoney(totals.priceExclVat)}</span></div>
                  </>
                ) : (
                  <>
                    <label className="flex items-center justify-between cursor-pointer">
                      <span className="flex items-center gap-1.5 text-stone-500"><input type="checkbox" checked={form.vatEnabled} onChange={e => set({ vatEnabled: e.target.checked })} /> ภาษีมูลค่าเพิ่ม {form.vatRate}%</span>
                      <span className="font-mono">{fmtMoney(totals.vatAmt)}</span>
                    </label>
                    <div className="flex items-center justify-between pt-2 border-t border-stone-200 font-semibold text-stone-800">
                      <span>จำนวนเงินรวมทั้งสิ้น</span><span className="font-mono text-lg text-sky-700">฿{fmtMoney(totals.grand)}</span>
                    </div>
                  </>
                )}
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-6 pt-5 border-t border-stone-200">
              <Btn variant="ghost" onClick={() => setShowForm(false)}>ปิดหน้าต่าง</Btn>
              <Btn onClick={save}>บันทึกเอกสาร</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Print / download copy-type choice */}
      {printChoiceMode && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setPrintChoiceMode(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{printChoiceMode === "print" ? "พิมพ์ใบสั่งซื้อ" : "ดาวน์โหลดใบสั่งซื้อ"}</div>
              <button onClick={() => setPrintChoiceMode(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-3">เลือกประเภทเอกสารที่ต้องการ</div>
            <div className="space-y-2">
              <button onClick={() => chooseCopyAndRun("ต้นฉบับ")} className="w-full text-left px-3 py-2.5 rounded-lg border border-stone-200 hover:border-sky-400 text-sm text-stone-700">ต้นฉบับ</button>
              <button onClick={() => chooseCopyAndRun("สำเนา")} className="w-full text-left px-3 py-2.5 rounded-lg border border-stone-200 hover:border-sky-400 text-sm text-stone-700">สำเนา</button>
            </div>
            {printChoiceMode === "download" && (
              <p className="text-[11px] text-stone-400 mt-3">จะดาวน์โหลดเป็นไฟล์ .html ที่เปิดดู/พิมพ์เป็น PDF เองภายหลังได้</p>
            )}
          </div>
        </div>
      )}

      {/* Confirm cancelling a payment */}
      {confirmingCancelPo && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setConfirmingCancelPo(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">คุณต้องการยกเลิกการชำระเงินใช่ไหม</div>
            <div className="text-sm text-stone-400 mb-4">ใบสั่งซื้อ {confirmingCancelPo.poNumber} จะเปลี่ยนสถานะกลับเป็น "รอชำระ"</div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setConfirmingCancelPo(null)}>ยกเลิก</Btn>
              <Btn onClick={confirmCancelPayment}>ยืนยัน</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Record payment popup */}
      {payingPo && paymentForm && (() => {
        const grand = poComputeTotals(payingPo).grand;
        const v = vendors.find(x => x.id === payingPo.vendorId);
        const whtAmount = paymentForm.whtEnabled ? Math.round(grand * (paymentForm.whtPercent / 100) * 100) / 100 : 0;
        function toggleWht(enabled) {
          if (enabled) {
            const amt = Math.round(grand * (paymentForm.whtPercent / 100) * 100) / 100;
            const net = Math.round((grand - amt) * 100) / 100;
            setPaymentForm(prev => ({ ...prev, whtEnabled: true, netPaid: String(net) }));
          } else {
            setPaymentForm(prev => ({ ...prev, whtEnabled: false, netPaid: String(grand) }));
          }
        }
        function changeWhtPercent(percent) {
          const amt = Math.round(grand * (percent / 100) * 100) / 100;
          const net = Math.round((grand - amt) * 100) / 100;
          setPaymentForm(prev => ({ ...prev, whtPercent: percent, netPaid: String(net) }));
        }
        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setPayingPo(null); setPaymentForm(null); }}>
            <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800 text-lg">บันทึกการชำระเงิน</div>
                <button onClick={() => { setPayingPo(null); setPaymentForm(null); }} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>

              <div className="space-y-2 text-sm mb-4">
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">เลขที่เอกสาร:</span>
                  <span className="font-medium text-stone-800 text-right">{payingPo.poNumber} ({v?.businessName || v?.contactPersonName || "-"})</span>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">ยอดที่ต้องชำระ:</span>
                  <span className="font-medium text-stone-800">{fmtMoney(grand)} บาท</span>
                </div>
              </div>

              <div className="space-y-3">
                <Field label="วันที่ชำระ"><input type="date" className={inputCls} value={paymentForm.paymentDate} onChange={e => setPF({ paymentDate: e.target.value })} /></Field>
                <Field label="ยอดจ่ายสุทธิ"><input type="number" className={inputCls} value={paymentForm.netPaid} onChange={e => setPF({ netPaid: e.target.value })} /></Field>

                <label className="flex items-center gap-2 text-sm text-stone-700 cursor-pointer">
                  <input type="checkbox" checked={paymentForm.whtEnabled} onChange={e => toggleWht(e.target.checked)} /> หัก ณ ที่จ่าย
                </label>
                {paymentForm.whtEnabled && (
                  <div className="flex items-center gap-2">
                    <select className={`${inputCls} max-w-[110px]`} value={paymentForm.whtPercent} onChange={e => changeWhtPercent(Number(e.target.value))}>
                      {WHT_RATES.map(r => <option key={r} value={r}>{r}%</option>)}
                    </select>
                    <input disabled className={`${inputCls} bg-stone-50 text-stone-500`} value={fmtMoney(whtAmount)} />
                  </div>
                )}

                <div className="text-sm font-semibold text-sky-700 pt-2 border-t border-stone-200">วิธีการชำระ</div>
                <div className="space-y-2">
                  {paymentForm.paymentMethods.map(pm => (
                    <div key={pm.id} className="flex items-center gap-2">
                      <select className="flex-1 min-w-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={pm.accountId} onChange={e => updatePaymentMethodRow(pm.id, { accountId: e.target.value })}>
                        {financeAccounts.map(acc => <option key={acc.id} value={acc.id}>{financeAccountDisplayName(acc)}</option>)}
                      </select>
                      <input type="number" className="w-28 flex-shrink-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={pm.amount} onChange={e => updatePaymentMethodRow(pm.id, { amount: e.target.value })} placeholder="จำนวนเงิน" />
                      <button onClick={() => removePaymentMethodRow(pm.id)} disabled={paymentForm.paymentMethods.length <= 1}
                        className={`flex-shrink-0 ${paymentForm.paymentMethods.length <= 1 ? "text-stone-200" : "text-stone-300 hover:text-rose-500"}`}>
                        <X size={14} />
                      </button>
                    </div>
                  ))}
                </div>
                <button onClick={addPaymentMethodRow} className="text-xs font-medium text-sky-700 hover:text-sky-900 flex items-center gap-1">
                  <Plus size={12} /> เพิ่มวิธีการชำระ
                </button>
                {(() => {
                  const paidTotal = paymentForm.paymentMethods.reduce((s, m) => s + (Number(m.amount) || 0), 0);
                  const diff = Math.round((Number(paymentForm.netPaid || 0) - paidTotal) * 100) / 100;
                  if (diff === 0) return <div className="text-xs text-emerald-600">ยอดรวมวิธีการชำระตรงกับยอดจ่ายสุทธิแล้ว ({fmtMoney(paidTotal)})</div>;
                  return <div className="text-xs text-amber-600">รวมวิธีการชำระ {fmtMoney(paidTotal)} — {diff > 0 ? `ขาดอีก ${fmtMoney(diff)}` : `เกินไป ${fmtMoney(Math.abs(diff))}`}</div>;
                })()}

                <div className="text-sm font-semibold text-sky-700 pt-2 border-t border-stone-200">รายละเอียดเพิ่มเติม</div>
                <Field label="หมายเหตุ:"><textarea rows={3} className={inputCls} value={paymentForm.note} onChange={e => setPF({ note: e.target.value })} /></Field>
              </div>

              <div className="flex justify-end gap-2 mt-5">
                <Btn variant="ghost" onClick={() => { setPayingPo(null); setPaymentForm(null); }}>ยกเลิก</Btn>
                <Btn onClick={savePayment}>บันทึก</Btn>
              </div>
            </div>
          </div>
        );
      })()}

      {/* Hidden printable PO document */}
      <div className="print-po">
        {(() => {
          const poBranch = branches?.find(b => b.id === form.branchId);
          const coName = poBranch?.companyName || storeInfo?.name;
          const coAddress = poBranch?.companyAddress || storeInfo?.address;
          const coTaxId = poBranch?.taxId || storeInfo?.taxId;
          const coPhone = poBranch?.phone || storeInfo?.phone;
          const coOfficeType = poBranch?.officeType;
          return (coName || coAddress || coTaxId) && (
            <div style={{ marginBottom: 16, paddingBottom: 12, borderBottom: "1px solid #ddd", fontSize: 13 }}>
              <div style={{ fontSize: 16, fontWeight: 600 }}>{coName}</div>
              {coAddress && <div style={{ color: "#444" }}>{coAddress}</div>}
              <div style={{ color: "#666", display: "flex", gap: 12, flexWrap: "wrap" }}>
                {coTaxId && <span>เลขประจำตัวผู้เสียภาษี: {coTaxId}{coOfficeType ? ` (${coOfficeType})` : ""}</span>}
                {coPhone && <span>โทร: {coPhone}</span>}
              </div>
            </div>
          );
        })()}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
          <div>
            <div style={{ fontSize: 20, fontWeight: 600 }}>ใบสั่งซื้อ</div>
            <div style={{ fontFamily: "monospace", fontSize: 14 }}>{form.poNumber}</div>
          </div>
          <div style={{ fontSize: 13, padding: "4px 10px", border: "1px solid #999", borderRadius: 4 }}>{docCopyLabel}</div>
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", fontSize: 13, marginBottom: 16 }}>
          <div>
            <div style={{ color: "#666" }}>ผู้จำหน่าย</div>
            <div>{vendor?.businessName || vendor?.contactPersonName || "-"}</div>
            <div style={{ whiteSpace: "pre-line", color: "#444" }}>{form.address}</div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div>วันที่: {fmtDate(form.date)}</div>
            <div>เครดิต (วัน): {form.creditDays || 0}</div>
            <div>วันครบกำหนด: {fmtDate(poDueDate(form))}</div>
            <div>ผู้สั่งซื้อ: {form.purchaser || "-"}</div>
          </div>
        </div>
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13, marginBottom: 16 }}>
          <thead>
            <tr style={{ borderBottom: "2px solid #333", textAlign: "left" }}>
              <th style={{ padding: "6px 4px" }}>ลำดับ</th>
              <th style={{ padding: "6px 4px" }}>ชื่อสินค้า / รายละเอียด</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>จำนวน</th>
              <th style={{ padding: "6px 4px" }}>หน่วย</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>ราคาต่อหน่วย</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>ราคารวม</th>
            </tr>
          </thead>
          <tbody>
            {form.lines.filter(l => l.stockItemId).map((l, i) => (
              <tr key={l.id} style={{ borderBottom: "1px solid #ddd" }}>
                <td style={{ padding: "6px 4px" }}>{i + 1}</td>
                <td style={{ padding: "6px 4px" }}>{l.description}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{l.qty}</td>
                <td style={{ padding: "6px 4px" }}>{l.unit}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{fmtMoney(l.unitPrice)}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{fmtMoney(poLineTotal(l))}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <div style={{ display: "flex", justifyContent: "flex-end" }}>
          <div style={{ width: 260, fontSize: 13 }}>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>รวมเป็นเงิน</span><span>{fmtMoney(totals.subtotal)}</span></div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>ส่วนลด</span><span>-{fmtMoney(totals.discountAmt)}</span></div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>ราคาหลังหักส่วนลด</span><span>{fmtMoney(totals.afterDiscount)}</span></div>
            {form.vatEnabled && <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>VAT {form.vatRate}%</span><span>{fmtMoney(totals.vatAmt)}</span></div>}
            <div style={{ display: "flex", justifyContent: "space-between", padding: "6px 0", borderTop: "2px solid #333", fontWeight: 600 }}><span>จำนวนเงินรวมทั้งสิ้น</span><span>฿{fmtMoney(totals.grand)}</span></div>
          </div>
        </div>
        {form.note && <div style={{ fontSize: 12, color: "#666", marginTop: 16 }}>หมายเหตุ: {form.note}</div>}
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: STOCK MANAGEMENT — ใบรับสินค้า
   ========================================================================= */

function GoodsReceiptsPage({ purchaseOrders, setPurchaseOrders, vendors, stockItems, setStockItems, goodsReceipts, setGoodsReceipts, currentBranchId, branches }) {
  const [receivingPoId, setReceivingPoId] = useState(null);
  const [receiveQtys, setReceiveQtys] = useState({}); // lineId -> qty to receive now
  const [taxInvoiceReceipt, setTaxInvoiceReceipt] = useState(null); // the goodsReceipt row being edited
  const [taxInvoiceForm, setTaxInvoiceForm] = useState(null);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  function branchIdForReceipt(gr) {
    if (gr.branchId) return gr.branchId;
    return purchaseOrders.find(p => p.id === gr.poId)?.branchId || null;
  }
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  const receivablePOs = purchaseOrders
    .filter(po => poReceiveStatus(po) !== "received" && poReceiveStatus(po) !== "draft")
    .filter(po => !effectiveBranchId || !po.branchId || po.branchId === effectiveBranchId);
  const visibleGoodsReceipts = goodsReceipts.filter(gr => !effectiveBranchId || !branchIdForReceipt(gr) || branchIdForReceipt(gr) === effectiveBranchId);
  const receivingPo = receivingPoId ? purchaseOrders.find(p => p.id === receivingPoId) : null;

  function openReceive(po) {
    setReceivingPoId(po.id);
    const init = {};
    po.lines.forEach(l => { init[l.id] = String(Math.max(0, (Number(l.qty) || 0) - (Number(l.receivedQty) || 0))); });
    setReceiveQtys(init);
  }
  function confirmReceive() {
    if (!receivingPo) return;
    const receiptLines = [];
    receivingPo.lines.forEach(l => {
      const qty = Number(receiveQtys[l.id]) || 0;
      if (qty > 0) receiptLines.push({ poLineId: l.id, stockItemId: l.stockItemId, qty });
    });
    if (receiptLines.length === 0) return;

    // Update stock levels
    setStockItems(prev => prev.map(s => {
      const line = receiptLines.find(r => r.stockItemId === s.id);
      if (!line) return s;
      if (!currentBranchId) return { ...s, currentStock: s.currentStock + line.qty };
      const existing = s.branchStock?.[currentBranchId] || { currentStock: s.currentStock, minStock: s.minStock };
      return { ...s, branchStock: { ...s.branchStock, [currentBranchId]: { ...existing, currentStock: Math.round((existing.currentStock + line.qty) * 1000) / 1000 } } };
    }));

    // Update PO received quantities
    setPurchaseOrders(prev => prev.map(po => po.id !== receivingPo.id ? po : {
      ...po,
      lines: po.lines.map(l => {
        const r = receiptLines.find(x => x.poLineId === l.id);
        return r ? { ...l, receivedQty: (Number(l.receivedQty) || 0) + r.qty } : l;
      }),
    }));

    // Log the receipt
    if (setGoodsReceipts) {
      setGoodsReceipts(prev => [...prev, {
        id: "gr" + Date.now(), poId: receivingPo.id, poNumber: receivingPo.poNumber,
        branchId: currentBranchId || receivingPo.branchId || null,
        date: new Date().toISOString().slice(0, 10), lines: receiptLines,
      }]);
    }

    setReceivingPoId(null);
  }

  function openTaxInvoice(gr) {
    const po = purchaseOrders.find(p => p.id === gr.poId);
    const v = vendors.find(x => x.id === po?.vendorId);
    setTaxInvoiceReceipt(gr);
    setTaxInvoiceForm(gr.taxInvoice || {
      invoiceNumber: "", invoiceDate: gr.date,
      vendorName: v?.businessName || v?.contactPersonName || "",
      taxId: v?.taxId || "", branch: "สำนักงานใหญ่",
      priceExclVat: "", vatAmount: "",
    });
  }
  function setTF(patch) { setTaxInvoiceForm(prev => ({ ...prev, ...patch })); }
  function saveTaxInvoice() {
    setGoodsReceipts(prev => prev.map(gr => gr.id === taxInvoiceReceipt.id ? { ...gr, taxInvoice: taxInvoiceForm } : gr));
    setTaxInvoiceReceipt(null);
    setTaxInvoiceForm(null);
  }
  function cancelTaxInvoice() {
    setTaxInvoiceReceipt(null);
    setTaxInvoiceForm(null);
  }

  return (
    <div>
      <PageHeader eyebrow="การจัดการสต๊อก" title="ใบรับสินค้า" subtitle="รับสินค้าเข้าคลังตามใบสั่งซื้อ"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ใบสั่งซื้อที่รอรับสินค้า</div>
      <div className="space-y-2 mb-6">
        {receivablePOs.map(po => {
          const v = vendors.find(x => x.id === po.vendorId);
          const status = poReceiveStatus(po);
          const totalQty = po.lines.reduce((s, l) => s + (Number(l.qty) || 0), 0);
          const receivedQty = po.lines.reduce((s, l) => s + (Number(l.receivedQty) || 0), 0);
          return (
            <Card key={po.id} className="p-4 flex items-center justify-between gap-3">
              <div className="min-w-0">
                <div className="font-medium text-stone-800 font-mono">{po.poNumber}</div>
                <div className="text-xs text-stone-400">{v?.businessName || v?.contactPersonName || "-"} · สั่ง {totalQty} รับแล้ว {receivedQty}</div>
              </div>
              <div className="flex items-center gap-3 flex-shrink-0">
                <span className={`text-xs px-2 py-0.5 rounded border font-medium ${PO_STATUS_STYLE[status]}`}>{PO_STATUS_LABEL[status]}</span>
                <Btn onClick={() => openReceive(po)}>รับสินค้า</Btn>
              </div>
            </Card>
          );
        })}
        {receivablePOs.length === 0 && (
          <div className="text-sm text-stone-400 text-center py-10 border border-dashed border-stone-300 rounded-lg">ไม่มีใบสั่งซื้อที่รอรับสินค้า</div>
        )}
      </div>

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ประวัติการรับสินค้า</div>
      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">วันที่รับ</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                <th className="px-4 py-3 font-medium">อ้างอิงใบสั่งซื้อ</th>
                <th className="px-4 py-3 font-medium">รายการที่รับ</th>
                <th className="px-4 py-3 font-medium">ใบกำกับภาษี</th>
              </tr>
            </thead>
            <tbody>
              {visibleGoodsReceipts.slice().reverse().map(gr => (
                <tr key={gr.id} className="border-b border-stone-100 last:border-0">
                  <td className="px-4 py-3 text-stone-400">{fmtDate(gr.date)}</td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchNameFor(branchIdForReceipt(gr)) || "-"}</td>}
                  <td className="px-4 py-3 font-mono text-stone-700">{gr.poNumber}</td>
                  <td className="px-4 py-3 text-stone-600">
                    {gr.lines.map((l, i) => {
                      const item = stockItems.find(s => s.id === l.stockItemId);
                      return <span key={i} className="mr-2">{item?.name || "-"} +{l.qty} {item?.unit}</span>;
                    })}
                  </td>
                  <td className="px-4 py-3">
                    {gr.taxInvoice?.invoiceNumber ? (
                      <button onClick={() => openTaxInvoice(gr)} className="text-xs text-left">
                        <div className="font-mono text-stone-700">{gr.taxInvoice.invoiceNumber}</div>
                        <div className="text-stone-400">{fmtDate(gr.taxInvoice.invoiceDate)} · แก้ไข</div>
                      </button>
                    ) : (
                      <button onClick={() => openTaxInvoice(gr)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1">
                        <Plus size={12} /> บันทึกใบกำกับภาษี
                      </button>
                    )}
                  </td>
                </tr>
              ))}
              {visibleGoodsReceipts.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 4 : 5} className="px-4 py-10 text-center text-stone-400">ยังไม่มีประวัติการรับสินค้า</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Receive popup */}
      {receivingPo && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setReceivingPoId(null)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 font-mono">{receivingPo.poNumber}</div>
              <button onClick={() => setReceivingPoId(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-3">ระบุจำนวนที่รับเข้าจริงของแต่ละรายการ (แก้ไขได้ถ้ารับไม่ครบ)</div>

            <div className="space-y-2">
              {receivingPo.lines.map(l => {
                const item = stockItems.find(s => s.id === l.stockItemId);
                const remaining = Math.max(0, (Number(l.qty) || 0) - (Number(l.receivedQty) || 0));
                return (
                  <div key={l.id} className="p-3 rounded-lg border border-stone-200">
                    <div className="flex items-center justify-between text-sm mb-1.5">
                      <span className="font-medium text-stone-800">{item?.name || l.description}</span>
                      <span className="text-xs text-stone-400">สั่ง {l.qty} · รับแล้ว {l.receivedQty || 0} · เหลือ {remaining} {l.unit}</span>
                    </div>
                    <div className="flex items-center gap-2">
                      <input type="number" step="any" min={0} max={remaining} className={`${inputCls} max-w-[120px]`}
                        value={receiveQtys[l.id] ?? ""} onChange={e => setReceiveQtys(prev => ({ ...prev, [l.id]: e.target.value }))} />
                      <span className="text-xs text-stone-400">{l.unit}</span>
                    </div>
                  </div>
                );
              })}
            </div>
            <Btn className="w-full justify-center mt-4" onClick={confirmReceive}><CheckCircle2 size={14} /> ยืนยันรับสินค้าเข้าคลัง</Btn>
          </div>
          </div>
        </div>
      )}
      {/* Tax invoice popup */}
      {taxInvoiceReceipt && taxInvoiceForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={cancelTaxInvoice}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">ใบกำกับภาษี</div>
              <button onClick={cancelTaxInvoice} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-4">อ้างอิงใบสั่งซื้อ {taxInvoiceReceipt.poNumber} · รับสินค้าวันที่ {fmtDate(taxInvoiceReceipt.date)}</div>

            <div className="space-y-3">
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขที่ใบกำกับภาษี"><input className={inputCls} value={taxInvoiceForm.invoiceNumber} onChange={e => setTF({ invoiceNumber: e.target.value })} /></Field>
                <Field label="วันที่ใบกำกับภาษี"><input type="date" className={inputCls} value={taxInvoiceForm.invoiceDate} onChange={e => setTF({ invoiceDate: e.target.value })} /></Field>
              </div>
              <Field label="ชื่อผู้จำหน่าย"><input className={inputCls} value={taxInvoiceForm.vendorName} onChange={e => setTF({ vendorName: e.target.value })} /></Field>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขประจำตัวผู้เสียภาษี">
                  <input className={inputCls} value={taxInvoiceForm.taxId} onChange={e => setTF({ taxId: e.target.value.replace(/\D/g, "").slice(0, 13) })} placeholder="เลข 13 หลัก" />
                </Field>
                <Field label="สำนักงาน/สาขา"><input className={inputCls} value={taxInvoiceForm.branch} onChange={e => setTF({ branch: e.target.value })} placeholder="เช่น สำนักงานใหญ่ หรือ สาขาที่ 001" /></Field>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="มูลค่าก่อนภาษี"><input type="number" step="any" className={inputCls} value={taxInvoiceForm.priceExclVat} onChange={e => setTF({ priceExclVat: e.target.value })} /></Field>
                <Field label="ภาษีมูลค่าเพิ่ม"><input type="number" step="any" className={inputCls} value={taxInvoiceForm.vatAmount} onChange={e => setTF({ vatAmount: e.target.value })} /></Field>
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-5 pt-4 border-t border-stone-200">
              <Btn variant="ghost" onClick={cancelTaxInvoice}>ยกเลิก</Btn>
              <Btn onClick={saveTaxInvoice}>บันทึก</Btn>
            </div>
          </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: SYSTEM SETTINGS — ช่องทางการเงิน
   ========================================================================= */

function FinanceAccountsPage({ financeAccounts, setFinanceAccounts, staff, currentBranchId, branches, ownerProfile, logActivity }) {
  const [showAddMenu, setShowAddMenu] = useState(false);
  const [formType, setFormType] = useState(null); // "pettyCash" | "bank" | "check" | "creditCard" | "other" | null
  const [form, setForm] = useState(null);
  const [topUpAccount, setTopUpAccount] = useState(null);
  const [deletingAccount, setDeletingAccount] = useState(null);
  const [topUpAmount, setTopUpAmount] = useState("");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleAccounts = financeAccounts.filter(a => !effectiveBranchId || !a.ourBranchId || a.ourBranchId === effectiveBranchId);
  function ourBranchNameFor(id) { return branches?.find(b => b.id === id)?.name; }
  const [savePin, setSavePin] = useState("");
  const [savePinError, setSavePinError] = useState("");
  const [pendingStatusChange, setPendingStatusChange] = useState(null); // { id, status }

  function openAdd(type, channelType) {
    const base = emptyFinanceAccountForm(type, effectiveBranchId);
    setForm(channelType ? { ...base, channelType } : base);
    setFormType(type);
    setShowAddMenu(false);
    setSavePin("");
    setSavePinError("");
  }
  function openEdit(acc) {
    setForm({ ...emptyFinanceAccountForm(acc.type), ...acc, initialBalance: String(acc.initialBalance) });
    setFormType(acc.type);
    setSavePin("");
    setSavePinError("");
  }
  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }
  function closeForm() { setForm(null); setFormType(null); }

  function accountLabel(acc) {
    if (acc.type === "pettyCash") return acc.name || "เงินสดย่อย";
    if (acc.type === "bank") return `${acc.bank} ${acc.accountNumber}`;
    if (acc.type === "check") return `${acc.bank} (เช็คจ่าย) ${acc.accountNumber}`;
    if (acc.type === "creditCard") return `${acc.bank} ${acc.cardName || "บัตรเครดิต"}`;
    if (acc.type === "other") return `${acc.channelType}${acc.deviceName ? " · " + acc.deviceName : ""}`;
    return "-";
  }
  function accountSubLabel(acc) {
    if (acc.type === "pettyCash") return `ผู้รับผิดชอบ: ${acc.responsiblePerson || "-"}`;
    if (acc.type === "bank" || acc.type === "check") return acc.accountName || "-";
    if (acc.type === "creditCard") return acc.cardNumber ? `เลขบัตร: •••• ${acc.cardNumber.slice(-4)}` : "-";
    if (acc.type === "other" && acc.channelType === "พร้อมเพย์") return acc.promptPayId ? `พร้อมเพย์: ${acc.promptPayId}` : "-";
    if (acc.type === "other") return acc.bank || "-";
    return "";
  }
  function accountDetail(acc) {
    if (acc.type === "pettyCash") return `วงเงินสดย่อย: ${fmtMoney(acc.limit)}`;
    if (acc.type === "bank") return `ประเภทบัญชี: ${BANK_ACCOUNT_TYPE_LABEL[acc.accountType]}\nสาขา: ${acc.branch || "-"}`;
    if (acc.type === "check") return acc.checkDetail || "-";
    if (acc.type === "creditCard") return acc.cardDetail || "-";
    if (acc.type === "other" && acc.channelType === "พร้อมเพย์") return acc.otherDetail || "-";
    if (acc.type === "other") return acc.otherDetail || "-";
    return "-";
  }

  function submit() {
    const isOwner = isOwnerPin(ownerProfile, savePin);
    const isStaff = (staff || []).some(s => s.pin === savePin && s.active);
    if (!isOwner && !isStaff) {
      setSavePinError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
      return;
    }
    const payload = { ...form, initialBalance: Number(form.initialBalance) || 0 };
    if (form.id) {
      setFinanceAccounts(prev => prev.map(a => a.id === form.id ? { ...payload, currentBalance: a.currentBalance } : a));
    } else {
      setFinanceAccounts(prev => [...prev, { ...payload, id: "fa" + Date.now(), currentBalance: payload.initialBalance }]);
    }
    closeForm();
  }
  function requestRemoveAccount(acc) {
    setDeletingAccount(acc);
  }
  function confirmRemoveAccount() {
    if (!deletingAccount) return;
    setFinanceAccounts(prev => prev.filter(a => a.id !== deletingAccount.id));
    setDeletingAccount(null);
  }
  function requestAccountStatus(id, status) {
    setPendingStatusChange({ id, status });
  }
  function confirmAccountStatus() {
    if (!pendingStatusChange) return;
    setFinanceAccounts(prev => prev.map(a => a.id === pendingStatusChange.id ? { ...a, status: pendingStatusChange.status } : a));
    setPendingStatusChange(null);
  }
  function confirmTopUp() {
    if (!topUpAccount || !Number(topUpAmount)) return;
    setFinanceAccounts(prev => prev.map(a => a.id === topUpAccount.id ? { ...a, currentBalance: a.currentBalance + Number(topUpAmount) } : a));
    setTopUpAccount(null);
    setTopUpAmount("");
  }

  const ADD_MENU_ITEMS = [
    { type: "pettyCash", label: "บัญชีเงินสดย่อย" },
    { type: "bank", label: "บัญชีธนาคาร" },
    { type: "check", label: "บัญชีเช็คจ่าย" },
    { type: "creditCard", label: "บัตรเครดิตจ่าย" },
    { type: "other", channelType: "พร้อมเพย์", label: "QR พร้อมเพย์" },
    { type: "other", label: "ช่องทางอื่นๆ" },
  ];

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ช่องทางการเงิน" subtitle="จัดการบัญชีเงินสด บัญชีธนาคาร และช่องทางรับ-จ่ายเงินอื่นๆ"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <div className="relative">
              <Btn onClick={() => setShowAddMenu(v => !v)}>เพิ่มบัญชี <ChevronDown size={14} /></Btn>
              {showAddMenu && (
                <div className="absolute right-0 top-full mt-1 bg-white border border-stone-200 rounded-lg shadow-lg z-10 w-52 overflow-hidden">
                  {ADD_MENU_ITEMS.map(item => (
                    <button key={item.label} onClick={() => openAdd(item.type, item.channelType)} className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 border-b border-stone-100 last:border-0">
                      {item.label}
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>
        } />

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">ประเภท</th>
                <th className="px-4 py-3 font-medium">ชื่อบัญชี</th>
                <th className="px-4 py-3 font-medium">รายละเอียดเพิ่มเติม</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขาร้านที่ใช้</th>}
                <th className="px-4 py-3 font-medium">ยอดเงินคงเหลือ</th>
                <th className="px-4 py-3 font-medium">สถานะ</th>
                <th className="px-4 py-3 font-medium"></th>
              </tr>
            </thead>
            <tbody>
              {visibleAccounts.map(acc => (
                <tr key={acc.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50 align-top">
                  <td className="px-4 py-3 text-stone-500">{FINANCE_ACCOUNT_TYPE_LABEL[acc.type]}</td>
                  <td className="px-4 py-3">
                    <div className="font-medium text-stone-800">{accountLabel(acc)}</div>
                    <div className="text-xs text-stone-400">{accountSubLabel(acc)}</div>
                  </td>
                  <td className="px-4 py-3 text-xs text-stone-500 whitespace-pre-line">
                    {accountDetail(acc)}
                    {acc.type === "pettyCash" && (
                      <button onClick={() => setTopUpAccount(acc)} className="flex items-center gap-1 text-sky-600 hover:text-sky-800 mt-1">
                        <Banknote size={12} /> เติมเงินสดย่อย
                      </button>
                    )}
                  </td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{ourBranchNameFor(acc.ourBranchId) || "ทุกสาขา"}</td>}
                  <td className="px-4 py-3 font-mono text-stone-800">฿{fmtMoney(acc.currentBalance)}</td>
                  <td className="px-4 py-3">
                    <select value={acc.status} onChange={e => requestAccountStatus(acc.id, e.target.value)}
                      className={`text-xs px-2 py-1 rounded border font-medium ${acc.status === "active" ? "bg-sky-50 text-sky-700 border-sky-300" : "bg-stone-100 text-stone-500 border-stone-300"}`}>
                      <option value="active">ใช้งานอยู่</option>
                      <option value="inactive">ปิดใช้งาน</option>
                    </select>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-3">
                      <button onClick={() => openEdit(acc)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                      <button onClick={() => requestRemoveAccount(acc)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                    </div>
                  </td>
                </tr>
              ))}
              {financeAccounts.length === 0 && (
                <tr><td colSpan={6} className="px-4 py-10 text-center text-stone-400">ยังไม่มีบัญชีในระบบ</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Add / edit account popup */}
      {form && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={closeForm}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800 text-lg">
                {form.id ? "แก้ไข" : "เพิ่ม"}{FINANCE_ACCOUNT_TYPE_LABEL[formType]}
              </div>
              <button onClick={closeForm} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>

            <div className="space-y-3">
              {branches && branches.length > 0 && (
                <Field label="สาขาร้านที่ใช้บัญชีนี้">
                  <select className={inputCls} value={form.ourBranchId || ""} onChange={e => set({ ourBranchId: e.target.value || null })}>
                    <option value="">ทุกสาขา (ใช้ร่วมกัน)</option>
                    {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
                  </select>
                </Field>
              )}
              {formType === "pettyCash" && (
                <>
                  <Field label="ชื่อวงเงินสดย่อย:"><input className={inputCls} value={form.name} onChange={e => set({ name: e.target.value })} /></Field>
                  <Field label="วงเงินสดย่อย:"><input type="number" className={inputCls} value={form.limit} onChange={e => set({ limit: e.target.value })} placeholder="0.00" /></Field>
                  <Field label="ผู้รับผิดชอบ:">
                    <select className={inputCls} value={form.responsiblePerson} onChange={e => set({ responsiblePerson: e.target.value })}>
                      <option value="">กรุณาเลือกผู้รับผิดชอบ</option>
                      {staff.map(s => <option key={s.id} value={s.name}>{s.name}</option>)}
                    </select>
                  </Field>
                  <Field label="รายละเอียดวงเงิน:"><textarea rows={3} className={inputCls} value={form.limitDetail} onChange={e => set({ limitDetail: e.target.value })} /></Field>
                  <Field label="ยอดเงินตั้งต้น:"><input type="number" className={inputCls} value={form.initialBalance} onChange={e => set({ initialBalance: e.target.value })} /></Field>
                </>
              )}

              {(formType === "bank" || formType === "check") && (
                <>
                  <Field label="ธนาคาร:">
                    <select className={inputCls} value={form.bank} onChange={e => set({ bank: e.target.value })}>
                      <option value="">กรุณาเลือกธนาคาร</option>
                      {THAI_BANKS.map(b => <option key={b} value={b}>{b}</option>)}
                    </select>
                  </Field>
                  <Field label="เลขที่บัญชี:"><input className={inputCls} value={form.accountNumber} onChange={e => set({ accountNumber: e.target.value })} /></Field>
                  <Field label="สาขาธนาคาร:"><input className={inputCls} value={form.branch} onChange={e => set({ branch: e.target.value })} /></Field>
                  <Field label="ชื่อบัญชี:"><input className={inputCls} value={form.accountName} onChange={e => set({ accountName: e.target.value })} /></Field>
                  {formType === "bank" && (
                    <div>
                      <div className="text-xs font-medium text-stone-500 mb-1.5">ประเภทบัญชี:</div>
                      <div className="flex gap-4">
                        {Object.entries(BANK_ACCOUNT_TYPE_LABEL).map(([val, label]) => (
                          <label key={val} className="flex items-center gap-1.5 text-sm text-stone-700 cursor-pointer">
                            <input type="radio" name="accountType" checked={form.accountType === val} onChange={() => set({ accountType: val })} /> {label}
                          </label>
                        ))}
                      </div>
                    </div>
                  )}
                  {formType === "check" && (
                    <Field label="รายละเอียดเช็ค:"><textarea rows={3} className={inputCls} value={form.checkDetail} onChange={e => set({ checkDetail: e.target.value })} /></Field>
                  )}
                  <Field label="ยอดเงินตั้งต้น:"><input type="number" className={inputCls} value={form.initialBalance} onChange={e => set({ initialBalance: e.target.value })} /></Field>
                </>
              )}

              {formType === "creditCard" && (
                <>
                  <Field label="ธนาคารผู้ออกบัตร:">
                    <select className={inputCls} value={form.bank} onChange={e => set({ bank: e.target.value })}>
                      <option value="">กรุณาเลือกธนาคาร</option>
                      {THAI_BANKS.map(b => <option key={b} value={b}>{b}</option>)}
                    </select>
                  </Field>
                  <Field label="ชื่อบัตร:"><input className={inputCls} value={form.cardName} onChange={e => set({ cardName: e.target.value })} placeholder="เช่น บัตรเครดิตธุรกิจ" /></Field>
                  <Field label="เลขบัตร:"><input className={inputCls} value={form.cardNumber} onChange={e => set({ cardNumber: e.target.value.replace(/\D/g, "").slice(0, 16) })} placeholder="1234567812345678" /></Field>
                  <Field label="รายละเอียดเพิ่มเติม:"><textarea rows={3} className={inputCls} value={form.cardDetail} onChange={e => set({ cardDetail: e.target.value })} /></Field>
                </>
              )}

              {formType === "other" && (
                <>
                  <Field label="ช่องทางชำระ:">
                    <select className={inputCls} value={form.channelType} onChange={e => set({ channelType: e.target.value })}>
                      {OTHER_CHANNEL_TYPES.map(t => <option key={t} value={t}>{t}</option>)}
                    </select>
                  </Field>
                  {form.channelType === "พร้อมเพย์" ? (
                    <>
                      <Field label="เบอร์พร้อมเพย์ (10 หลัก) หรือ เลขผู้เสียภาษี/บัตรประชาชน (13 หลัก):">
                        <input className={inputCls} value={form.promptPayId} onChange={e => set({ promptPayId: e.target.value.replace(/[^0-9]/g, "").slice(0, 13) })} placeholder="เช่น 0812345678" />
                      </Field>
                      {form.promptPayId && buildPromptPayPayload(form.promptPayId, 100) ? (
                        <div className="flex items-center gap-3">
                          <img src={promptPayQrImageUrl(form.promptPayId, 100, 100)} alt="ตัวอย่าง QR" className="rounded-lg border border-stone-200" />
                          <span className="text-xs text-stone-400">ตัวอย่าง QR (ยอด ฿100 สำหรับทดสอบ)</span>
                        </div>
                      ) : form.promptPayId ? (
                        <p className="text-xs text-rose-500">ต้องมี 10 หลัก (เบอร์มือถือ) หรือ 13 หลัก (เลขผู้เสียภาษี/บัตรประชาชน)</p>
                      ) : null}
                    </>
                  ) : (
                    <Field label="ธนาคาร:">
                      <select className={inputCls} value={form.bank} onChange={e => set({ bank: e.target.value })}>
                        <option value="">กรุณาเลือกธนาคาร</option>
                        {THAI_BANKS.map(b => <option key={b} value={b}>{b}</option>)}
                      </select>
                    </Field>
                  )}
                  <Field label="ชื่อเครื่อง/เลขซีเรียล:"><input className={inputCls} value={form.deviceName} onChange={e => set({ deviceName: e.target.value })} /></Field>
                  <Field label="รายละเอียดเพิ่มเติม:"><textarea rows={3} className={inputCls} value={form.otherDetail} onChange={e => set({ otherDetail: e.target.value })} /></Field>
                </>
              )}
            </div>

            <div className="mt-4 pt-4 border-t border-stone-200">
              <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก) — ต้องกรอกก่อนบันทึก">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls}
                  value={savePin} onChange={e => { setSavePin(e.target.value.replace(/\D/g, "").slice(0, 6)); setSavePinError(""); }}
                  placeholder="••••••" />
              </Field>
              {savePinError && <div className="text-xs text-rose-500 mt-1">{savePinError}</div>}
            </div>

            <div className="flex justify-end gap-2 mt-4 pt-4 border-t border-stone-200">
              <Btn variant="ghost" onClick={closeForm}>ยกเลิก</Btn>
              <Btn disabled={savePin.length !== 6} onClick={submit}>บันทึกและปิด</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingAccount && (
        <ConfirmDeletePin
          message={`ลบ "${financeAccountDisplayName(deletingAccount)}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingAccount(null)}
          onConfirm={confirmRemoveAccount}
          logActivity={logActivity} activityLabel={`ลบบัญชี ${financeAccountDisplayName(deletingAccount)}`}
        />
      )}

      {/* Confirm status change popup */}
      {pendingStatusChange && (() => {
        const acc = financeAccounts.find(a => a.id === pendingStatusChange.id);
        return (
          <ConfirmDeletePin
            message={`เปลี่ยนสถานะ "${acc ? financeAccountDisplayName(acc) : ""}" เป็น "${pendingStatusChange.status === "active" ? "ใช้งานอยู่" : "ปิดใช้งาน"}" ใช่ไหม?`}
            staff={staff} ownerProfile={ownerProfile}
            onCancel={() => setPendingStatusChange(null)}
            onConfirm={confirmAccountStatus}
            confirmLabel="ยืนยันเปลี่ยนสถานะ"
            logActivity={logActivity} activityLabel={`เปลี่ยนสถานะบัญชี ${acc ? financeAccountDisplayName(acc) : ""} เป็น ${pendingStatusChange.status === "active" ? "ใช้งานอยู่" : "ปิดใช้งาน"}`}
            activityCategory="แก้ไขสถานะ"
          />
        );
      })()}

      {/* Top-up petty cash popup */}
      {topUpAccount && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setTopUpAccount(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เติมเงินสดย่อย</div>
              <button onClick={() => setTopUpAccount(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-3">{topUpAccount.name} · คงเหลือปัจจุบัน ฿{fmtMoney(topUpAccount.currentBalance)}</div>
            <Field label="จำนวนเงินที่เติม"><input type="number" autoFocus className={inputCls} value={topUpAmount} onChange={e => setTopUpAmount(e.target.value)} placeholder="0.00" /></Field>
            <Btn className="w-full justify-center mt-4" onClick={confirmTopUp}>ยืนยันเติมเงิน</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: STOREFRONT — รอบการขาย
   ========================================================================= */

function SalesShiftsPage({ salesShifts, setSalesShifts, financeAccounts, setFinanceAccounts, staff, history, currentBranchId, branches }) {
  const [tab, setTab] = useState("current"); // "current" | "history"
  const [showOpenForm, setShowOpenForm] = useState(false);
  const [openForm, setOpenForm] = useState(null);
  const [closingShift, setClosingShift] = useState(null);
  const [closeForm, setCloseForm] = useState(null);
  const [, forceTick] = useState(0);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;

  const cashAccounts = financeAccounts.filter(a => a.type === "pettyCash" && a.status === "active" && a.name !== "เงินสด");
  const visibleShifts = salesShifts.filter(s => !effectiveBranchId || !s.branchId || s.branchId === effectiveBranchId);
  const currentOpenShift = visibleShifts.find(s => s.status === "open" && (!effectiveBranchId ? true : (s.branchId || null) === effectiveBranchId));
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  // Re-render once a minute so the "elapsed time" readout on an open shift stays fresh.
  useEffect(() => {
    const id = setInterval(() => forceTick(t => t + 1), 60000);
    return () => clearInterval(id);
  }, []);

  function nowLocal() {
    const d = new Date();
    d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
    return d.toISOString().slice(0, 16);
  }
  function entriesDuring(shift, upTo) {
    const startKey = shift.openedAt; // "YYYY-MM-DDTHH:MM"
    const endKey = upTo || nowLocal();
    return history.filter(h => {
      if (!(h.amount > 0)) return false;
      const key = `${h.date}T${h.time || "00:00"}`;
      return key >= startKey && key <= endKey;
    });
  }
  function shiftSummary(shift, upTo) {
    const entries = entriesDuring(shift, upTo);
    const byGroup = {};
    entries.forEach(h => {
      const acc = financeAccounts.find(a => a.id === h.financeAccountId);
      const label = h.financeAccountId ? paymentChannelGroupLabel(acc) : "อื่นๆ";
      byGroup[label] = (byGroup[label] || 0) + h.amount;
    });
    const totalSales = entries.reduce((s, h) => s + h.amount, 0);
    const cashSales = byGroup["เงินสด"] || 0;
    return { entries, billCount: entries.length, totalSales, cashSales, byGroup };
  }
  function elapsedLabel(openedAt) {
    const start = new Date(openedAt);
    const ms = Date.now() - start.getTime();
    const totalMin = Math.max(0, Math.floor(ms / 60000));
    return `${Math.floor(totalMin / 60)} ชม. ${totalMin % 60} นาที`;
  }

  function openTheOpenForm() {
    const acc = cashAccounts[0];
    setOpenForm({
      cashAccountId: acc?.id || "",
      openingCash: acc ? String(acc.currentBalance) : "0",
      openedBy: staff[0]?.name || "",
      note: "",
    });
    setShowOpenForm(true);
  }
  function setOF(patch) { setOpenForm(prev => ({ ...prev, ...patch })); }
  function pickCashAccount(id) {
    const acc = financeAccounts.find(a => a.id === id);
    setOF({ cashAccountId: id, openingCash: acc ? String(acc.currentBalance) : "0" });
  }
  function confirmOpenShift() {
    if (!openForm.cashAccountId || !openForm.openedBy) return;
    setSalesShifts(prev => [...prev, {
      id: "sh" + Date.now(), status: "open", branchId: effectiveBranchId || null,
      cashAccountId: openForm.cashAccountId,
      openedBy: openForm.openedBy, openedAt: nowLocal(),
      openingCash: Number(openForm.openingCash) || 0,
      closedBy: "", closedAt: "", cashSales: "", actualCash: "", note: openForm.note,
    }]);
    setShowOpenForm(false);
  }

  function openCloseForm(shift) {
    const summary = shiftSummary(shift);
    setClosingShift(shift);
    setCloseForm({
      cashSales: String(summary.cashSales),
      actualCash: String(shift.openingCash + summary.cashSales),
      closedBy: shift.openedBy,
      tipAmount: "",
      note: "",
    });
  }
  function setCF(patch) { setCloseForm(prev => ({ ...prev, ...patch })); }
  function confirmCloseShift() {
    if (!closingShift || !closeForm) return;
    const actual = Number(closeForm.actualCash) || 0;
    setSalesShifts(prev => prev.map(s => s.id === closingShift.id ? {
      ...s, status: "closed",
      closedBy: closeForm.closedBy, closedAt: nowLocal(),
      cashSales: Number(closeForm.cashSales) || 0, actualCash: actual, tipAmount: Number(closeForm.tipAmount) || 0, note: closeForm.note,
    } : s));
    // Reconcile the linked cash account to the actual counted amount.
    setFinanceAccounts(prev => prev.map(a => a.id === closingShift.cashAccountId ? { ...a, currentBalance: actual } : a));
    setClosingShift(null);
    setCloseForm(null);
    setTab("history");
  }

  function fmtDateTime(iso) {
    if (!iso) return "-";
    const d = new Date(iso);
    return `${fmtDate(d.toISOString().slice(0, 10))} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
  }
  function accountName(id) {
    const a = financeAccounts.find(x => x.id === id);
    return a?.name || "-";
  }

  return (
    <div>
      <PageHeader eyebrow="หน้าร้าน" title="รอบการขาย" subtitle="เปิด-ปิดรอบการขาย และตรวจนับเงินสดประจำกะ"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <div className="flex gap-1 border-b border-stone-200 mb-5">
        <button onClick={() => setTab("current")}
          className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px ${tab === "current" ? "border-amber-600 text-stone-800" : "border-transparent text-stone-400 hover:text-stone-600"}`}>
          กะปัจจุบัน
        </button>
        <button onClick={() => setTab("history")}
          className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px ${tab === "history" ? "border-amber-600 text-stone-800" : "border-transparent text-stone-400 hover:text-stone-600"}`}>
          ประวัติรอบการขาย
        </button>
      </div>

      {tab === "current" && (
        currentOpenShift ? (() => {
          const summary = shiftSummary(currentOpenShift);
          const expectedCash = currentOpenShift.openingCash + summary.cashSales;
          const groupEntries = Object.entries(summary.byGroup).sort((a, b) => b[1] - a[1]);
          return (
            <Card className="p-5">
              <div className="flex items-center justify-between flex-wrap gap-3 mb-4">
                <div>
                  <div className="flex items-center gap-1.5 text-emerald-600 font-semibold text-sm"><CircleDot size={13} /> กะกำลังดำเนินอยู่ — {currentOpenShift.openedBy}</div>
                  <div className="text-xs text-stone-400 mt-1">
                    เปิดกะเมื่อ {fmtDateTime(currentOpenShift.openedAt)} · ผ่านมา {elapsedLabel(currentOpenShift.openedAt)}
                  </div>
                </div>
              </div>

              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-5">
                <Card className="p-4">
                  <div className="text-xs text-stone-400">ยอดขายรวมกะนี้</div>
                  <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(summary.totalSales)}</div>
                </Card>
                <Card className="p-4">
                  <div className="text-xs text-stone-400">จำนวนบิล</div>
                  <div className="text-2xl font-serif text-stone-900 mt-1">{summary.billCount}</div>
                </Card>
                <Card className="p-4">
                  <div className="text-xs text-stone-400">เงินสดที่ควรมีในลิ้นชัก</div>
                  <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(expectedCash)}</div>
                </Card>
              </div>

              <div className="space-y-0 mb-5">
                {groupEntries.length === 0 && (
                  <div className="text-sm text-stone-400 text-center py-6 border border-dashed border-stone-300 rounded-lg">ยังไม่มียอดขายระหว่างกะนี้</div>
                )}
                {groupEntries.map(([label, amt]) => (
                  <div key={label} className="flex items-center justify-between py-2.5 border-b border-stone-100 last:border-0">
                    <span className="text-sm text-stone-600">{label}</span>
                    <span className="font-mono font-semibold text-stone-800">฿{fmtMoney(amt)}</span>
                  </div>
                ))}
              </div>

              <Btn onClick={() => openCloseForm(currentOpenShift)}><Clock size={14} /> ปิดกะการขาย</Btn>
            </Card>
          );
        })() : (
          <Card className="p-8 text-center">
            <Clock size={28} className="text-stone-300 mx-auto mb-3" />
            <div className="text-sm text-stone-500 mb-4">ยังไม่มีกะที่เปิดอยู่ในตอนนี้</div>
            <Btn onClick={openTheOpenForm}><Plus size={14} /> เปิดกะการขาย</Btn>
          </Card>
        )
      )}

      {tab === "history" && (() => {
        const thisMonthKey = new Date().toISOString().slice(0, 7);
        const tipThisMonth = visibleShifts
          .filter(s => s.status === "closed" && (s.closedAt || "").slice(0, 7) === thisMonthKey)
          .reduce((sum, s) => sum + (Number(s.tipAmount) || 0), 0);

        // Bound each shift's channel breakdown to its own open→close window (or "now" if still open).
        const shiftChannelTotals = {};
        visibleShifts.forEach(s => {
          shiftChannelTotals[s.id] = shiftSummary(s, s.status === "closed" ? s.closedAt : undefined).byGroup;
        });
        // Fixed column order: cash first, then every other channel that appears anywhere, ranked by total volume.
        const otherTotals = {};
        Object.values(shiftChannelTotals).forEach(byGroup => {
          Object.entries(byGroup).forEach(([label, amt]) => {
            if (label === "เงินสด") return;
            otherTotals[label] = (otherTotals[label] || 0) + amt;
          });
        });
        const channelColumns = Object.keys(otherTotals).sort((a, b) => otherTotals[b] - otherTotals[a]);

        return (
        <>
        <Card className="p-4 mb-5 max-w-xs">
          <div className="text-xs text-stone-400">ยอดทิปรวมเดือนนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(tipThisMonth)}</div>
        </Card>
        <Card>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                  <th className="px-4 py-3 font-medium">บัญชีเงินสด</th>
                  {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                  <th className="px-4 py-3 font-medium">เปิดรอบ</th>
                  <th className="px-4 py-3 font-medium">ปิดรอบ</th>
                  <th className="px-4 py-3 font-medium">เงินสดเริ่มต้น</th>
                  <th className="px-4 py-3 font-medium">ยอดขายเงินสด</th>
                  {channelColumns.map(label => <th key={label} className="px-4 py-3 font-medium whitespace-nowrap">{label}</th>)}
                  <th className="px-4 py-3 font-medium">ยอดขายรวม</th>
                  <th className="px-4 py-3 font-medium">คาดว่าควรมี</th>
                  <th className="px-4 py-3 font-medium">นับได้จริง</th>
                  <th className="px-4 py-3 font-medium">ส่วนต่าง</th>
                  <th className="px-4 py-3 font-medium">ทิป</th>
                  <th className="px-4 py-3 font-medium">สถานะ</th>
                </tr>
              </thead>
              <tbody>
                {visibleShifts.slice().reverse().map(s => {
                  const expected = s.status === "closed" ? s.openingCash + s.cashSales : null;
                  const diff = s.status === "closed" ? s.actualCash - expected : null;
                  const byGroup = shiftChannelTotals[s.id] || {};
                  const otherChannelsTotal = channelColumns.reduce((sum, label) => sum + (byGroup[label] || 0), 0);
                  const totalSales = s.status === "closed" ? s.cashSales + otherChannelsTotal : (byGroup["เงินสด"] || 0) + otherChannelsTotal;
                  return (
                    <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                      <td className="px-4 py-3 text-stone-700">{accountName(s.cashAccountId)}</td>
                      {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchNameFor(s.branchId) || "-"}</td>}
                      <td className="px-4 py-3 text-stone-500">{fmtDateTime(s.openedAt)}<div className="text-[11px] text-stone-400">{s.openedBy}</div></td>
                      <td className="px-4 py-3 text-stone-500">{s.status === "closed" ? <>{fmtDateTime(s.closedAt)}<div className="text-[11px] text-stone-400">{s.closedBy}</div></> : "-"}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(s.openingCash)}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">{s.status === "closed" ? `฿${fmtMoney(s.cashSales)}` : "-"}</td>
                      {channelColumns.map(label => (
                        <td key={label} className="px-4 py-3 font-mono text-stone-700 whitespace-nowrap">
                          {byGroup[label] ? `฿${fmtMoney(byGroup[label])}` : "-"}
                        </td>
                      ))}
                      <td className="px-4 py-3 font-mono font-semibold text-stone-800">฿{fmtMoney(totalSales)}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">{expected != null ? `฿${fmtMoney(expected)}` : "-"}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">{s.status === "closed" ? `฿${fmtMoney(s.actualCash)}` : "-"}</td>
                      <td className={`px-4 py-3 font-mono font-medium ${diff > 0 ? "text-emerald-600" : diff < 0 ? "text-rose-600" : "text-stone-400"}`}>
                        {diff != null ? `${diff > 0 ? "+" : ""}฿${fmtMoney(diff)}` : "-"}
                      </td>
                      <td className="px-4 py-3 font-mono text-amber-700">{s.status === "closed" ? `฿${fmtMoney(s.tipAmount || 0)}` : "-"}</td>
                      <td className="px-4 py-3">
                        <span className={`text-xs px-2 py-0.5 rounded border font-medium ${s.status === "open" ? "bg-emerald-50 text-emerald-700 border-emerald-300" : "bg-stone-100 text-stone-500 border-stone-300"}`}>
                          {s.status === "open" ? "กำลังเปิดอยู่" : "ปิดแล้ว"}
                        </span>
                      </td>
                    </tr>
                  );
                })}
                {visibleShifts.length === 0 && (
                  <tr><td colSpan={(!effectiveBranchId ? 12 : 11) + channelColumns.length} className="px-4 py-10 text-center text-stone-400">ยังไม่มีรอบการขาย</td></tr>
                )}
              </tbody>
            </table>
          </div>
        </Card>
        </>
        );
      })()}

      {/* Open shift popup */}
      {showOpenForm && openForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowOpenForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800 text-lg">เปิดกะการขาย</div>
              <button onClick={() => setShowOpenForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            {cashAccounts.length === 0 ? (
              <div className="text-sm text-stone-400 py-4">ยังไม่มีบัญชีเงินสดที่ใช้งานอยู่ กรุณาเพิ่มในหน้า "ช่องทางการเงิน" ก่อน</div>
            ) : (
              <div className="space-y-3">
                <Field label="บัญชีเงินสด">
                  <select className={inputCls} value={openForm.cashAccountId} onChange={e => pickCashAccount(e.target.value)}>
                    {cashAccounts.map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
                  </select>
                </Field>
                <Field label="เงินสดเริ่มต้น"><input type="number" className={inputCls} value={openForm.openingCash} onChange={e => setOF({ openingCash: e.target.value })} /></Field>
                <Field label="ผู้เปิดกะ">
                  <select className={inputCls} value={openForm.openedBy} onChange={e => setOF({ openedBy: e.target.value })}>
                    {staff.map(s => <option key={s.id} value={s.name}>{s.name}</option>)}
                  </select>
                </Field>
                <Field label="หมายเหตุ"><textarea rows={2} className={inputCls} value={openForm.note} onChange={e => setOF({ note: e.target.value })} /></Field>
                <Btn className="w-full justify-center" onClick={confirmOpenShift}>เปิดกะการขาย</Btn>
              </div>
            )}
          </div>
        </div>
      )}

      {/* Close shift popup */}
      {closingShift && closeForm && (() => {
        const expected = closingShift.openingCash + (Number(closeForm.cashSales) || 0);
        const diff = (Number(closeForm.actualCash) || 0) - expected;
        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setClosingShift(null); setCloseForm(null); }}>
            <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800 text-lg">ปิดกะการขาย</div>
                <button onClick={() => { setClosingShift(null); setCloseForm(null); }} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>
              <div className="text-xs text-stone-400 mb-3">
                {accountName(closingShift.cashAccountId)} · เปิดโดย {closingShift.openedBy} · {fmtDateTime(closingShift.openedAt)}
              </div>
              <div className="space-y-3">
                <Field label="เงินสดเริ่มต้น"><input disabled className={`${inputCls} bg-stone-50 text-stone-500`} value={fmtMoney(closingShift.openingCash)} /></Field>
                <Field label="ยอดขายเงินสดระหว่างกะ (คำนวณจากช่องทาง)"><input type="number" className={inputCls} value={closeForm.cashSales} onChange={e => setCF({ cashSales: e.target.value })} /></Field>
                <Field label="ยอดที่ควรมี"><input disabled className={`${inputCls} bg-stone-50 text-stone-500`} value={fmtMoney(expected)} /></Field>
                <Field label="นับเงินสดได้จริง"><input type="number" className={inputCls} value={closeForm.actualCash} onChange={e => setCF({ actualCash: e.target.value })} /></Field>
                <div className={`text-sm font-medium ${diff > 0 ? "text-emerald-600" : diff < 0 ? "text-rose-600" : "text-stone-400"}`}>
                  ส่วนต่าง: {diff > 0 ? "+" : ""}฿{fmtMoney(diff)} {diff > 0 ? "(เงินเกิน)" : diff < 0 ? "(เงินขาด)" : "(ตรงพอดี)"}
                </div>
                <Field label="ผู้ปิดกะ">
                  <select className={inputCls} value={closeForm.closedBy} onChange={e => setCF({ closedBy: e.target.value })}>
                    {staff.map(s => <option key={s.id} value={s.name}>{s.name}</option>)}
                  </select>
                </Field>
                <Field label="ยอดทิป (บาท)"><input type="number" min={0} className={inputCls} value={closeForm.tipAmount} onChange={e => setCF({ tipAmount: e.target.value })} placeholder="0.00" /></Field>
                <Field label="หมายเหตุ"><textarea rows={2} className={inputCls} value={closeForm.note} onChange={e => setCF({ note: e.target.value })} /></Field>
                <Btn className="w-full justify-center" onClick={confirmCloseShift}>ยืนยันปิดกะการขาย</Btn>
              </div>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

/* =========================================================================
   PAGE: ค่าใช้จ่าย
   ========================================================================= */

function emptyExpenseLine() {
  return { id: "exl" + Date.now() + Math.random().toString(36).slice(2, 5), description: "", category: "", qty: "1", unit: "", unitPrice: "" };
}
function emptyExpenseForm() {
  return {
    id: null, expenseNumber: "",
    vendorId: "", address: "",
    date: new Date().toISOString().slice(0, 10), creditDays: "0",
    reference: "", reference2: "", priceMode: "excl",
    lines: [emptyExpenseLine(), emptyExpenseLine(), emptyExpenseLine()],
    discountPercent: "0", vatEnabled: true, vatRate: 7,
    note: "", internalNote: "",
    paymentStatus: "pending", payment: null,
  };
}
/* Thai Social Security maximum monthly deduction schedule (base salary cap × 5%),
   per the government's phased increase announced for BE 2569 onward. */
function socialSecurityCapForYear(buddhistYear) {
  if (buddhistYear >= 2575) return 1150; // ฐานเงินเดือนสูงสุด 23,000 บาท
  if (buddhistYear >= 2572) return 1000; // ฐานเงินเดือนสูงสุด 20,000 บาท
  return 875; // BE 2569-2571: ฐานเงินเดือนสูงสุด 17,500 บาท
}
function nextExpenseNumber(expenses) {
  const now = new Date();
  const prefix = `EXP${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}`;
  const seq = expenses.filter(e => (e.expenseNumber || "").startsWith(prefix)).length + 1;
  return `${prefix}${String(seq).padStart(4, "0")}`;
}

function ExpensesPage({ expenses, setExpenses, vendors, financeAccounts, setFinanceAccounts, currentBranchId, branches, storeInfo, staff, ownerProfile, logActivity }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(emptyExpenseForm());
  const [showShareMenu, setShowShareMenu] = useState(false);
  const [printChoiceMode, setPrintChoiceMode] = useState(null); // "print" | "download" | null
  const [docCopyLabel, setDocCopyLabel] = useState("ต้นฉบับ");
  const [pendingAction, setPendingAction] = useState(null); // "print" | "download" | null
  const [payingExpense, setPayingExpense] = useState(null);
  const [confirmingCancelExpense, setConfirmingCancelExpense] = useState(null);
  const [taxInvoiceExpense, setTaxInvoiceExpense] = useState(null); // the expense row being edited
  const [taxInvoiceForm, setTaxInvoiceForm] = useState(null);
  const [paymentForm, setPaymentForm] = useState(null);
  const [deletingExpense, setDeletingExpense] = useState(null);

  const WHT_RATES = [1, 2, 3, 5, 10, 15];

  useEffect(() => {
    if (pendingAction === "print") {
      printA4Page();
      setPendingAction(null);
    } else if (pendingAction === "download") {
      downloadPrintTemplate(".print-po", `ค่าใช้จ่าย-${form.expenseNumber}-${docCopyLabel}.html`);
      setPendingAction(null);
    }
  }, [pendingAction]);

  function openCreate() {
    setForm({ ...emptyExpenseForm(), expenseNumber: nextExpenseNumber(expenses), branchId: currentBranchId || "" });
    setShowForm(true);
  }
  function openEdit(exp) {
    setForm({ ...exp, lines: exp.lines.length ? exp.lines.map(l => ({ ...l })) : [emptyExpenseLine()] });
    setShowForm(true);
  }
  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }
  function setVendor(vendorId) {
    const v = vendors.find(x => x.id === vendorId);
    set({ vendorId, address: v ? [v.address, v.zipcode].filter(Boolean).join(" ") : "", creditDays: v?.creditDays || "0" });
  }
  function updateLine(idx, patch) {
    setForm(prev => ({ ...prev, lines: prev.lines.map((l, i) => i === idx ? { ...l, ...patch } : l) }));
  }
  function addLine() {
    setForm(prev => ({ ...prev, lines: [...prev.lines, emptyExpenseLine()] }));
  }
  function removeLine(idx) {
    setForm(prev => ({ ...prev, lines: prev.lines.filter((_, i) => i !== idx) }));
  }
  function save() {
    const cleanLines = form.lines.filter(l => l.description && Number(l.qty) > 0);
    if (cleanLines.length === 0) return;
    const payload = { ...form, lines: cleanLines };
    if (form.id) {
      setExpenses(prev => prev.map(e => e.id === form.id ? payload : e));
      setShowForm(false);
    } else {
      const newId = "exp" + Date.now();
      setExpenses(prev => [...prev, { ...payload, id: newId, branchId: payload.branchId || currentBranchId || null }]);
      setForm(prev => ({ ...prev, id: newId }));
      // keep the popup open so the share/print/download buttons (which need a saved id) appear
    }
  }
  function expenseShareText() {
    const v = vendors.find(x => x.id === form.vendorId);
    const t = poComputeTotals(form);
    const lines = form.lines.filter(l => l.description).map(l => `- ${l.description} x${l.qty} ${l.unit} = ฿${fmtMoney(poLineTotal(l))}`).join("\n");
    return `ค่าใช้จ่าย ${form.expenseNumber}\nผู้จำหน่าย: ${v?.businessName || v?.contactPersonName || "-"}\nวันที่: ${fmtDate(form.date)}\n\n${lines}\n\nยอดรวมทั้งสิ้น: ฿${fmtMoney(t.grand)}`;
  }
  function shareCopyText() {
    if (navigator.clipboard) navigator.clipboard.writeText(expenseShareText()).catch(() => {});
    setShowShareMenu(false);
  }
  function chooseCopyAndRun(type) {
    setDocCopyLabel(type);
    const action = printChoiceMode;
    setPrintChoiceMode(null);
    setPendingAction(action);
  }

  const totals = poComputeTotals(form);
  const vendor = vendors.find(v => v.id === form.vendorId);

  function handlePaymentStatusChange(exp, status) {
    if (status === "pending") {
      if (exp.paymentStatus === "paid") {
        setConfirmingCancelExpense(exp);
        return;
      }
      setExpenses(prev => prev.map(e => e.id === exp.id ? { ...e, paymentStatus: "pending" } : e));
      return;
    }
    const grand = poComputeTotals(exp).grand;
    setPayingExpense(exp);
    setPaymentForm({
      paymentDate: new Date().toISOString().slice(0, 10),
      netPaid: String(grand),
      whtEnabled: false, whtPercent: 3,
      paymentMethods: [{ id: "pm" + Date.now(), accountId: financeAccounts[0]?.id || "", amount: String(grand) }],
      note: "",
    });
  }
  function setPF(patch) { setPaymentForm(prev => ({ ...prev, ...patch })); }
  function addPaymentMethodRow() {
    setPaymentForm(prev => ({ ...prev, paymentMethods: [...prev.paymentMethods, { id: "pm" + Date.now() + Math.random().toString(36).slice(2, 5), accountId: financeAccounts[0]?.id || "", amount: "" }] }));
  }
  function updatePaymentMethodRow(id, patch) {
    setPaymentForm(prev => ({ ...prev, paymentMethods: prev.paymentMethods.map(m => m.id === id ? { ...m, ...patch } : m) }));
  }
  function removePaymentMethodRow(id) {
    setPaymentForm(prev => ({ ...prev, paymentMethods: prev.paymentMethods.filter(m => m.id !== id) }));
  }
  function savePayment() {
    if (!payingExpense || !paymentForm) return;
    setExpenses(prev => prev.map(e => e.id === payingExpense.id ? { ...e, paymentStatus: "paid", payment: { ...paymentForm } } : e));
    if (setFinanceAccounts) {
      setFinanceAccounts(prev => prev.map(acc => {
        const paidFromThis = paymentForm.paymentMethods
          .filter(pm => pm.accountId === acc.id)
          .reduce((s, pm) => s + (Number(pm.amount) || 0), 0);
        return paidFromThis > 0 ? { ...acc, currentBalance: acc.currentBalance - paidFromThis } : acc;
      }));
    }
    setPayingExpense(null);
    setPaymentForm(null);
  }
  function confirmCancelPayment() {
    if (!confirmingCancelExpense) return;
    setExpenses(prev => prev.map(e => e.id === confirmingCancelExpense.id ? { ...e, paymentStatus: "pending" } : e));
    if (setFinanceAccounts && confirmingCancelExpense.payment?.paymentMethods) {
      setFinanceAccounts(prev => prev.map(acc => {
        const paidFromThis = confirmingCancelExpense.payment.paymentMethods
          .filter(pm => pm.accountId === acc.id)
          .reduce((s, pm) => s + (Number(pm.amount) || 0), 0);
        return paidFromThis > 0 ? { ...acc, currentBalance: acc.currentBalance + paidFromThis } : acc;
      }));
    }
    setConfirmingCancelExpense(null);
  }
  function confirmRemoveExpense() {
    if (!deletingExpense) return;
    setExpenses(prev => prev.filter(e => e.id !== deletingExpense.id));
    setDeletingExpense(null);
  }

  function openTaxInvoice(exp) {
    const v = vendors.find(x => x.id === exp.vendorId);
    setTaxInvoiceExpense(exp);
    if (exp.taxInvoice) {
      setTaxInvoiceForm(exp.taxInvoice);
    } else {
      const totals = poComputeTotals(exp);
      setTaxInvoiceForm({
        invoiceNumber: "", invoiceDate: exp.date,
        vendorName: v?.businessName || v?.contactPersonName || "",
        taxId: v?.taxId || "", branch: "สำนักงานใหญ่",
        priceExclVat: String(Math.round(totals.priceExclVat * 100) / 100),
        vatAmount: String(Math.round(totals.vatAmt * 100) / 100),
      });
    }
  }
  function setTF(patch) { setTaxInvoiceForm(prev => ({ ...prev, ...patch })); }
  function saveTaxInvoice() {
    setExpenses(prev => prev.map(e => e.id === taxInvoiceExpense.id ? { ...e, taxInvoice: taxInvoiceForm } : e));
    setTaxInvoiceExpense(null);
    setTaxInvoiceForm(null);
  }
  function cancelTaxInvoice() {
    setTaxInvoiceExpense(null);
    setTaxInvoiceForm(null);
  }

  const totalThisMonth = expenses
    .filter(e => e.date.slice(0, 7) === new Date().toISOString().slice(0, 7))
    .reduce((s, e) => s + poComputeTotals(e).grand, 0);

  const exportRows = expenses.map(exp => {
    const v = vendors.find(x => x.id === exp.vendorId);
    const t = poComputeTotals(exp);
    return {
      "เลขที่": exp.expenseNumber, "ผู้จำหน่าย": v?.businessName || v?.contactPersonName || "-",
      "วันที่": fmtDate(exp.date), "ยอดรวม": t.grand, "สถานะการเงิน": exp.paymentStatus === "paid" ? "ชำระเงินแล้ว" : "รอชำระ",
    };
  });

  return (
    <div>
      <PageHeader eyebrow="ค่าใช้จ่าย" title="ค่าใช้จ่าย" subtitle="บันทึกเงินเดือนและค่าใช้จ่ายต่างๆ ของร้าน"
        right={
          <div className="flex items-center gap-2">
            <ExportButton data={exportRows} filename="ค่าใช้จ่าย" sheetName="Expenses" />
            <Btn onClick={openCreate}><Plus size={14} /> สร้างค่าใช้จ่าย</Btn>
          </div>
        } />

      <Card className="p-4 mb-5 max-w-xs">
        <div className="text-xs text-stone-400">ค่าใช้จ่ายรวมเดือนนี้</div>
        <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(totalThisMonth)}</div>
      </Card>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">เลขที่</th>
                <th className="px-4 py-3 font-medium">ผู้จำหน่าย</th>
                <th className="px-4 py-3 font-medium">วันที่</th>
                <th className="px-4 py-3 font-medium">ยอดรวม</th>
                <th className="px-4 py-3 font-medium">การเงิน</th>
                <th className="px-4 py-3 font-medium">ใบกำกับภาษี</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {expenses.map(exp => {
                const v = vendors.find(x => x.id === exp.vendorId);
                const t = poComputeTotals(exp);
                const paymentStatus = exp.paymentStatus || "pending";
                return (
                  <tr key={exp.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 font-mono text-stone-500">{exp.expenseNumber || "-"}</td>
                    <td className="px-4 py-3 font-medium text-stone-800">{v?.businessName || v?.contactPersonName || "-"}</td>
                    <td className="px-4 py-3 text-stone-400">{fmtDate(exp.date)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(t.grand)}</td>
                    <td className="px-4 py-3">
                      <select value={paymentStatus} onChange={e => handlePaymentStatusChange(exp, e.target.value)}
                        className={`text-xs px-2 py-1 rounded border font-medium ${paymentStatus === "paid" ? "bg-emerald-50 text-emerald-700 border-emerald-300" : "bg-amber-50 text-amber-700 border-amber-300"}`}>
                        <option value="pending">รอชำระ</option>
                        <option value="paid">ชำระเงิน</option>
                      </select>
                    </td>
                    <td className="px-4 py-3">
                      {exp.taxInvoice?.invoiceNumber ? (
                        <button onClick={() => openTaxInvoice(exp)} className="text-xs text-left">
                          <div className="font-mono text-stone-700">{exp.taxInvoice.invoiceNumber}</div>
                          <div className="text-stone-400">{fmtDate(exp.taxInvoice.invoiceDate)} · แก้ไข</div>
                        </button>
                      ) : (
                        <button onClick={() => openTaxInvoice(exp)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1">
                          <Plus size={12} /> บันทึกใบกำกับภาษี
                        </button>
                      )}
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-3">
                        <button onClick={() => openEdit(exp)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                        <button onClick={() => setDeletingExpense(exp)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {expenses.length === 0 && (
                <tr><td colSpan={6} className="px-4 py-10 text-center text-stone-400">ยังไม่มีค่าใช้จ่าย</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Expense document form */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setShowForm(false)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-5xl p-6" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-5 pb-4 border-b border-stone-200">
              <div className="flex items-center gap-2">
                <Banknote size={20} className="text-sky-600" />
                <div>
                  <div className="text-xs text-stone-400">{form.id ? "แก้ไขค่าใช้จ่าย" : "สร้างค่าใช้จ่าย"}</div>
                  <div className="font-semibold text-stone-800 text-lg font-mono">{form.expenseNumber}</div>
                </div>
                {currentBranchId ? (
                  <span className="text-xs px-2.5 py-1 rounded-full border font-medium ml-2 bg-amber-50 text-amber-700 border-amber-200">
                    {form.id ? "บันทึกไว้สำหรับสาขา" : "กำลังบันทึกสำหรับสาขา"}: {branches?.find(b => b.id === currentBranchId)?.name || "-"}
                  </span>
                ) : branches && branches.length > 0 ? (
                  <div className="flex items-center gap-1.5 ml-2">
                    <span className="text-xs text-stone-400">สาขา:</span>
                    <select className={`${inputCls} py-1 text-xs max-w-[160px]`} value={form.branchId || ""} onChange={e => set({ branchId: e.target.value || null })}>
                      <option value="">ไม่ผูกกับสาขาใด</option>
                      {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
                    </select>
                  </div>
                ) : null}
              </div>
              <div className="flex items-center gap-2">
                {form.id && (
                  <>
                    <div className="relative">
                      <Btn variant="ghost" onClick={() => setShowShareMenu(v => !v)}><Copy size={14} /> แชร์ค่าใช้จ่าย</Btn>
                      {showShareMenu && (
                        <div className="absolute right-0 top-full mt-1 bg-white border border-stone-200 rounded-lg shadow-lg z-10 w-56 overflow-hidden">
                          <button onClick={shareCopyText} className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2">
                            <Copy size={14} className="text-stone-400" /> คัดลอกเป็นข้อความ
                          </button>
                        </div>
                      )}
                    </div>
                    <Btn variant="ghost" onClick={() => setPrintChoiceMode("print")}><Printer size={14} /> พิมพ์ค่าใช้จ่าย</Btn>
                    <Btn variant="ghost" onClick={() => setPrintChoiceMode("download")}><ReceiptText size={14} /> ดาวน์โหลด</Btn>
                  </>
                )}
                <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600 ml-2"><X size={18} /></button>
              </div>
            </div>

            {!form.id && (
              <div className="text-xs text-amber-600 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2 mb-4">
                บันทึกเอกสารก่อน จึงจะแชร์ พิมพ์ หรือดาวน์โหลดค่าใช้จ่ายนี้ได้
              </div>
            )}

            <div className="grid grid-cols-1 lg:grid-cols-12 gap-8 mb-5">
              <div className="col-span-1 lg:col-span-7 space-y-3">
                <Field label="ชื่อผู้จำหน่าย">
                  <select className={inputCls} value={form.vendorId} onChange={e => setVendor(e.target.value)}>
                    <option value="">เลือกผู้จำหน่าย</option>
                    {vendors.map(v => <option key={v.id} value={v.id}>{v.businessName || v.contactPersonName}</option>)}
                  </select>
                </Field>
                <Field label="ที่อยู่"><textarea rows={5} className={inputCls} value={form.address} onChange={e => set({ address: e.target.value })} placeholder="ที่อยู่ผู้จำหน่าย (ดึงอัตโนมัติเมื่อเลือกผู้จำหน่าย)" /></Field>
              </div>

              <div className="col-span-1 lg:col-span-5">
                <div className="space-y-0">
                  <div className="flex items-center justify-between py-2 border-b border-stone-100">
                    <span className="text-sm text-stone-500 flex-shrink-0">วันที่:</span>
                    <input type="date" className="text-sm text-right border-0 focus:outline-none focus:ring-0 text-stone-700 w-40" value={form.date} onChange={e => set({ date: e.target.value })} />
                  </div>
                  <div className="flex items-center justify-between py-2 border-b border-stone-100">
                    <span className="text-sm text-stone-500 flex-shrink-0">เครดิต (วัน):</span>
                    <input type="number" className="text-sm text-right border-0 focus:outline-none focus:ring-0 text-stone-700 w-40" value={form.creditDays} onChange={e => set({ creditDays: e.target.value })} />
                  </div>
                  <div className="flex items-center justify-between py-2 border-b border-stone-100">
                    <span className="text-sm text-stone-500 flex-shrink-0">วันครบกำหนด:</span>
                    <span className="text-sm text-stone-400 w-40 text-right">{fmtDate(poDueDate(form))}</span>
                  </div>
                  <div className="flex items-center justify-between py-2">
                    <span className="text-sm text-stone-500 flex-shrink-0">สกุลเงิน:</span>
                    <span className="text-sm text-stone-500 w-40 text-right">THB - ไทย</span>
                  </div>
                </div>
              </div>
            </div>

            <div className="pt-4 border-t border-stone-200 space-y-3 mb-3">
              <Field label="รายละเอียด"><input className={inputCls} value={form.reference2 || ""} onChange={e => set({ reference2: e.target.value })} /></Field>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขที่อ้างอิง"><input className={inputCls} value={form.reference} onChange={e => set({ reference: e.target.value })} /></Field>
                <Field label="ราคาสินค้า">
                  <select className={inputCls} value={form.priceMode} onChange={e => set({ priceMode: e.target.value })}>
                    <option value="excl">ราคาไม่รวมภาษี</option>
                    <option value="incl">ราคารวมภาษี</option>
                  </select>
                </Field>
              </div>
            </div>

            <Card className="p-0 overflow-hidden mb-2">
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="bg-blue-950 text-white text-xs uppercase tracking-wide">
                      <th className="px-3 py-2.5 font-medium text-left w-12">ลำดับ</th>
                      <th className="px-3 py-2.5 font-medium text-left">รายละเอียด</th>
                      <th className="px-3 py-2.5 font-medium text-left w-36">หมวดหมู่</th>
                      <th className="px-3 py-2.5 font-medium text-right w-20">จำนวน</th>
                      <th className="px-3 py-2.5 font-medium text-left w-24">หน่วย</th>
                      <th className="px-3 py-2.5 font-medium text-right w-28">ราคาต่อหน่วย</th>
                      <th className="px-3 py-2.5 font-medium text-right w-28">ราคารวม</th>
                      <th className="px-2 py-2.5 w-8"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {form.lines.map((l, i) => (
                      <tr key={l.id} className="border-b border-stone-100 last:border-0">
                        <td className="px-3 py-2 text-stone-400 align-top">{i + 1}</td>
                        <td className="px-3 py-2 align-top">
                          <input className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm" placeholder="รายละเอียด" value={l.description} onChange={e => updateLine(i, { description: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top">
                          <select className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm" value={l.category} onChange={e => updateLine(i, { category: e.target.value })}>
                            <option value="">กรุณาเลือก</option>
                            {EXPENSE_CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
                          </select>
                        </td>
                        <td className="px-3 py-2 align-top">
                          <input type="number" step="any" className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={l.qty} onChange={e => updateLine(i, { qty: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top">
                          <input className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm" placeholder="หน่วย" value={l.unit} onChange={e => updateLine(i, { unit: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top">
                          <input type="number" step="any" className="w-full rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={l.unitPrice} onChange={e => updateLine(i, { unitPrice: e.target.value })} />
                        </td>
                        <td className="px-3 py-2 align-top text-right font-mono text-stone-700">{fmtMoney(poLineTotal(l))}</td>
                        <td className="px-2 py-2 align-top text-center">
                          <button onClick={() => removeLine(i)} className="text-stone-300 hover:text-rose-500"><X size={14} /></button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </Card>
            <button onClick={addLine} className="text-xs font-medium text-sky-700 hover:text-sky-900 flex items-center gap-1 mb-5">
              <Plus size={12} /> เพิ่มแถวรายการ
            </button>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
              <div className="space-y-3">
                <Field label="หมายเหตุ"><textarea rows={3} className={inputCls} value={form.note} onChange={e => set({ note: e.target.value })} /></Field>
                <Field label="โน้ตภายในบริษัท"><textarea rows={3} className={inputCls} value={form.internalNote} onChange={e => set({ internalNote: e.target.value })} /></Field>
              </div>
              <div className="space-y-1.5 text-sm">
                <div className="flex items-center justify-between"><span className="text-stone-500">รวมเป็นเงิน</span><span className="font-mono">{fmtMoney(totals.subtotal)}</span></div>
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">ส่วนลด</span>
                  <span className="flex items-center gap-2">
                    <input type="number" className="w-16 rounded-md border border-stone-300 px-2 py-1 text-sm text-right" value={form.discountPercent} onChange={e => set({ discountPercent: e.target.value })} /> %
                    <span className="font-mono w-20 text-right">-{fmtMoney(totals.discountAmt)}</span>
                  </span>
                </div>
                <div className="flex items-center justify-between"><span className="text-stone-500">ราคาหลังหักส่วนลด</span><span className="font-mono">{fmtMoney(totals.afterDiscount)}</span></div>

                {form.priceMode === "incl" ? (
                  <>
                    <div className="flex items-center justify-between pt-2 border-t border-stone-200 font-semibold text-stone-800">
                      <span>จำนวนเงินรวมทั้งสิ้น</span><span className="font-mono text-lg text-sky-700">฿{fmtMoney(totals.grand)}</span>
                    </div>
                    <div className="h-2" />
                    <label className="flex items-center justify-between cursor-pointer">
                      <span className="flex items-center gap-1.5 text-stone-500"><input type="checkbox" checked={form.vatEnabled} onChange={e => set({ vatEnabled: e.target.checked })} /> ภาษีมูลค่าเพิ่ม {form.vatRate}%</span>
                      <span className="font-mono">{fmtMoney(totals.vatAmt)}</span>
                    </label>
                    <div className="flex items-center justify-between"><span className="text-stone-500">ราคาไม่รวมภาษีมูลค่าเพิ่ม</span><span className="font-mono">{fmtMoney(totals.priceExclVat)}</span></div>
                  </>
                ) : (
                  <>
                    <label className="flex items-center justify-between cursor-pointer">
                      <span className="flex items-center gap-1.5 text-stone-500"><input type="checkbox" checked={form.vatEnabled} onChange={e => set({ vatEnabled: e.target.checked })} /> ภาษีมูลค่าเพิ่ม {form.vatRate}%</span>
                      <span className="font-mono">{fmtMoney(totals.vatAmt)}</span>
                    </label>
                    <div className="flex items-center justify-between pt-2 border-t border-stone-200 font-semibold text-stone-800">
                      <span>จำนวนเงินรวมทั้งสิ้น</span><span className="font-mono text-lg text-sky-700">฿{fmtMoney(totals.grand)}</span>
                    </div>
                  </>
                )}
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-6 pt-5 border-t border-stone-200">
              <Btn variant="ghost" onClick={() => setShowForm(false)}>ปิดหน้าต่าง</Btn>
              <Btn onClick={save}>บันทึกเอกสาร</Btn>
            </div>
          </div>
          </div>
        </div>
      )}

      {/* Print / download copy-type choice */}
      {printChoiceMode && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setPrintChoiceMode(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{printChoiceMode === "print" ? "พิมพ์ค่าใช้จ่าย" : "ดาวน์โหลดค่าใช้จ่าย"}</div>
              <button onClick={() => setPrintChoiceMode(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-3">เลือกประเภทเอกสารที่ต้องการ</div>
            <div className="space-y-2">
              <button onClick={() => chooseCopyAndRun("ต้นฉบับ")} className="w-full text-left px-3 py-2.5 rounded-lg border border-stone-200 hover:border-sky-400 text-sm text-stone-700">ต้นฉบับ</button>
              <button onClick={() => chooseCopyAndRun("สำเนา")} className="w-full text-left px-3 py-2.5 rounded-lg border border-stone-200 hover:border-sky-400 text-sm text-stone-700">สำเนา</button>
            </div>
            {printChoiceMode === "download" && (
              <p className="text-[11px] text-stone-400 mt-3">จะดาวน์โหลดเป็นไฟล์ .html ที่เปิดดู/พิมพ์เป็น PDF เองภายหลังได้</p>
            )}
          </div>
        </div>
      )}

      {/* Confirm cancelling a payment */}
      {confirmingCancelExpense && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setConfirmingCancelExpense(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">คุณต้องการยกเลิกการชำระเงินใช่ไหม</div>
            <div className="text-sm text-stone-400 mb-4">ค่าใช้จ่าย {confirmingCancelExpense.expenseNumber} จะเปลี่ยนสถานะกลับเป็น "รอชำระ"</div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setConfirmingCancelExpense(null)}>ยกเลิก</Btn>
              <Btn onClick={confirmCancelPayment}>ยืนยัน</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Record payment popup */}
      {payingExpense && paymentForm && (() => {
        const grand = poComputeTotals(payingExpense).grand;
        const v = vendors.find(x => x.id === payingExpense.vendorId);
        const whtAmount = paymentForm.whtEnabled ? Math.round(grand * (paymentForm.whtPercent / 100) * 100) / 100 : 0;
        function toggleWht(enabled) {
          if (enabled) {
            const amt = Math.round(grand * (paymentForm.whtPercent / 100) * 100) / 100;
            const net = Math.round((grand - amt) * 100) / 100;
            setPaymentForm(prev => ({ ...prev, whtEnabled: true, netPaid: String(net) }));
          } else {
            setPaymentForm(prev => ({ ...prev, whtEnabled: false, netPaid: String(grand) }));
          }
        }
        function changeWhtPercent(percent) {
          const amt = Math.round(grand * (percent / 100) * 100) / 100;
          const net = Math.round((grand - amt) * 100) / 100;
          setPaymentForm(prev => ({ ...prev, whtPercent: percent, netPaid: String(net) }));
        }
        return (
          <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => { setPayingExpense(null); setPaymentForm(null); }}>
            <div className="bg-white rounded-xl w-full max-w-md p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-between mb-4">
                <div className="font-semibold text-stone-800 text-lg">บันทึกการชำระเงิน</div>
                <button onClick={() => { setPayingExpense(null); setPaymentForm(null); }} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>

              <div className="space-y-2 text-sm mb-4">
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">เลขที่เอกสาร:</span>
                  <span className="font-medium text-stone-800 text-right">{payingExpense.expenseNumber} ({v?.businessName || v?.contactPersonName || "-"})</span>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-stone-500">ยอดที่ต้องชำระ:</span>
                  <span className="font-medium text-stone-800">{fmtMoney(grand)} บาท</span>
                </div>
              </div>

              <div className="space-y-3">
                <Field label="วันที่ชำระ"><input type="date" className={inputCls} value={paymentForm.paymentDate} onChange={e => setPF({ paymentDate: e.target.value })} /></Field>
                <Field label="ยอดจ่ายสุทธิ"><input type="number" className={inputCls} value={paymentForm.netPaid} onChange={e => setPF({ netPaid: e.target.value })} /></Field>

                <label className="flex items-center gap-2 text-sm text-stone-700 cursor-pointer">
                  <input type="checkbox" checked={paymentForm.whtEnabled} onChange={e => toggleWht(e.target.checked)} /> หัก ณ ที่จ่าย
                </label>
                {paymentForm.whtEnabled && (
                  <div className="flex items-center gap-2">
                    <select className={`${inputCls} max-w-[110px]`} value={paymentForm.whtPercent} onChange={e => changeWhtPercent(Number(e.target.value))}>
                      {WHT_RATES.map(r => <option key={r} value={r}>{r}%</option>)}
                    </select>
                    <input disabled className={`${inputCls} bg-stone-50 text-stone-500`} value={fmtMoney(whtAmount)} />
                  </div>
                )}

                <div className="text-sm font-semibold text-sky-700 pt-2 border-t border-stone-200">วิธีการชำระ</div>
                <div className="space-y-2">
                  {paymentForm.paymentMethods.map(pm => (
                    <div key={pm.id} className="flex items-center gap-2">
                      <select className="flex-1 min-w-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={pm.accountId} onChange={e => updatePaymentMethodRow(pm.id, { accountId: e.target.value })}>
                        {financeAccounts.map(acc => <option key={acc.id} value={acc.id}>{financeAccountDisplayName(acc)}</option>)}
                      </select>
                      <input type="number" className="w-28 flex-shrink-0 rounded-md border border-stone-300 px-3 py-2 text-sm text-stone-800 focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-amber-400" value={pm.amount} onChange={e => updatePaymentMethodRow(pm.id, { amount: e.target.value })} placeholder="จำนวนเงิน" />
                      <button onClick={() => removePaymentMethodRow(pm.id)} disabled={paymentForm.paymentMethods.length <= 1}
                        className={`flex-shrink-0 ${paymentForm.paymentMethods.length <= 1 ? "text-stone-200" : "text-stone-300 hover:text-rose-500"}`}>
                        <X size={14} />
                      </button>
                    </div>
                  ))}
                </div>
                <button onClick={addPaymentMethodRow} className="text-xs font-medium text-sky-700 hover:text-sky-900 flex items-center gap-1">
                  <Plus size={12} /> เพิ่มวิธีการชำระ
                </button>
                {(() => {
                  const paidTotal = paymentForm.paymentMethods.reduce((s, m) => s + (Number(m.amount) || 0), 0);
                  const diff = Math.round((Number(paymentForm.netPaid || 0) - paidTotal) * 100) / 100;
                  if (diff === 0) return <div className="text-xs text-emerald-600">ยอดรวมวิธีการชำระตรงกับยอดจ่ายสุทธิแล้ว ({fmtMoney(paidTotal)})</div>;
                  return <div className="text-xs text-amber-600">รวมวิธีการชำระ {fmtMoney(paidTotal)} — {diff > 0 ? `ขาดอีก ${fmtMoney(diff)}` : `เกินไป ${fmtMoney(Math.abs(diff))}`}</div>;
                })()}

                <div className="text-sm font-semibold text-sky-700 pt-2 border-t border-stone-200">รายละเอียดเพิ่มเติม</div>
                <Field label="หมายเหตุ:"><textarea rows={3} className={inputCls} value={paymentForm.note} onChange={e => setPF({ note: e.target.value })} /></Field>
              </div>

              <div className="flex justify-end gap-2 mt-5">
                <Btn variant="ghost" onClick={() => { setPayingExpense(null); setPaymentForm(null); }}>ยกเลิก</Btn>
                <Btn onClick={savePayment}>บันทึก</Btn>
              </div>
            </div>
          </div>
        );
      })()}

      {/* Hidden printable expense document */}
      <div className="print-po">
        {(() => {
          const expBranch = branches?.find(b => b.id === form.branchId);
          const coName = expBranch?.companyName || storeInfo?.name;
          const coAddress = expBranch?.companyAddress || storeInfo?.address;
          const coTaxId = expBranch?.taxId || storeInfo?.taxId;
          const coPhone = expBranch?.phone || storeInfo?.phone;
          const coOfficeType = expBranch?.officeType;
          return (coName || coAddress || coTaxId) && (
            <div style={{ marginBottom: 16, paddingBottom: 12, borderBottom: "1px solid #ddd", fontSize: 13 }}>
              <div style={{ fontSize: 16, fontWeight: 600 }}>{coName}</div>
              {coAddress && <div style={{ color: "#444" }}>{coAddress}</div>}
              <div style={{ color: "#666", display: "flex", gap: 12, flexWrap: "wrap" }}>
                {coTaxId && <span>เลขประจำตัวผู้เสียภาษี: {coTaxId}{coOfficeType ? ` (${coOfficeType})` : ""}</span>}
                {coPhone && <span>โทร: {coPhone}</span>}
              </div>
            </div>
          );
        })()}
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
          <div>
            <div style={{ fontSize: 20, fontWeight: 600 }}>ค่าใช้จ่าย</div>
            <div style={{ fontFamily: "monospace", fontSize: 14 }}>{form.expenseNumber}</div>
          </div>
          <div style={{ fontSize: 13, padding: "4px 10px", border: "1px solid #999", borderRadius: 4 }}>{docCopyLabel}</div>
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", fontSize: 13, marginBottom: 16 }}>
          <div>
            <div style={{ color: "#666" }}>ผู้จำหน่าย</div>
            <div>{vendor?.businessName || vendor?.contactPersonName || "-"}</div>
            <div style={{ whiteSpace: "pre-line", color: "#444" }}>{form.address}</div>
          </div>
          <div style={{ textAlign: "right" }}>
            <div>วันที่: {fmtDate(form.date)}</div>
            <div>เครดิต (วัน): {form.creditDays || 0}</div>
            <div>วันครบกำหนด: {fmtDate(poDueDate(form))}</div>
          </div>
        </div>
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13, marginBottom: 16 }}>
          <thead>
            <tr style={{ borderBottom: "2px solid #333", textAlign: "left" }}>
              <th style={{ padding: "6px 4px" }}>ลำดับ</th>
              <th style={{ padding: "6px 4px" }}>รายละเอียด</th>
              <th style={{ padding: "6px 4px" }}>หมวดหมู่</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>จำนวน</th>
              <th style={{ padding: "6px 4px" }}>หน่วย</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>ราคาต่อหน่วย</th>
              <th style={{ padding: "6px 4px", textAlign: "right" }}>ราคารวม</th>
            </tr>
          </thead>
          <tbody>
            {form.lines.filter(l => l.description).map((l, i) => (
              <tr key={l.id} style={{ borderBottom: "1px solid #ddd" }}>
                <td style={{ padding: "6px 4px" }}>{i + 1}</td>
                <td style={{ padding: "6px 4px" }}>{l.description}</td>
                <td style={{ padding: "6px 4px" }}>{l.category}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{l.qty}</td>
                <td style={{ padding: "6px 4px" }}>{l.unit}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{fmtMoney(l.unitPrice)}</td>
                <td style={{ padding: "6px 4px", textAlign: "right" }}>{fmtMoney(poLineTotal(l))}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <div style={{ display: "flex", justifyContent: "flex-end" }}>
          <div style={{ width: 260, fontSize: 13 }}>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>รวมเป็นเงิน</span><span>{fmtMoney(totals.subtotal)}</span></div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>ส่วนลด</span><span>-{fmtMoney(totals.discountAmt)}</span></div>
            <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>ราคาหลังหักส่วนลด</span><span>{fmtMoney(totals.afterDiscount)}</span></div>
            {form.vatEnabled && <div style={{ display: "flex", justifyContent: "space-between", padding: "3px 0" }}><span>VAT {form.vatRate}%</span><span>{fmtMoney(totals.vatAmt)}</span></div>}
            <div style={{ display: "flex", justifyContent: "space-between", padding: "6px 0", borderTop: "2px solid #333", fontWeight: 600 }}><span>จำนวนเงินรวมทั้งสิ้น</span><span>฿{fmtMoney(totals.grand)}</span></div>
          </div>
        </div>
        {form.note && <div style={{ fontSize: 12, color: "#666", marginTop: 16 }}>หมายเหตุ: {form.note}</div>}
      </div>

      {/* Confirm delete popup */}
      {deletingExpense && (
        <ConfirmDeletePin
          message={`ลบ "${deletingExpense.expenseNumber}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingExpense(null)}
          onConfirm={confirmRemoveExpense}
          logActivity={logActivity} activityLabel={`ลบค่าใช้จ่าย ${deletingExpense.expenseNumber}`} activityCategory="การเงิน"
        />
      )}

      {/* Tax invoice popup */}
      {taxInvoiceExpense && taxInvoiceForm && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={cancelTaxInvoice}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">ใบกำกับภาษี</div>
              <button onClick={cancelTaxInvoice} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-4">อ้างอิงค่าใช้จ่าย {taxInvoiceExpense.expenseNumber}</div>

            <div className="space-y-3">
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขที่ใบกำกับภาษี"><input className={inputCls} value={taxInvoiceForm.invoiceNumber} onChange={e => setTF({ invoiceNumber: e.target.value })} /></Field>
                <Field label="วันที่ใบกำกับภาษี"><input type="date" className={inputCls} value={taxInvoiceForm.invoiceDate} onChange={e => setTF({ invoiceDate: e.target.value })} /></Field>
              </div>
              <Field label="ชื่อผู้จำหน่าย"><input className={inputCls} value={taxInvoiceForm.vendorName} onChange={e => setTF({ vendorName: e.target.value })} /></Field>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="เลขประจำตัวผู้เสียภาษี">
                  <input className={inputCls} value={taxInvoiceForm.taxId} onChange={e => setTF({ taxId: e.target.value.replace(/\D/g, "").slice(0, 13) })} placeholder="เลข 13 หลัก" />
                </Field>
                <Field label="สำนักงาน/สาขา"><input className={inputCls} value={taxInvoiceForm.branch} onChange={e => setTF({ branch: e.target.value })} placeholder="เช่น สำนักงานใหญ่ หรือ สาขาที่ 001" /></Field>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <Field label="มูลค่าก่อนภาษี"><input type="number" step="any" className={inputCls} value={taxInvoiceForm.priceExclVat} onChange={e => setTF({ priceExclVat: e.target.value })} /></Field>
                <Field label="ภาษีมูลค่าเพิ่ม"><input type="number" step="any" className={inputCls} value={taxInvoiceForm.vatAmount} onChange={e => setTF({ vatAmount: e.target.value })} /></Field>
              </div>
            </div>

            <div className="flex justify-end gap-2 mt-5 pt-4 border-t border-stone-200">
              <Btn variant="ghost" onClick={cancelTaxInvoice}>ยกเลิก</Btn>
              <Btn onClick={saveTaxInvoice}>บันทึก</Btn>
            </div>
          </div>
          </div>
        </div>
      )}
    </div>
  );
}


/* =========================================================================
   PAGE: ภาพรวม — แดชบอร์ด
   ========================================================================= */

function DashboardPage({ history, orderHistory, expenses, stockItems, members, setActive, branches, currentBranchId }) {
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode (currentBranchId is null)
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const now = new Date();
  const todayStr = now.toISOString().slice(0, 10);
  const thisMonthKey = todayStr.slice(0, 7);
  const lastMonthDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
  const lastMonthKey = `${lastMonthDate.getFullYear()}-${String(lastMonthDate.getMonth() + 1).padStart(2, "0")}`;

  const historyInScope = effectiveBranchId ? history.filter(h => h.branchId === effectiveBranchId) : history;
  const orderHistoryInScope = effectiveBranchId ? orderHistory.filter(o => o.branchId === effectiveBranchId) : orderHistory;
  const expensesInScope = effectiveBranchId ? expenses.filter(e => e.branchId === effectiveBranchId) : expenses;

  const salesToday = historyInScope.filter(h => h.amount > 0 && h.date === todayStr).reduce((s, h) => s + h.amount, 0);
  const billsToday = historyInScope.filter(h => h.amount > 0 && h.date === todayStr).length;
  const salesThisMonth = historyInScope.filter(h => h.amount > 0 && h.date.slice(0, 7) === thisMonthKey).reduce((s, h) => s + h.amount, 0);
  const salesLastMonth = historyInScope.filter(h => h.amount > 0 && h.date.slice(0, 7) === lastMonthKey).reduce((s, h) => s + h.amount, 0);
  const salesChangePct = salesLastMonth > 0 ? Math.round(((salesThisMonth - salesLastMonth) / salesLastMonth) * 1000) / 10 : null;

  const expensesThisMonth = expensesInScope
    .filter(e => e.date.slice(0, 7) === thisMonthKey)
    .reduce((s, e) => s + poComputeTotals(e).grand, 0);
  const grossProfit = salesThisMonth - expensesThisMonth;

  // Top-selling items (all recorded orders, member and walk-in alike)
  const itemTotals = {};
  orderHistoryInScope.forEach(o => o.items.forEach(it => { itemTotals[it.name] = (itemTotals[it.name] || 0) + it.qty; }));
  const topItems = Object.entries(itemTotals).sort((a, b) => b[1] - a[1]).slice(0, 5);
  const maxItemQty = Math.max(1, ...topItems.map(([, q]) => q));

  // Peak hours
  const bucketCounts = TIME_BUCKETS.map(b => ({ ...b, count: 0 }));
  orderHistoryInScope.forEach(o => {
    const hour = Number((o.time || "00:00").split(":")[0]);
    const bucket = bucketCounts.find(b => hour >= b.from && hour < b.to) || bucketCounts.find(b => b.key === "night");
    if (bucket) bucket.count++;
  });
  const maxBucketCount = Math.max(1, ...bucketCounts.map(b => b.count));

  // Last 7 days trend
  const last7 = [];
  for (let i = 6; i >= 0; i--) {
    const d = new Date();
    d.setDate(d.getDate() - i);
    const key = d.toISOString().slice(0, 10);
    const total = historyInScope.filter(h => h.amount > 0 && h.date === key).reduce((s, h) => s + h.amount, 0);
    last7.push({ key, label: `${d.getDate()}/${d.getMonth() + 1}`, total });
  }
  const maxDayTotal = Math.max(1, ...last7.map(d => d.total));

  const lowStockCount = stockItems.filter(s => stockQtyFor(s, effectiveBranchId) <= stockMinFor(s, effectiveBranchId)).length;

  const branchBreakdown = (branches || []).filter(b => b.active).map(b => {
    const sales = history.filter(h => h.branchId === b.id && h.amount > 0 && h.date.slice(0, 7) === thisMonthKey).reduce((s, h) => s + h.amount, 0);
    const exp = expenses.filter(e => e.branchId === b.id && e.date.slice(0, 7) === thisMonthKey).reduce((s, e) => s + poComputeTotals(e).grand, 0);
    return { branch: b, sales, exp, profit: sales - exp };
  });

  return (
    <div>
      <PageHeader eyebrow="ภาพรวม" title="แดชบอร์ด" subtitle="สรุปภาพรวมยอดขาย เมนูขายดี และผลประกอบการของร้าน"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[200px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา (รวม)</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : currentBranchId && branches ? (
          <span className="text-xs px-3 py-1.5 rounded-full bg-stone-100 text-stone-600 font-medium">{branches.find(b => b.id === currentBranchId)?.name}</span>
        ) : null} />

      <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 mb-6">
        <Card className="p-4">
          <div className="text-xs text-stone-400">ยอดขายวันนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(salesToday)}</div>
          <div className="text-[11px] text-stone-400 mt-0.5">{billsToday} บิล</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">ยอดขายเดือนนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(salesThisMonth)}</div>
          {salesChangePct != null && (
            <div className={`text-[11px] mt-0.5 ${salesChangePct >= 0 ? "text-emerald-600" : "text-rose-500"}`}>
              {salesChangePct >= 0 ? "▲" : "▼"} {Math.abs(salesChangePct)}% จากเดือนก่อน
            </div>
          )}
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">ค่าใช้จ่ายเดือนนี้</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(expensesThisMonth)}</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">กำไรขั้นต้นโดยประมาณ</div>
          <div className={`text-2xl font-serif mt-1 ${grossProfit >= 0 ? "text-stone-900" : "text-rose-600"}`}>฿{fmtMoney(grossProfit)}</div>
          <div className="text-[11px] text-stone-400 mt-0.5">ยอดขาย − ค่าใช้จ่าย (ไม่รวมต้นทุนวัตถุดิบ)</div>
        </Card>
      </div>

      {lowStockCount > 0 && (
        <Card className="p-4 mb-6 border-rose-200 bg-rose-50 flex items-center justify-between flex-wrap gap-3">
          <div className="flex items-center gap-2 text-rose-600 text-sm font-medium">
            <AlertTriangle size={16} /> มีสินค้าใกล้หมด {lowStockCount} รายการ
          </div>
          <Btn variant="ghost" onClick={() => setActive("stockItems")}>ดูรายการสินค้า</Btn>
        </Card>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5 mb-6">
        <Card className="p-5">
          <div className="text-sm font-semibold text-stone-700 mb-4">ยอดขาย 7 วันล่าสุด</div>
          <div className="flex items-end gap-2 h-32">
            {last7.map(d => (
              <div key={d.key} className="flex-1 flex flex-col items-center justify-end h-full">
                <div className="text-[10px] text-stone-400 mb-1">{d.total > 0 ? fmtMoney(d.total) : ""}</div>
                <div className="w-full bg-amber-400 rounded-t" style={{ height: `${(d.total / maxDayTotal) * 100}%`, minHeight: d.total > 0 ? 4 : 0 }} />
                <div className="text-[11px] text-stone-400 mt-1">{d.label}</div>
              </div>
            ))}
          </div>
        </Card>

        <Card className="p-5">
          <div className="text-sm font-semibold text-stone-700 mb-4">ช่วงเวลาขายดี</div>
          <div className="space-y-2">
            {bucketCounts.map(b => (
              <div key={b.key} className="flex items-center gap-2 text-xs">
                <span className="w-40 flex-shrink-0 text-stone-500">{b.label}</span>
                <div className="flex-1 h-2 rounded-full bg-stone-100 overflow-hidden">
                  <div className="h-full bg-sky-500 rounded-full" style={{ width: `${(b.count / maxBucketCount) * 100}%` }} />
                </div>
                <span className="w-6 text-right font-mono text-stone-400 flex-shrink-0">{b.count}</span>
              </div>
            ))}
          </div>
        </Card>
      </div>

      <Card className="p-5">
        <div className="text-sm font-semibold text-stone-700 mb-4">เมนูขายดี 5 อันดับแรก</div>
        {topItems.length === 0 ? (
          <div className="text-sm text-stone-400 text-center py-6">ยังไม่มีข้อมูลการสั่งอาหาร</div>
        ) : (
          <div className="space-y-2">
            {topItems.map(([name, qty], i) => (
              <div key={name} className="flex items-center gap-3">
                <span className="w-5 text-sm text-stone-400 flex-shrink-0">{i + 1}</span>
                <span className="w-40 flex-shrink-0 text-sm text-stone-700 truncate">{name}</span>
                <div className="flex-1 h-2 rounded-full bg-stone-100 overflow-hidden">
                  <div className="h-full bg-amber-500 rounded-full" style={{ width: `${(qty / maxItemQty) * 100}%` }} />
                </div>
                <span className="w-16 text-right text-xs font-mono text-stone-500 flex-shrink-0">{qty} ครั้ง</span>
              </div>
            ))}
          </div>
        )}
      </Card>

      {branchBreakdown.length > 1 && (
        <Card className="p-5 mt-5">
          <div className="text-sm font-semibold text-stone-700 mb-4">เปรียบเทียบรายสาขา (เดือนนี้)</div>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                  <th className="px-3 py-2 font-medium">สาขา</th>
                  <th className="px-3 py-2 font-medium">ยอดขาย</th>
                  <th className="px-3 py-2 font-medium">ค่าใช้จ่าย</th>
                  <th className="px-3 py-2 font-medium">กำไรขั้นต้น</th>
                </tr>
              </thead>
              <tbody>
                {branchBreakdown.map(row => (
                  <tr key={row.branch.id} className="border-b border-stone-100 last:border-0">
                    <td className="px-3 py-2 font-medium text-stone-800">{row.branch.name}</td>
                    <td className="px-3 py-2 font-mono text-stone-700">฿{fmtMoney(row.sales)}</td>
                    <td className="px-3 py-2 font-mono text-stone-700">฿{fmtMoney(row.exp)}</td>
                    <td className={`px-3 py-2 font-mono font-semibold ${row.profit >= 0 ? "text-emerald-600" : "text-rose-600"}`}>฿{fmtMoney(row.profit)}</td>
                  </tr>
                ))}
                <tr className="font-semibold">
                  <td className="px-3 py-2 text-stone-800">รวมทุกสาขา</td>
                  <td className="px-3 py-2 font-mono">฿{fmtMoney(branchBreakdown.reduce((s, r) => s + r.sales, 0))}</td>
                  <td className="px-3 py-2 font-mono">฿{fmtMoney(branchBreakdown.reduce((s, r) => s + r.exp, 0))}</td>
                  <td className="px-3 py-2 font-mono">฿{fmtMoney(branchBreakdown.reduce((s, r) => s + r.profit, 0))}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </Card>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ภาพรวม — รายงานกำไร-ขาดทุน
   ========================================================================= */

function ProfitLossPage({ history, orderHistory, expenses, menu, stockItems, branches, currentBranchId }) {
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const now = new Date();
  const thisMonthKey = now.toISOString().slice(0, 7);
  const lastMonthDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
  const lastMonthKey = `${lastMonthDate.getFullYear()}-${String(lastMonthDate.getMonth() + 1).padStart(2, "0")}`;
  const yearKey = String(now.getFullYear());

  const [periodMode, setPeriodMode] = useState("thisMonth"); // thisMonth | lastMonth | thisYear | custom
  const [customFrom, setCustomFrom] = useState(thisMonthKey + "-01");
  const [customTo, setCustomTo] = useState(now.toISOString().slice(0, 10));

  function inPeriod(dateStr) {
    if (periodMode === "thisMonth") return dateStr.slice(0, 7) === thisMonthKey;
    if (periodMode === "lastMonth") return dateStr.slice(0, 7) === lastMonthKey;
    if (periodMode === "thisYear") return dateStr.slice(0, 4) === yearKey;
    return dateStr >= customFrom && dateStr <= customTo;
  }

  const allSalesInPeriod = history.filter(h => h.amount > 0 && inPeriod(h.date));
  const allRevenue = allSalesInPeriod.reduce((s, h) => s + h.amount, 0);
  const salesInPeriod = effectiveBranchId ? allSalesInPeriod.filter(h => h.branchId === effectiveBranchId) : allSalesInPeriod;
  const revenue = salesInPeriod.reduce((s, h) => s + h.amount, 0);

  // Order-level items aren't tagged per branch, so total COGS is estimated for
  // a single branch by its share of revenue within the period (noted below).
  const ordersInPeriod = orderHistory.filter(o => inPeriod(o.date));
  let totalCogsAllBranches = 0;
  ordersInPeriod.forEach(o => {
    o.items.forEach(item => {
      const menuItem = menu.find(m => m.name === item.name);
      (menuItem?.recipe || []).forEach(r => {
        const stockItem = stockItems.find(s => s.id === r.stockItemId);
        const info = getRecipeUnitInfo(stockItem);
        totalCogsAllBranches += (Number(r.qty) || 0) * info.costPerRecipeUnit * item.qty;
      });
    });
  });
  const cogs = Math.round(effectiveBranchId && allRevenue > 0 ? totalCogsAllBranches * (revenue / allRevenue) : totalCogsAllBranches);

  const grossProfit = revenue - cogs;
  const grossMargin = revenue > 0 ? Math.round((grossProfit / revenue) * 1000) / 10 : null;

  const allExpensesInPeriod = expenses.filter(e => inPeriod(e.date));
  const expensesInPeriod = effectiveBranchId ? allExpensesInPeriod.filter(e => e.branchId === effectiveBranchId) : allExpensesInPeriod;
  const expenseByCategory = {};
  expensesInPeriod.forEach(e => {
    e.lines.forEach(l => {
      const cat = l.category || "อื่นๆ";
      expenseByCategory[cat] = (expenseByCategory[cat] || 0) + poLineTotal(l);
    });
  });
  const totalExpenses = Object.values(expenseByCategory).reduce((s, v) => s + v, 0);

  const netProfit = grossProfit - totalExpenses;
  const netMargin = revenue > 0 ? Math.round((netProfit / revenue) * 1000) / 10 : null;

  const PERIOD_LABEL = { thisMonth: "เดือนนี้", lastMonth: "เดือนก่อน", thisYear: "ปีนี้", custom: "กำหนดเอง" };

  return (
    <div>
      <PageHeader eyebrow="ภาพรวม" title="รายงานกำไร-ขาดทุน" subtitle="สรุปรายได้ ต้นทุน ค่าใช้จ่าย และกำไรสุทธิตามช่วงเวลา"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[200px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา (รวม)</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : currentBranchId && branches ? (
          <span className="text-xs px-3 py-1.5 rounded-full bg-stone-100 text-stone-600 font-medium">{branches.find(b => b.id === currentBranchId)?.name}</span>
        ) : null} />

      <div className="flex flex-wrap items-center gap-2 mb-5">
        {["thisMonth", "lastMonth", "thisYear", "custom"].map(mode => (
          <button key={mode} onClick={() => setPeriodMode(mode)}
            className={`px-4 py-2 rounded-full text-sm font-medium border ${periodMode === mode ? "bg-stone-900 text-white border-stone-900" : "bg-white border-stone-300 text-stone-600 hover:border-stone-400"}`}>
            {PERIOD_LABEL[mode]}
          </button>
        ))}
        {periodMode === "custom" && (
          <div className="flex items-center gap-2 ml-2">
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customFrom} onChange={e => setCustomFrom(e.target.value)} />
            <span className="text-stone-400 text-sm">ถึง</span>
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customTo} onChange={e => setCustomTo(e.target.value)} />
          </div>
        )}
      </div>

      <Card className="p-6 max-w-2xl">
        <div className="space-y-1 text-sm">
          <div className="flex items-center justify-between py-2">
            <span className="text-stone-700 font-medium">รายได้จากการขาย</span>
            <span className="font-mono text-stone-800">฿{fmtMoney(revenue)}</span>
          </div>
          <div className="flex items-center justify-between py-2 border-b border-stone-200">
            <span className="text-stone-500 pl-4">หัก ต้นทุนขาย (วัตถุดิบ)</span>
            <span className="font-mono text-rose-500">-฿{fmtMoney(cogs)}</span>
          </div>
          <div className="flex items-center justify-between py-2.5 font-semibold">
            <span className="text-stone-800">กำไรขั้นต้น (Gross Profit)</span>
            <span className="font-mono text-stone-900">
              ฿{fmtMoney(grossProfit)} {grossMargin != null && <span className="text-xs text-stone-400 font-normal">({grossMargin}%)</span>}
            </span>
          </div>

          <div className="pt-3 border-t border-stone-200">
            <div className="text-stone-500 pl-4 mb-1">หัก ค่าใช้จ่ายในการดำเนินงาน</div>
            {Object.entries(expenseByCategory).sort((a, b) => b[1] - a[1]).map(([cat, amt]) => (
              <div key={cat} className="flex items-center justify-between py-1 pl-8 text-xs text-stone-500">
                <span>{cat}</span>
                <span className="font-mono">-฿{fmtMoney(amt)}</span>
              </div>
            ))}
            {Object.keys(expenseByCategory).length === 0 && (
              <div className="pl-8 text-xs text-stone-300">ไม่มีค่าใช้จ่ายในช่วงนี้</div>
            )}
            <div className="flex items-center justify-between py-2 border-b border-stone-200">
              <span className="text-stone-600 pl-4 font-medium">รวมค่าใช้จ่าย</span>
              <span className="font-mono text-rose-500">-฿{fmtMoney(totalExpenses)}</span>
            </div>
          </div>

          <div className={`flex items-center justify-between py-3 mt-2 rounded-lg px-4 ${netProfit >= 0 ? "bg-emerald-50" : "bg-rose-50"}`}>
            <span className={`font-semibold ${netProfit >= 0 ? "text-emerald-700" : "text-rose-700"}`}>กำไรสุทธิ (Net Profit)</span>
            <span className={`font-mono text-lg font-semibold ${netProfit >= 0 ? "text-emerald-700" : "text-rose-700"}`}>
              ฿{fmtMoney(netProfit)} {netMargin != null && <span className="text-xs font-normal">({netMargin}%)</span>}
            </span>
          </div>
        </div>
      </Card>

      <p className="text-xs text-stone-400 mt-4 max-w-2xl">
        หมายเหตุ: ต้นทุนขายคำนวณจากสูตรวัตถุดิบที่ผูกไว้ในแต่ละเมนู (หน้า "เพิ่มเมนูอาหาร") คูณกับจำนวนที่ขายได้จริงในช่วงเวลานี้ —
        เมนูที่ยังไม่ได้ผูกสูตรวัตถุดิบจะไม่ถูกคำนวณต้นทุนให้ ตัวเลขจึงเป็นค่าประมาณการ ไม่ใช่ตัวเลขบัญชีที่แม่นยำ 100%
        {effectiveBranchId && " · เมื่อเลือกดูเฉพาะสาขา ต้นทุนขายเป็นค่าประมาณการตามสัดส่วนยอดขายของสาขานั้น เทียบกับยอดขายรวมทุกสาขา (ระบบยังไม่ได้บันทึกว่าแต่ละออเดอร์ขายจากสาขาไหนโดยตรง)"}
      </p>
    </div>
  );
}

/* =========================================================================
   PAGE: ภาพรวม — ยอดขายแยกตามพนักงาน
   ========================================================================= */

function StaffSalesReportPage({ history, staff, positions, currentBranchId, branches }) {
  const now = new Date();
  const thisMonthKey = now.toISOString().slice(0, 7);
  const lastMonthDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
  const lastMonthKey = `${lastMonthDate.getFullYear()}-${String(lastMonthDate.getMonth() + 1).padStart(2, "0")}`;
  const yearKey = String(now.getFullYear());

  const [periodMode, setPeriodMode] = useState("thisMonth"); // thisMonth | lastMonth | thisYear | custom
  const [customFrom, setCustomFrom] = useState(thisMonthKey + "-01");
  const [customTo, setCustomTo] = useState(now.toISOString().slice(0, 10));
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;

  function inPeriod(dateStr) {
    if (periodMode === "thisMonth") return dateStr.slice(0, 7) === thisMonthKey;
    if (periodMode === "lastMonth") return dateStr.slice(0, 7) === lastMonthKey;
    if (periodMode === "thisYear") return dateStr.slice(0, 4) === yearKey;
    return dateStr >= customFrom && dateStr <= customTo;
  }
  const PERIOD_LABEL = { thisMonth: "เดือนนี้", lastMonth: "เดือนก่อน", thisYear: "ปีนี้", custom: "กำหนดเอง" };

  const billsInScope = history
    .filter(h => h.amount > 0 && inPeriod(h.date))
    .filter(h => !effectiveBranchId || !h.branchId || h.branchId === effectiveBranchId);

  // Group by the staff display name recorded on each closed bill.
  const byStaff = {};
  billsInScope.forEach(h => {
    const key = h.staffDisplayName || "ไม่ระบุพนักงาน";
    if (!byStaff[key]) byStaff[key] = { name: key, billCount: 0, total: 0 };
    byStaff[key].billCount += 1;
    byStaff[key].total += h.amount;
  });
  const rows = Object.values(byStaff)
    .map(r => ({ ...r, avgBill: r.billCount > 0 ? r.total / r.billCount : 0 }))
    .sort((a, b) => b.total - a.total);

  const grandTotal = rows.reduce((s, r) => s + r.total, 0);
  const grandBills = rows.reduce((s, r) => s + r.billCount, 0);

  function activeStaffMeta(name) {
    return staff.find(s => (s.displayName || s.name) === name);
  }
  function positionNameFor(meta) {
    if (!meta) return null;
    return positions?.find(p => p.id === meta.positionId)?.name;
  }

  const exportRows = rows.map(r => ({
    "พนักงาน": r.name, "จำนวนบิล": r.billCount, "ยอดขายรวม": Math.round(r.total * 100) / 100,
    "ยอดเฉลี่ยต่อบิล": Math.round(r.avgBill * 100) / 100,
    "สัดส่วนของยอดขายรวม (%)": grandTotal > 0 ? Math.round((r.total / grandTotal) * 1000) / 10 : 0,
  }));

  return (
    <div>
      <PageHeader eyebrow="ภาพรวม" title="แยกตามพนักงาน" subtitle="สรุปยอดปิดบิลของพนักงานแต่ละคนตามช่วงเวลา"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <ExportButton data={exportRows} filename={`แยกตามพนักงาน-${periodMode}`} sheetName="StaffSales" />
          </div>
        } />

      <div className="flex flex-wrap items-center gap-2 mb-5">
        {["thisMonth", "lastMonth", "thisYear", "custom"].map(mode => (
          <button key={mode} onClick={() => setPeriodMode(mode)}
            className={`px-3.5 py-2 rounded-lg text-sm font-medium ${periodMode === mode ? "bg-stone-900 text-white" : "bg-white border border-stone-300 text-stone-600 hover:border-stone-400"}`}>
            {PERIOD_LABEL[mode]}
          </button>
        ))}
        {periodMode === "custom" && (
          <>
            <input type="date" className={`${inputCls} max-w-[150px]`} value={customFrom} onChange={e => setCustomFrom(e.target.value)} />
            <span className="text-stone-400 text-sm">ถึง</span>
            <input type="date" className={`${inputCls} max-w-[150px]`} value={customTo} onChange={e => setCustomTo(e.target.value)} />
          </>
        )}
      </div>

      <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mb-5">
        <Card className="p-4">
          <div className="text-xs text-stone-400">ยอดขายรวมทุกพนักงาน</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(grandTotal)}</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">จำนวนบิลรวม</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{grandBills.toLocaleString()}</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">พนักงานที่ปิดบิล</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{rows.length}</div>
        </Card>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">อันดับ</th>
                <th className="px-4 py-3 font-medium">พนักงาน</th>
                <th className="px-4 py-3 font-medium">ตำแหน่ง</th>
                <th className="px-4 py-3 font-medium">จำนวนบิล</th>
                <th className="px-4 py-3 font-medium">ยอดขายรวม</th>
                <th className="px-4 py-3 font-medium">ยอดเฉลี่ย/บิล</th>
                <th className="px-4 py-3 font-medium">สัดส่วน</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((r, i) => {
                const meta = activeStaffMeta(r.name);
                const share = grandTotal > 0 ? Math.round((r.total / grandTotal) * 1000) / 10 : 0;
                return (
                  <tr key={r.name} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 text-stone-400 font-mono">#{i + 1}</td>
                    <td className="px-4 py-3 font-medium text-stone-800">{r.name}</td>
                    <td className="px-4 py-3 text-stone-500">{meta ? (positionNameFor(meta) || "-") : <span className="text-stone-300">ไม่พบในระบบพนักงาน</span>}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">{r.billCount.toLocaleString()}</td>
                    <td className="px-4 py-3 font-mono text-stone-800 font-semibold">฿{fmtMoney(r.total)}</td>
                    <td className="px-4 py-3 font-mono text-stone-600">฿{fmtMoney(r.avgBill)}</td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-2">
                        <div className="w-16 h-1.5 rounded-full bg-stone-100 overflow-hidden">
                          <div className="h-full bg-amber-500" style={{ width: `${share}%` }} />
                        </div>
                        <span className="text-xs text-stone-400 font-mono">{share}%</span>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {rows.length === 0 && (
                <tr><td colSpan={7} className="px-4 py-10 text-center text-stone-400">ไม่มีข้อมูลยอดขายในช่วงเวลานี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      <p className="text-xs text-stone-400 mt-4 max-w-2xl">
        หมายเหตุ: จัดกลุ่มตามชื่อที่แสดงในใบเสร็จ (Display Name) ของพนักงานที่ล็อกอินและกดปิดบิลนั้นๆ — บิลเก่าก่อนมีการบันทึกชื่อพนักงานจะถูกจัดเป็น "ไม่ระบุพนักงาน"
      </p>
    </div>
  );
}

/* =========================================================================
   PAGE: ภาพรวม — ภาษีมูลค่าเพิ่ม (ภ.พ.30)
   ========================================================================= */

function VatReportPage({ history, setHistory, goodsReceipts, setGoodsReceipts, expenses, setExpenses, paymentSettings, vatFilings, setVatFilings, storeInfo, purchaseOrders, vendors }) {
  const [tab, setTab] = useState("file"); // "file" | "history"
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [checkedMap, setCheckedMap] = useState({}); // key -> boolean, staged selection for this month
  const [confirmingFile, setConfirmingFile] = useState(false);
  const [cancelingFiling, setCancelingFiling] = useState(null);
  const [expandedFilingId, setExpandedFilingId] = useState(null);
  const [broughtForwardVat, setBroughtForwardVat] = useState("");
  const vatRate = paymentSettings?.vat?.rate || 7;
  const vatEnabled = !!paymentSettings?.vat?.enabled;

  // Auto-fill "ภาษีซื้อที่ยกมา" from the previous month's filing when it ended in
  // a refund/credit position — that unused credit carries forward to offset this
  // month's VAT instead of being cashed out. Otherwise leave blank for manual entry.
  useEffect(() => {
    const [y, m] = monthFilter.split("-").map(Number);
    const prevDate = new Date(y, m - 2, 1);
    const prevMonthKey = `${prevDate.getFullYear()}-${String(prevDate.getMonth() + 1).padStart(2, "0")}`;
    const prevFiling = (vatFilings || []).find(f => f.month === prevMonthKey);
    if (prevFiling && prevFiling.netVat < 0) {
      setBroughtForwardVat(String(Math.round(Math.abs(prevFiling.netVat) * 100) / 100));
    } else {
      setBroughtForwardVat("");
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [monthFilter, vatFilings]);

  // Bills already covered by a past filing are excluded from the current working view.
  const salesInMonth = history.filter(h => h.amount > 0 && h.date.slice(0, 7) === monthFilter && !h.vatFiled);
  // Extract the VAT portion from each bill's final (VAT-inclusive) total. This formula
  // recovers the exact original VAT amount whether the store's VAT mode is "added on
  // top" or "already included" in the price, since both produce a grand total equal
  // to pre-tax-base × (1 + rate/100).
  const outputVatEntries = vatEnabled ? salesInMonth.map(h => ({
    ...h,
    vatAmt: Math.round(h.amount * vatRate / (100 + vatRate) * 100) / 100,
    baseAmt: Math.round((h.amount - h.amount * vatRate / (100 + vatRate)) * 100) / 100,
  })) : [];
  const totalSalesBase = outputVatEntries.reduce((s, h) => s + h.baseAmt, 0);
  const outputVat = outputVatEntries.reduce((s, h) => s + h.vatAmt, 0);

  // Input VAT comes from the actual tax invoices recorded against goods receipts
  // (หน้า "ใบรับสินค้า") and ค่าใช้จ่าย — the real supporting documents for claiming
  // input VAT, filtered by the tax invoice's own date (not the receipt/expense date).
  // Entries already covered by a past filing are excluded here too.
  const allInputVatEntries = [
    ...(goodsReceipts || [])
      .filter(gr => gr.taxInvoice?.invoiceNumber && (gr.taxInvoice.invoiceDate || "").slice(0, 7) === monthFilter && !gr.taxInvoice.vatFiled)
      .map(gr => ({
        key: `gr-${gr.id}`, source: "goodsReceipt", sourceId: gr.id,
        ref: gr.taxInvoice.invoiceNumber,
        invoiceDate: gr.taxInvoice.invoiceDate,
        poRef: gr.poNumber,
        vendorName: gr.taxInvoice.vendorName,
        taxId: gr.taxInvoice.taxId,
        branch: gr.taxInvoice.branch,
        sourceLabel: `ใบรับสินค้า ${gr.poNumber}`,
        priceExclVat: Number(gr.taxInvoice.priceExclVat) || 0,
        vatAmt: Number(gr.taxInvoice.vatAmount) || 0,
        savedIncluded: gr.taxInvoice.vatIncluded !== false,
      })),
    ...(expenses || [])
      .filter(e => e.taxInvoice?.invoiceNumber && (e.taxInvoice.invoiceDate || "").slice(0, 7) === monthFilter && !e.taxInvoice.vatFiled)
      .map(e => ({
        key: `exp-${e.id}`, source: "expense", sourceId: e.id,
        ref: e.taxInvoice.invoiceNumber,
        invoiceDate: e.taxInvoice.invoiceDate,
        poRef: e.reference || e.expenseNumber,
        vendorName: e.taxInvoice.vendorName,
        taxId: e.taxInvoice.taxId,
        branch: e.taxInvoice.branch,
        sourceLabel: `ค่าใช้จ่าย ${e.expenseNumber}`,
        priceExclVat: Number(e.taxInvoice.priceExclVat) || 0,
        vatAmt: Number(e.taxInvoice.vatAmount) || 0,
        savedIncluded: e.taxInvoice.vatIncluded !== false,
      })),
  ];

  // Reset the staged checkbox selection to match the saved state whenever the
  // list of candidate entries for this month changes (e.g. switching months).
  useEffect(() => {
    const next = {};
    allInputVatEntries.forEach(e => { next[e.key] = e.savedIncluded; });
    setCheckedMap(next);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [monthFilter, goodsReceipts, expenses]);

  const inputVatEntries = allInputVatEntries.filter(e => checkedMap[e.key] !== false);
  const purchaseBaseTotal = inputVatEntries.reduce((s, e) => s + e.priceExclVat, 0);
  const inputVat = inputVatEntries.reduce((s, e) => s + e.vatAmt, 0);

  function toggleEntry(key) {
    const nextValue = checkedMap[key] === false ? true : false;
    setCheckedMap(prev => ({ ...prev, [key]: nextValue }));
    // Persist immediately so the choice is remembered next time this month is opened.
    if (key.startsWith("gr-") && setGoodsReceipts) {
      const id = key.slice(3);
      setGoodsReceipts(prev => prev.map(gr => gr.id === id ? { ...gr, taxInvoice: { ...gr.taxInvoice, vatIncluded: nextValue } } : gr));
    } else if (key.startsWith("exp-") && setExpenses) {
      const id = key.slice(4);
      setExpenses(prev => prev.map(e => e.id === id ? { ...e, taxInvoice: { ...e.taxInvoice, vatIncluded: nextValue } } : e));
    }
  }

  const netVat = outputVat - inputVat - (Number(broughtForwardVat) || 0);

  function confirmFileReturn() {
    const salesIds = new Set(outputVatEntries.map(h => h.id));
    const grIds = new Set(inputVatEntries.filter(e => e.source === "goodsReceipt").map(e => e.sourceId));
    const expIds = new Set(inputVatEntries.filter(e => e.source === "expense").map(e => e.sourceId));

    if (setHistory) setHistory(prev => prev.map(h => salesIds.has(h.id) ? { ...h, vatFiled: true } : h));
    if (setGoodsReceipts) setGoodsReceipts(prev => prev.map(gr => grIds.has(gr.id) ? { ...gr, taxInvoice: { ...gr.taxInvoice, vatFiled: true } } : gr));
    if (setExpenses) setExpenses(prev => prev.map(e => expIds.has(e.id) ? { ...e, taxInvoice: { ...e.taxInvoice, vatFiled: true } } : e));

    if (setVatFilings) {
      setVatFilings(prev => [...prev, {
        id: "vf" + Date.now(),
        month: monthFilter,
        filedAt: new Date().toISOString(),
        outputVat, inputVat, netVat, broughtForwardVat: Number(broughtForwardVat) || 0,
        totalSalesBase, purchaseBaseTotal,
        salesIds: [...salesIds],
        purchaseRefs: [...grIds].map(id => ({ source: "goodsReceipt", sourceId: id })).concat([...expIds].map(id => ({ source: "expense", sourceId: id }))),
        salesEntries: outputVatEntries.map(h => ({
          receiptNumber: h.receiptNumber || "-", date: h.date, action: h.action, member: h.member,
          channelName: h.channelName || "-", taxId: h.taxInvoice?.taxId || "", branch: h.taxInvoice?.branch || "",
          baseAmt: h.baseAmt, vatAmt: h.vatAmt, amount: h.amount,
        })),
        purchaseEntries: inputVatEntries.map(e => ({
          ref: e.ref, invoiceDate: e.invoiceDate, poRef: e.poRef, sourceLabel: e.sourceLabel,
          vendorName: e.vendorName, taxId: e.taxId, branch: e.branch,
          priceExclVat: e.priceExclVat, vatAmt: e.vatAmt,
        })),
      }]);
    }
    setConfirmingFile(false);
  }

  function exportFilingReport(f) {
    const [y, m] = f.month.split("-");
    const thaiMonthName = ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"][Number(m) - 1];
    const buddhistYear = Number(y) + 543;
    const toDMY = d => d ? fmtDate(d) : "";

    // Sheet 1 — ภาษีซื้อ (Input Tax)
    const inputRows = [
      ["รายงานภาษีซื้อ(ภ.พ.30)"],
      [`สำหรับงวดภาษี เดือน ${thaiMonthName} ปี ${buddhistYear}`],
      [`ชื่อผู้ประกอบการ ${storeInfo?.name || ""} เลขประจำผู้เสียภาษีอากร ${storeInfo?.taxId || ""}`],
      [null, null, "ชื่อสถานที่ประกอบการ ", storeInfo?.address || ""],
      [],
      ["ลำดับที่", "วันที่ใบกำกับภาษี", "เลขที่ใบกำกับภาษี", "เลขที่อ้างอิง", "ชื่อผู้จำหน่าย", "เลขผู้เสียภาษี", "สำนักงานใหญ่/สาขา", "มูลค่า", "ภาษีมูลค่าเพิ่ม"],
      ...f.purchaseEntries.map((p, i) => [i + 1, toDMY(p.invoiceDate), p.ref, p.poRef || "-", p.vendorName || "-", p.taxId || "-", p.branch || "-", p.priceExclVat, p.vatAmt]),
      [null, null, null, null, null, null, "ยอดรวมทั้งหมด", f.purchaseBaseTotal, f.inputVat],
    ];

    // Sheet 2 — ภาษีขาย (Output Tax)
    const outputRows = [
      ["รายงานภาษีขาย"],
      [`สำหรับงวดภาษี เดือน ${thaiMonthName} ปี ${buddhistYear}`],
      [`ชื่อผู้ประกอบการ ${storeInfo?.name || ""} เลขประจำผู้เสียภาษีอากร ${storeInfo?.taxId || ""}`],
      [null, null, "ชื่อสถานที่ประกอบการ ", storeInfo?.address || ""],
      [],
      ["ลำดับที่", "วัน/เดือน/ปี", "เลขที่เอกสาร", "ช่องทางขาย", "ชื่อลูกค้า", "เลขผู้เสียภาษี", "สำนักงานใหญ่/สาขา", "มูลค่า", "ภาษีมูลค่าเพิ่ม"],
      ...f.salesEntries.map((s, i) => [i + 1, toDMY(s.date), s.receiptNumber, s.channelName || "-", s.member, s.taxId || "-", s.branch || "-", s.baseAmt, s.vatAmt]),
      [null, null, null, null, null, null, "ยอดรวมทั้งหมด", f.totalSalesBase, f.outputVat],
    ];

    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(inputRows), "InputTaxReport");
    XLSX.utils.book_append_sheet(wb, XLSX.utils.aoa_to_sheet(outputRows), "OutTaxReport");
    XLSX.writeFile(wb, `ภพ30-${f.month}.xlsx`);
  }

  function cancelFiling(f) {
    const salesIdSet = new Set(f.salesIds || []);
    const grIdSet = new Set((f.purchaseRefs || []).filter(r => r.source === "goodsReceipt").map(r => r.sourceId));
    const expIdSet = new Set((f.purchaseRefs || []).filter(r => r.source === "expense").map(r => r.sourceId));

    if (setHistory && salesIdSet.size > 0) {
      setHistory(prev => prev.map(h => salesIdSet.has(h.id) ? { ...h, vatFiled: false } : h));
    }
    if (setGoodsReceipts && grIdSet.size > 0) {
      setGoodsReceipts(prev => prev.map(gr => grIdSet.has(gr.id) ? { ...gr, taxInvoice: { ...gr.taxInvoice, vatFiled: false } } : gr));
    }
    if (setExpenses && expIdSet.size > 0) {
      setExpenses(prev => prev.map(e => expIdSet.has(e.id) ? { ...e, taxInvoice: { ...e.taxInvoice, vatFiled: false } } : e));
    }
    if (setVatFilings) {
      setVatFilings(prev => prev.filter(x => x.id !== f.id));
    }
    setCancelingFiling(null);
  }

  const exportRows = [
    { "รายการ": "ยอดขาย (ไม่รวม VAT)", "จำนวนเงิน": Math.round(totalSalesBase * 100) / 100 },
    { "รายการ": "ภาษีขาย (Output VAT)", "จำนวนเงิน": Math.round(outputVat * 100) / 100 },
    { "รายการ": "ยอดซื้อ (ไม่รวม VAT)", "จำนวนเงิน": Math.round(purchaseBaseTotal * 100) / 100 },
    { "รายการ": "ภาษีซื้อ (Input VAT)", "จำนวนเงิน": Math.round(inputVat * 100) / 100 },
    { "รายการ": netVat >= 0 ? "ภาษีที่ต้องชำระ" : "ภาษีที่ขอคืน/ยกไป", "จำนวนเงิน": Math.round(Math.abs(netVat) * 100) / 100 },
  ];

  return (
    <div>
      <PageHeader eyebrow="ภาพรวม" title="ภาษีมูลค่าเพิ่ม (ภ.พ.30)" subtitle="สรุปภาษีขาย-ภาษีซื้อรายเดือน สำหรับยื่นแบบต่อกรมสรรพากร" />

      <div className="flex gap-1 border-b border-stone-200 mb-5">
        <button onClick={() => setTab("file")}
          className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px ${tab === "file" ? "border-amber-600 text-stone-800" : "border-transparent text-stone-400 hover:text-stone-600"}`}>
          ยื่นภาษีเดือนนี้
        </button>
        <button onClick={() => setTab("history")}
          className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px ${tab === "history" ? "border-amber-600 text-stone-800" : "border-transparent text-stone-400 hover:text-stone-600"}`}>
          ดูรายงานภาษี
        </button>
        <button onClick={() => setTab("wht")}
          className={`px-4 py-2.5 text-sm font-medium border-b-2 -mb-px ${tab === "wht" ? "border-amber-600 text-stone-800" : "border-transparent text-stone-400 hover:text-stone-600"}`}>
          ภาษีหัก ณ ที่จ่าย (WHT)
        </button>
      </div>

      {tab === "file" && (
        <>
      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`ภพ30-${monthFilter}`} sheetName="VAT" />
        </div>
      </div>

      {!vatEnabled && (
        <Card className="p-4 mb-5 border-amber-200 bg-amber-50">
          <div className="text-sm text-amber-700">ระบบยังไม่ได้เปิดใช้งาน VAT ในหน้า "การชำระเงิน" — ภาษีขายจะแสดงเป็น 0 จนกว่าจะเปิดใช้งาน</div>
        </Card>
      )}

      <Card className="p-6 max-w-2xl">
        <div className="text-sm font-semibold text-stone-700 mb-3">ส่วนที่ 1 — ภาษีขาย (Output Tax)</div>
        <div className="space-y-1 text-sm mb-5">
          <div className="flex justify-between py-1"><span className="text-stone-600">ยอดขายทั้งสิ้น (ไม่รวมภาษีมูลค่าเพิ่ม)</span><span className="font-mono">฿{fmtMoney(totalSalesBase)}</span></div>
          <div className="flex justify-between py-1"><span className="text-stone-600">จำนวนบิลขาย</span><span className="font-mono">{salesInMonth.length} บิล</span></div>
          <div className="flex justify-between py-2 border-t border-stone-200 font-semibold"><span>ภาษีขาย ({vatRate}%)</span><span className="font-mono text-sky-700">฿{fmtMoney(outputVat)}</span></div>
        </div>

        <div className="text-sm font-semibold text-stone-700 mb-3">ส่วนที่ 2 — ภาษีซื้อ (Input Tax)</div>
        <div className="space-y-1 text-sm mb-5">
          <div className="flex justify-between py-1"><span className="text-stone-600">ยอดซื้อทั้งสิ้น (ไม่รวมภาษีมูลค่าเพิ่ม)</span><span className="font-mono">฿{fmtMoney(purchaseBaseTotal)}</span></div>
          <div className="flex justify-between py-1"><span className="text-stone-600">จำนวนใบกำกับภาษีที่บันทึกไว้</span><span className="font-mono">{inputVatEntries.length} ฉบับ</span></div>
          <div className="flex justify-between py-2 border-t border-stone-200 font-semibold"><span>ภาษีซื้อ</span><span className="font-mono text-sky-700">฿{fmtMoney(inputVat)}</span></div>
          <div className="flex justify-between items-center py-1">
            <span className="text-stone-600">ภาษีซื้อที่ยกมา</span>
            <input type="number" step="any" className="w-32 rounded-md border border-stone-300 px-2 py-1 text-sm text-right font-mono"
              value={broughtForwardVat} onChange={e => setBroughtForwardVat(e.target.value)} placeholder="0.00" />
          </div>
        </div>

        <div className={`flex items-center justify-between py-3 rounded-lg px-4 ${netVat >= 0 ? "bg-rose-50" : "bg-emerald-50"}`}>
          <span className={`font-semibold ${netVat >= 0 ? "text-rose-700" : "text-emerald-700"}`}>
            {netVat >= 0 ? "ภาษีที่ต้องชำระ" : "ภาษีที่ขอคืน/ยกไปเดือนถัดไป"}
          </span>
          <span className={`font-mono text-lg font-semibold ${netVat >= 0 ? "text-rose-700" : "text-emerald-700"}`}>฿{fmtMoney(Math.abs(netVat))}</span>
        </div>

        <Btn className="w-full justify-center mt-4" disabled={outputVatEntries.length === 0 && inputVatEntries.length === 0} onClick={() => setConfirmingFile(true)}>
          <ShieldCheck size={14} /> บันทึกแบบยื่นภาษี
        </Btn>
      </Card>

      {outputVatEntries.length > 0 && (
        <Card className="mt-5">
          <div className="px-4 pt-4 text-sm font-semibold text-stone-700">รายการภาษีขาย (บิลขายในเดือนนี้)</div>
          <div className="overflow-x-auto">
            <table className="w-full text-sm mt-2">
              <thead>
                <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                  <th className="px-4 py-3 font-medium">เลขที่ใบเสร็จ</th>
                  <th className="px-4 py-3 font-medium">วันที่/เวลา</th>
                  <th className="px-4 py-3 font-medium">รายการ</th>
                  <th className="px-4 py-3 font-medium">ลูกค้า/สมาชิก</th>
                  <th className="px-4 py-3 font-medium">มูลค่าก่อนภาษี</th>
                  <th className="px-4 py-3 font-medium">ภาษีขาย</th>
                  <th className="px-4 py-3 font-medium">ยอดรวม</th>
                </tr>
              </thead>
              <tbody>
                {outputVatEntries.map(h => (
                  <tr key={h.id} className="border-b border-stone-100 last:border-0">
                    <td className="px-4 py-3 font-mono text-stone-500">{h.receiptNumber || "-"}</td>
                    <td className="px-4 py-3 text-stone-400">{fmtDate(h.date)}{h.time && <div className="text-[11px]">{h.time} น.</div>}</td>
                    <td className="px-4 py-3 text-stone-600">{h.action}</td>
                    <td className="px-4 py-3 text-stone-600">{h.member}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(h.baseAmt)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(h.vatAmt)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(h.amount)}</td>
                  </tr>
                ))}
                <tr className="font-semibold">
                  <td colSpan={4} className="px-4 py-3 text-stone-800">รวม</td>
                  <td className="px-4 py-3 font-mono">฿{fmtMoney(totalSalesBase)}</td>
                  <td className="px-4 py-3 font-mono">฿{fmtMoney(outputVat)}</td>
                  <td className="px-4 py-3 font-mono">฿{fmtMoney(totalSalesBase + outputVat)}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </Card>
      )}

      {allInputVatEntries.length > 0 && (
        <Card className="mt-5">
          <div className="px-4 pt-4">
            <div className="text-sm font-semibold text-stone-700">รายการภาษีซื้อ — ติ๊กเลือกรายการที่จะนำมาคิดภาษีซื้อของเดือนนี้</div>
          </div>
          <div className="overflow-x-auto">
            <table className="w-full text-sm mt-2">
              <thead>
                <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                  <th className="px-4 py-3 font-medium w-10"></th>
                  <th className="px-4 py-3 font-medium">เลขที่ใบกำกับภาษี</th>
                  <th className="px-4 py-3 font-medium">ที่มา</th>
                  <th className="px-4 py-3 font-medium">ผู้จำหน่าย</th>
                  <th className="px-4 py-3 font-medium">เลขผู้เสียภาษี</th>
                  <th className="px-4 py-3 font-medium">สำนักงาน/สาขา</th>
                  <th className="px-4 py-3 font-medium">มูลค่าก่อนภาษี</th>
                  <th className="px-4 py-3 font-medium">ภาษีซื้อ</th>
                </tr>
              </thead>
              <tbody>
                {allInputVatEntries.map(e => {
                  const isChecked = checkedMap[e.key] !== false;
                  return (
                    <tr key={e.key} className={`border-b border-stone-100 last:border-0 ${!isChecked ? "opacity-40" : ""}`}>
                      <td className="px-4 py-3"><input type="checkbox" checked={isChecked} onChange={() => toggleEntry(e.key)} /></td>
                      <td className="px-4 py-3 font-mono text-stone-700">{e.ref}</td>
                      <td className="px-4 py-3 text-stone-500">{e.sourceLabel}</td>
                      <td className="px-4 py-3 text-stone-600">{e.vendorName || "-"}</td>
                      <td className="px-4 py-3 font-mono text-stone-500">{e.taxId || "-"}</td>
                      <td className="px-4 py-3 text-stone-500">{e.branch || "-"}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(e.priceExclVat)}</td>
                      <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(e.vatAmt)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      <p className="text-xs text-stone-400 mt-4 max-w-2xl">
        ยอดในส่วนที่ 2 ด้านบนคำนวณจากรายการที่ติ๊กเลือกไว้เท่านั้น — ติ๊กออกถ้าต้องการยกภาษีซื้อรายการนั้นไปคิดในเดือนอื่นแทน แล้วกด "บันทึก" เพื่อจดจำการเลือกไว้
      </p>

      <p className="text-xs text-stone-400 mt-2 max-w-2xl">
        หมายเหตุ: <strong>ภาษีขาย</strong> คำนวณย้อนกลับจากยอดขายรวมที่บันทึกไว้ (ตามอัตรา VAT ที่ตั้งไว้ในหน้า "การชำระเงิน") <strong>ภาษีซื้อ</strong> ดึงจากใบกำกับภาษีจริงที่บันทึกไว้ในหน้า "ใบรับสินค้า" เท่านั้น (นับตามวันที่ในใบกำกับภาษี ไม่ใช่วันที่รับสินค้า) — รายการรับสินค้าที่ยังไม่ได้บันทึกใบกำกับภาษีจะไม่ถูกนับในรายงานนี้ —
        ตัวเลขนี้เป็นข้อมูลสรุปเพื่อช่วยเตรียมยื่นแบบ ภ.พ.30 ไม่ใช่การยื่นแบบอัตโนมัติ กรุณาตรวจสอบความถูกต้องกับนักบัญชีก่อนยื่นจริงทุกครั้ง — กด "บันทึกแบบยื่นภาษี" เมื่อยื่นแบบกับกรมสรรพากรจริงแล้ว รายการที่ยื่นแล้วจะหายไปจากตารางด้านบน (ดูย้อนหลังได้ที่แท็บ "ดูรายงานภาษี")
      </p>
        </>
      )}

      {tab === "history" && (
        <div className="space-y-4">
          {(vatFilings || []).length === 0 && (
            <div className="text-sm text-stone-400 text-center py-10 border border-dashed border-stone-300 rounded-lg">ยังไม่มีการยื่นภาษีที่บันทึกไว้</div>
          )}
          {[...(vatFilings || [])].sort((a, b) => b.month.localeCompare(a.month) || b.filedAt.localeCompare(a.filedAt)).map(f => {
            const [y, m] = f.month.split("-");
            const thaiMonthName = ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"][Number(m) - 1];
            return (
              <Card key={f.id} className="p-5">
                <div className="flex items-center justify-between flex-wrap gap-2 mb-3">
                  <div>
                    <div className="font-semibold text-stone-800">เดือน{thaiMonthName} {Number(y) + 543}</div>
                    <div className="text-xs text-stone-400">ยื่นเมื่อ {fmtDate(f.filedAt.slice(0, 10))} {f.filedAt.slice(11, 16)} น.</div>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className={`text-sm font-semibold px-3 py-1.5 rounded-lg ${f.netVat >= 0 ? "bg-rose-50 text-rose-700" : "bg-emerald-50 text-emerald-700"}`}>
                      {f.netVat >= 0 ? "ชำระ" : "ขอคืน"} ฿{fmtMoney(Math.abs(f.netVat))}
                    </div>
                    <Btn variant="ghost" onClick={() => exportFilingReport(f)}><Download size={14} /> ดาวน์โหลด</Btn>
                    <Btn variant="ghost" onClick={() => setCancelingFiling(f)}><X size={14} /> ยกเลิก</Btn>
                  </div>
                </div>
                <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4 text-sm">
                  <div><div className="text-xs text-stone-400">ยอดขาย</div><div className="font-mono">฿{fmtMoney(f.totalSalesBase)}</div></div>
                  <div><div className="text-xs text-stone-400">ภาษีขาย</div><div className="font-mono">฿{fmtMoney(f.outputVat)}</div></div>
                  <div><div className="text-xs text-stone-400">ยอดซื้อ</div><div className="font-mono">฿{fmtMoney(f.purchaseBaseTotal)}</div></div>
                  <div><div className="text-xs text-stone-400">ภาษีซื้อ</div><div className="font-mono">฿{fmtMoney(f.inputVat)}</div></div>
                  {f.broughtForwardVat > 0 && (
                    <div><div className="text-xs text-stone-400">ภาษีซื้อที่ยกมา</div><div className="font-mono">฿{fmtMoney(f.broughtForwardVat)}</div></div>
                  )}
                </div>

                <button onClick={() => setExpandedFilingId(prev => prev === f.id ? null : f.id)}
                  className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1">
                  {expandedFilingId === f.id ? <ChevronUp size={13} /> : <ChevronDown size={13} />}
                  ดูรายละเอียด ({f.salesEntries.length} บิลขาย, {f.purchaseEntries.length} บิลซื้อ)
                </button>

                {expandedFilingId === f.id && (
                  <>
                <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5 mt-4">บิลขาย ({f.salesEntries.length} รายการ)</div>
                <div className="overflow-x-auto mb-4">
                  <table className="w-full text-xs">
                    <thead>
                      <tr className="text-left text-stone-400 border-b border-stone-200">
                        <th className="py-1.5 pr-3">เลขที่ใบเสร็จ</th><th className="py-1.5 pr-3">วันที่</th><th className="py-1.5 pr-3">รายการ</th><th className="py-1.5 pr-3">ลูกค้า</th><th className="py-1.5 pr-3 text-right">ยอดรวม</th>
                      </tr>
                    </thead>
                    <tbody>
                      {f.salesEntries.map((s, i) => (
                        <tr key={i} className="border-b border-stone-100 last:border-0">
                          <td className="py-1.5 pr-3 font-mono">{s.receiptNumber}</td>
                          <td className="py-1.5 pr-3">{fmtDate(s.date)}</td>
                          <td className="py-1.5 pr-3">{s.action}</td>
                          <td className="py-1.5 pr-3">{s.member}</td>
                          <td className="py-1.5 pr-3 text-right font-mono">฿{fmtMoney(s.amount)}</td>
                        </tr>
                      ))}
                      {f.salesEntries.length === 0 && <tr><td colSpan={5} className="py-2 text-center text-stone-300">ไม่มี</td></tr>}
                    </tbody>
                  </table>
                </div>

                <div className="text-xs font-semibold text-stone-500 uppercase tracking-wide mb-1.5">บิลซื้อ ({f.purchaseEntries.length} รายการ)</div>
                <div className="overflow-x-auto">
                  <table className="w-full text-xs">
                    <thead>
                      <tr className="text-left text-stone-400 border-b border-stone-200">
                        <th className="py-1.5 pr-3">เลขที่ใบกำกับภาษี</th><th className="py-1.5 pr-3">ที่มา</th><th className="py-1.5 pr-3">ผู้จำหน่าย</th><th className="py-1.5 pr-3 text-right">มูลค่าก่อนภาษี</th><th className="py-1.5 pr-3 text-right">ภาษีซื้อ</th>
                      </tr>
                    </thead>
                    <tbody>
                      {f.purchaseEntries.map((p, i) => (
                        <tr key={i} className="border-b border-stone-100 last:border-0">
                          <td className="py-1.5 pr-3 font-mono">{p.ref}</td>
                          <td className="py-1.5 pr-3">{p.sourceLabel}</td>
                          <td className="py-1.5 pr-3">{p.vendorName || "-"}</td>
                          <td className="py-1.5 pr-3 text-right font-mono">฿{fmtMoney(p.priceExclVat)}</td>
                          <td className="py-1.5 pr-3 text-right font-mono">฿{fmtMoney(p.vatAmt)}</td>
                        </tr>
                      ))}
                      {f.purchaseEntries.length === 0 && <tr><td colSpan={5} className="py-2 text-center text-stone-300">ไม่มี</td></tr>}
                    </tbody>
                  </table>
                </div>
                  </>
                )}
              </Card>
            );
          })}
        </div>
      )}

      {tab === "wht" && (() => {
        const whtMonth = monthFilter;
        function buildWhtEntries(docs, refKey, dateKey) {
          return (docs || [])
            .filter(d => d.paymentStatus === "paid" && d.payment?.whtEnabled && (d.payment.paymentDate || "").slice(0, 7) === whtMonth)
            .map(d => {
              const v = vendors?.find(x => x.id === d.vendorId);
              const grand = poComputeTotals(d).grand;
              const whtPercent = Number(d.payment.whtPercent) || 0;
              const whtAmt = Math.round(grand * (whtPercent / 100) * 100) / 100;
              return {
                ref: d[refKey], date: d.payment.paymentDate,
                vendorName: v?.businessName || v?.contactPersonName || "-",
                taxId: v?.taxId || "-",
                formType: v?.contactType === "corporate" ? "ภ.ง.ด.53" : "ภ.ง.ด.3",
                grand, whtPercent, whtAmt,
              };
            });
        }
        const whtEntries = [
          ...buildWhtEntries(purchaseOrders, "poNumber"),
          ...buildWhtEntries(expenses, "expenseNumber"),
        ].sort((a, b) => a.date.localeCompare(b.date));

        const totalWht = whtEntries.reduce((s, e) => s + e.whtAmt, 0);
        const total3 = whtEntries.filter(e => e.formType === "ภ.ง.ด.3").reduce((s, e) => s + e.whtAmt, 0);
        const total53 = whtEntries.filter(e => e.formType === "ภ.ง.ด.53").reduce((s, e) => s + e.whtAmt, 0);

        const whtExportRows = whtEntries.map(e => ({
          "เลขที่เอกสาร": e.ref, "วันที่ชำระ": fmtDate(e.date), "ผู้รับเงิน": e.vendorName, "เลขผู้เสียภาษี": e.taxId,
          "แบบที่ยื่น": e.formType, "ยอดเงินที่จ่าย": e.grand, "อัตราหัก (%)": e.whtPercent, "ภาษีหัก ณ ที่จ่าย": e.whtAmt,
        }));

        return (
          <>
            <div className="flex flex-wrap items-center gap-3 mb-5">
              <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
              <div className="ml-auto">
                <ExportButton data={whtExportRows} filename={`ภงด-${monthFilter}`} sheetName="WHT" />
              </div>
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-5 max-w-2xl">
              <Card className="p-4">
                <div className="text-xs text-stone-400">รวมภาษีหัก ณ ที่จ่าย</div>
                <div className="text-xl font-serif text-stone-900 mt-1">฿{fmtMoney(totalWht)}</div>
              </Card>
              <Card className="p-4">
                <div className="text-xs text-stone-400">ภ.ง.ด.3 (บุคคลธรรมดา)</div>
                <div className="text-xl font-serif text-stone-900 mt-1">฿{fmtMoney(total3)}</div>
              </Card>
              <Card className="p-4">
                <div className="text-xs text-stone-400">ภ.ง.ด.53 (นิติบุคคล)</div>
                <div className="text-xl font-serif text-stone-900 mt-1">฿{fmtMoney(total53)}</div>
              </Card>
            </div>

            <Card>
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                      <th className="px-4 py-3 font-medium">เลขที่เอกสาร</th>
                      <th className="px-4 py-3 font-medium">วันที่ชำระ</th>
                      <th className="px-4 py-3 font-medium">ผู้รับเงิน</th>
                      <th className="px-4 py-3 font-medium">เลขผู้เสียภาษี</th>
                      <th className="px-4 py-3 font-medium">แบบที่ยื่น</th>
                      <th className="px-4 py-3 font-medium">ยอดเงินที่จ่าย</th>
                      <th className="px-4 py-3 font-medium">อัตรา</th>
                      <th className="px-4 py-3 font-medium">ภาษีหัก ณ ที่จ่าย</th>
                    </tr>
                  </thead>
                  <tbody>
                    {whtEntries.map((e, i) => (
                      <tr key={i} className="border-b border-stone-100 last:border-0">
                        <td className="px-4 py-3 font-mono text-stone-700">{e.ref}</td>
                        <td className="px-4 py-3 text-stone-400">{fmtDate(e.date)}</td>
                        <td className="px-4 py-3 text-stone-600">{e.vendorName}</td>
                        <td className="px-4 py-3 font-mono text-stone-500">{e.taxId}</td>
                        <td className="px-4 py-3">
                          <span className={`text-xs px-2 py-0.5 rounded border font-medium ${e.formType === "ภ.ง.ด.53" ? "bg-sky-50 text-sky-700 border-sky-300" : "bg-amber-50 text-amber-700 border-amber-300"}`}>{e.formType}</span>
                        </td>
                        <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(e.grand)}</td>
                        <td className="px-4 py-3 font-mono text-stone-700">{e.whtPercent}%</td>
                        <td className="px-4 py-3 font-mono text-rose-600">฿{fmtMoney(e.whtAmt)}</td>
                      </tr>
                    ))}
                    {whtEntries.length === 0 && (
                      <tr><td colSpan={8} className="px-4 py-10 text-center text-stone-400">ไม่มีรายการหัก ณ ที่จ่ายในเดือนนี้</td></tr>
                    )}
                  </tbody>
                </table>
              </div>
            </Card>

            <p className="text-xs text-stone-400 mt-4 max-w-2xl">
              หมายเหตุ: ดึงจากรายการชำระเงินจริงของใบสั่งซื้อและค่าใช้จ่ายที่ติ๊ก "หัก ณ ที่จ่าย" ไว้ตอนบันทึกการชำระเงิน — นับตามวันที่ชำระจริง แยกแบบยื่นอัตโนมัติตามประเภทผู้จำหน่าย (บุคคลธรรมดา → ภ.ง.ด.3, นิติบุคคล → ภ.ง.ด.53) ตัวเลขนี้เป็นข้อมูลสรุปช่วยเตรียมยื่น กรุณาตรวจสอบกับนักบัญชีก่อนยื่นจริงทุกครั้ง
            </p>
          </>
        );
      })()}

      {/* Confirm filing popup */}
      {confirmingFile && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setConfirmingFile(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">ยืนยันบันทึกแบบยื่นภาษี</div>
            <div className="text-sm text-stone-500 mb-4">
              บิลขาย {outputVatEntries.length} รายการ และบิลซื้อ {inputVatEntries.length} รายการของเดือนนี้จะถูกทำเครื่องหมายว่ายื่นแล้ว และจะหายไปจากตารางด้านบน (ดูย้อนหลังได้ที่แท็บ "ดูรายงานภาษี")
            </div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setConfirmingFile(false)}>ยกเลิก</Btn>
              <Btn onClick={confirmFileReturn}>ยืนยัน</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Confirm cancel filing popup */}
      {cancelingFiling && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setCancelingFiling(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">ยกเลิกการยื่นภาษี?</div>
            <div className="text-sm text-stone-500 mb-4">
              บิลขาย {cancelingFiling.salesEntries?.length || 0} รายการ และบิลซื้อ {cancelingFiling.purchaseEntries?.length || 0} รายการของเดือนนี้จะถูกยกเลิกสถานะ "ยื่นแล้ว" และกลับไปแสดงในแท็บ "ยื่นภาษีเดือนนี้" อีกครั้ง — ใช้เมื่อยื่นผิดหรือต้องแก้ไขข้อมูลก่อนยื่นใหม่
            </div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setCancelingFiling(null)}>ยกเลิก</Btn>
              <Btn onClick={() => cancelFiling(cancelingFiling)}>ยืนยันยกเลิกการยื่น</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ภาพรวม — รายงานต้นทุนเมนู (Food Cost %)
   ========================================================================= */

function menuItemCost(item, stockItems) {
  return (item.recipe || []).reduce((sum, r) => {
    const stockItem = stockItems.find(s => s.id === r.stockItemId);
    const info = getRecipeUnitInfo(stockItem);
    return sum + (Number(r.qty) || 0) * info.costPerRecipeUnit;
  }, 0);
}

function FoodCostPage({ menu, categories, stockItems, orderHistory, currentBranchId, branches }) {
  const [categoryFilter, setCategoryFilter] = useState("");
  const [targetPct, setTargetPct] = useState(30);
  const [sortBy, setSortBy] = useState("foodCostDesc");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;

  const now = new Date();
  const thisMonthKey = now.toISOString().slice(0, 7);
  const lastMonthDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
  const lastMonthKey = `${lastMonthDate.getFullYear()}-${String(lastMonthDate.getMonth() + 1).padStart(2, "0")}`;
  const yearKey = String(now.getFullYear());

  const [periodMode, setPeriodMode] = useState("thisMonth"); // thisMonth | lastMonth | thisYear | custom
  const [customFrom, setCustomFrom] = useState(thisMonthKey + "-01");
  const [customTo, setCustomTo] = useState(now.toISOString().slice(0, 10));

  function inPeriod(dateStr) {
    if (periodMode === "thisMonth") return dateStr.slice(0, 7) === thisMonthKey;
    if (periodMode === "lastMonth") return dateStr.slice(0, 7) === lastMonthKey;
    if (periodMode === "thisYear") return dateStr.slice(0, 4) === yearKey;
    return dateStr >= customFrom && dateStr <= customTo;
  }
  const PERIOD_LABEL = { thisMonth: "เดือนนี้", lastMonth: "เดือนก่อน", thisYear: "ปีนี้", custom: "กำหนดเอง" };

  const qtySoldByName = {};
  orderHistory
    .filter(o => inPeriod(o.date))
    .filter(o => !effectiveBranchId || !o.branchId || o.branchId === effectiveBranchId)
    .forEach(o => o.items.forEach(it => { qtySoldByName[it.name] = (qtySoldByName[it.name] || 0) + it.qty; }));

  const rows = menu.map(item => {
    const cost = menuItemCost(item, stockItems);
    const hasRecipe = (item.recipe || []).length > 0;
    const price = item.price || 0;
    const profit = price - cost;
    const foodCostPct = price > 0 && hasRecipe ? Math.round((cost / price) * 1000) / 10 : null;
    const qtySold = qtySoldByName[item.name] || 0;
    const totalProfit = hasRecipe ? profit * qtySold : null;
    const cat = categories.find(c => c.id === item.catId);
    return { item, cat, cost, price, profit, foodCostPct, qtySold, totalProfit, hasRecipe };
  }).filter(r => !categoryFilter || r.item.catId === categoryFilter);

  const sorted = [...rows].sort((a, b) => {
    if (sortBy === "foodCostDesc") return (b.foodCostPct ?? -1) - (a.foodCostPct ?? -1);
    if (sortBy === "foodCostAsc") return (a.foodCostPct ?? 999) - (b.foodCostPct ?? 999);
    if (sortBy === "profitDesc") return b.profit - a.profit;
    if (sortBy === "qtyDesc") return b.qtySold - a.qtySold;
    return a.item.name.localeCompare(b.item.name, "th");
  });

  const withRecipe = rows.filter(r => r.hasRecipe);
  const avgFoodCost = withRecipe.length > 0 ? Math.round((withRecipe.reduce((s, r) => s + r.foodCostPct, 0) / withRecipe.length) * 10) / 10 : null;
  const noRecipeCount = rows.filter(r => !r.hasRecipe).length;
  const overTargetCount = withRecipe.filter(r => r.foodCostPct > targetPct).length;

  function foodCostColor(pct) {
    if (pct == null) return "text-stone-400";
    if (pct <= targetPct) return "text-emerald-600";
    if (pct <= targetPct + 10) return "text-amber-600";
    return "text-rose-600";
  }

  const exportRows = sorted.map(r => ({
    "เมนู": r.item.name, "หมวดหมู่": r.cat?.name || "-", "ราคาขาย": r.price,
    "ต้นทุนต่อจาน": r.hasRecipe ? Math.round(r.cost * 100) / 100 : "", "กำไรต่อจาน": r.hasRecipe ? Math.round(r.profit * 100) / 100 : "",
    "Food Cost %": r.foodCostPct ?? "", "จำนวนขาย": r.qtySold, "กำไรรวม": r.totalProfit != null ? Math.round(r.totalProfit * 100) / 100 : "",
  }));

  return (
    <div>
      <PageHeader eyebrow="ภาพรวม" title="รายงานต้นทุนเมนู" subtitle="เทียบราคาขายกับต้นทุนวัตถุดิบของแต่ละเมนู (Food Cost %)"
        right={
          <div className="flex items-center gap-2">
            {!currentBranchId && branches && branches.length > 0 && (
              <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
                <option value="">ทุกสาขา</option>
                {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            )}
            <ExportButton data={exportRows} filename="รายงานต้นทุนเมนู" sheetName="FoodCost" />
          </div>
        } />

      <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mb-5">
        <Card className="p-4">
          <div className="text-xs text-stone-400">Food Cost % เฉลี่ยทั้งร้าน</div>
          <div className={`text-2xl font-serif mt-1 ${foodCostColor(avgFoodCost)}`}>{avgFoodCost != null ? `${avgFoodCost}%` : "-"}</div>
        </Card>
        <Card className="p-4">
          <div className="flex items-center gap-1.5 text-xs text-stone-400">
            <AlertTriangle size={13} className={overTargetCount > 0 ? "text-rose-500" : "text-stone-300"} /> เมนูต้นทุนเกินเป้าหมาย
          </div>
          <div className={`text-2xl font-serif mt-1 ${overTargetCount > 0 ? "text-rose-600" : "text-stone-900"}`}>{overTargetCount}</div>
        </Card>
        <Card className="p-4">
          <div className="text-xs text-stone-400">เมนูที่ยังไม่ผูกสูตรวัตถุดิบ</div>
          <div className="text-2xl font-serif text-stone-900 mt-1">{noRecipeCount}</div>
        </Card>
      </div>

      <div className="flex flex-wrap items-center gap-2 mb-4">
        {["thisMonth", "lastMonth", "thisYear", "custom"].map(mode => (
          <button key={mode} onClick={() => setPeriodMode(mode)}
            className={`px-4 py-2 rounded-full text-sm font-medium border ${periodMode === mode ? "bg-stone-900 text-white border-stone-900" : "bg-white border-stone-300 text-stone-600 hover:border-stone-400"}`}>
            {PERIOD_LABEL[mode]}
          </button>
        ))}
        {periodMode === "custom" && (
          <div className="flex items-center gap-2 ml-2">
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customFrom} onChange={e => setCustomFrom(e.target.value)} />
            <span className="text-stone-400 text-sm">ถึง</span>
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customTo} onChange={e => setCustomTo(e.target.value)} />
          </div>
        )}
      </div>

      <div className="flex flex-wrap items-center gap-3 mb-4">
        <select className={`${inputCls} max-w-[220px]`} value={categoryFilter} onChange={e => setCategoryFilter(e.target.value)}>
          <option value="">ทุกหมวดหมู่</option>
          {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
        <select className={`${inputCls} max-w-[220px]`} value={sortBy} onChange={e => setSortBy(e.target.value)}>
          <option value="foodCostDesc">เรียง: Food Cost % สูงสุดก่อน</option>
          <option value="foodCostAsc">เรียง: Food Cost % ต่ำสุดก่อน</option>
          <option value="profitDesc">เรียง: กำไรต่อจานมากสุดก่อน</option>
          <option value="qtyDesc">เรียง: ขายดีที่สุดก่อน</option>
          <option value="name">เรียง: ชื่อเมนู (ก-ฮ)</option>
        </select>
        <label className="flex items-center gap-2 text-sm text-stone-600 ml-auto">
          เป้าหมาย Food Cost ไม่เกิน
          <input type="number" className="w-16 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={targetPct} onChange={e => setTargetPct(Number(e.target.value) || 0)} />
          %
        </label>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">เมนู</th>
                <th className="px-4 py-3 font-medium">หมวดหมู่</th>
                <th className="px-4 py-3 font-medium">ราคาขาย</th>
                <th className="px-4 py-3 font-medium">ต้นทุนต่อจาน</th>
                <th className="px-4 py-3 font-medium">กำไรต่อจาน</th>
                <th className="px-4 py-3 font-medium">Food Cost %</th>
                <th className="px-4 py-3 font-medium">จำนวนขาย</th>
                <th className="px-4 py-3 font-medium">กำไรรวม</th>
              </tr>
            </thead>
            <tbody>
              {sorted.map(r => (
                <tr key={r.item.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 font-medium text-stone-800">
                    {r.item.name}
                    {!r.hasRecipe && <span className="ml-2 text-[10px] px-1.5 py-0.5 rounded bg-stone-100 text-stone-400 border border-stone-200">ไม่มีสูตร</span>}
                  </td>
                  <td className="px-4 py-3 text-stone-500">{r.cat?.name || "-"}</td>
                  <td className="px-4 py-3 font-mono text-stone-700">฿{fmtMoney(r.price)}</td>
                  <td className="px-4 py-3 font-mono text-stone-700">{r.hasRecipe ? `฿${fmtMoney(r.cost)}` : "-"}</td>
                  <td className={`px-4 py-3 font-mono ${r.hasRecipe ? (r.profit >= 0 ? "text-emerald-600" : "text-rose-600") : "text-stone-300"}`}>
                    {r.hasRecipe ? `฿${fmtMoney(r.profit)}` : "-"}
                  </td>
                  <td className={`px-4 py-3 font-mono font-medium ${foodCostColor(r.foodCostPct)}`}>{r.foodCostPct != null ? `${r.foodCostPct}%` : "-"}</td>
                  <td className="px-4 py-3 font-mono text-stone-500">{r.qtySold}</td>
                  <td className="px-4 py-3 font-mono text-stone-700">{r.totalProfit != null ? `฿${fmtMoney(r.totalProfit)}` : "-"}</td>
                </tr>
              ))}
              {sorted.length === 0 && (
                <tr><td colSpan={8} className="px-4 py-10 text-center text-stone-400">ไม่พบเมนูในหมวดหมู่นี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      <p className="text-xs text-stone-400 mt-4">
        Food Cost % = ต้นทุนวัตถุดิบต่อจาน ÷ ราคาขาย × 100 — ยิ่งเปอร์เซ็นต์ต่ำ กำไรต่อจานยิ่งดี (ร้านอาหารทั่วไปมักตั้งเป้าไว้ที่ 28-35%)
        เมนูที่ขึ้น "ไม่มีสูตร" ยังไม่ได้ผูกวัตถุดิบไว้ในหน้า "เพิ่มเมนูอาหาร" จึงคำนวณต้นทุนให้ไม่ได้ · "จำนวนขาย" และ "กำไรรวม" นับเฉพาะช่วงเวลาที่เลือกไว้ด้านบน
      </p>
    </div>
  );
}

/* =========================================================================
   PAGE: พนักงาน — ลงเวลาเข้า-ออกงาน
   ========================================================================= */

function minutesBetween(t1, t2) {
  const [h1, m1] = t1.split(":").map(Number);
  const [h2, m2] = t2.split(":").map(Number);
  return (h2 * 60 + m2) - (h1 * 60 + m1);
}
function fmtHoursMinutes(mins) {
  if (mins == null || mins < 0) return "-";
  const h = Math.floor(mins / 60), m = mins % 60;
  return `${h} ชม. ${m} นาที`;
}

/* =========================================================================
   PAGE: ฝ่ายบุคคล — ตั้งค่าการลงเวลา
   ========================================================================= */

function AttendanceSettingsPage({ attendanceSettings, setAttendanceSettings }) {
  const [form, setForm] = useState(attendanceSettings);
  const [saved, setSaved] = useState(false);

  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }

  function saveSettings() {
    setAttendanceSettings(form);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="ตั้งค่าการลงเวลา" subtitle="กำหนดว่าต้องถ่ายรูปตอนลงเวลาเข้า-ออกงานหรือไม่" />

      <Card className="p-5 max-w-md mb-5">
        <label className="flex items-center justify-between cursor-pointer">
          <div>
            <div className="text-sm font-semibold text-stone-700 flex items-center gap-1.5"><ImageIcon size={15} className="text-amber-600" /> ถ่ายรูปตอนลงเวลา</div>
            <p className="text-xs text-stone-400 mt-1 max-w-xs">เมื่อเปิดใช้งาน พนักงานต้องถ่ายรูปหน้าตัวเองผ่านกล้องก่อนลงเวลาเข้า/ออกงานทุกครั้ง เพื่อยืนยันว่าเป็นตัวจริง</p>
          </div>
          <button onClick={() => set({ requirePhoto: !form.requirePhoto })}
            className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ml-4 ${form.requirePhoto ? "bg-emerald-500" : "bg-stone-300"}`}>
            <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${form.requirePhoto ? "translate-x-5" : "translate-x-0"}`} />
          </button>
        </label>
        <div className="mt-3 text-xs">
          {form.requirePhoto
            ? <span className="text-emerald-600 font-medium">เปิดใช้งานอยู่ — ต้องถ่ายรูปทุกครั้งที่ลงเวลา</span>
            : <span className="text-stone-400">ปิดใช้งานอยู่ — ลงเวลาด้วย PIN อย่างเดียว</span>}
        </div>
      </Card>

      <Card className="p-5 max-w-md mb-5">
        <label className="flex items-center justify-between cursor-pointer mb-1">
          <div>
            <div className="text-sm font-semibold text-stone-700 flex items-center gap-1.5"><MapPin size={15} className="text-amber-600" /> เปิดใช้งาน Check-in ตาม GPS</div>
            <p className="text-xs text-stone-400 mt-1 max-w-xs">เมื่อเปิดใช้งาน พนักงานต้องอยู่ในรัศมีที่กำหนดจากสาขาของตัวเองจึงจะลงเวลาได้ — ตำแหน่ง GPS ของแต่ละสาขาตั้งค่าได้ที่หน้า "ตั้งค่าระบบ → สาขา"</p>
          </div>
          <button onClick={() => set({ gpsEnabled: !form.gpsEnabled })}
            className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ml-4 ${form.gpsEnabled ? "bg-emerald-500" : "bg-stone-300"}`}>
            <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${form.gpsEnabled ? "translate-x-5" : "translate-x-0"}`} />
          </button>
        </label>

        {form.gpsEnabled && (
          <div className="mt-4">
            <Field label="รัศมีที่อนุญาต (เมตร)">
              <input type="number" min={0} className={inputCls} value={form.gpsRadiusMeters} onChange={e => set({ gpsRadiusMeters: Number(e.target.value) || 0 })} />
            </Field>
          </div>
        )}
      </Card>

      <div className="flex items-center gap-3 max-w-md">
        <Btn onClick={saveSettings}>บันทึก</Btn>
        {saved && <span className="text-xs text-emerald-600">บันทึกแล้ว</span>}
      </div>
    </div>
  );
}

function AttendancePage({ attendance, setAttendance, staff, attendanceSettings, branches }) {
  const [pinInput, setPinInput] = useState("");
  const [punchMessage, setPunchMessage] = useState(null); // { type: "in"|"out"|"error", text }
  const [locating, setLocating] = useState(false);
  const [cameraOn, setCameraOn] = useState(false);
  const [capturedPhoto, setCapturedPhoto] = useState(null);
  const [cameraError, setCameraError] = useState("");
  const videoRef = useRef(null);
  const streamRef = useRef(null);
  const gpsEnabled = !!attendanceSettings?.gpsEnabled;
  const gpsRadiusMeters = attendanceSettings?.gpsRadiusMeters || 100;
  const [nowClock, setNowClock] = useState(() => new Date());
  useEffect(() => {
    const timer = setInterval(() => setNowClock(new Date()), 1000);
    return () => clearInterval(timer);
  }, []);
  // Each staff member may work at one or more branches; check-in is valid if
  // the current position is within range of ANY of their assigned branches'
  // own GPS coordinates (falls back to the old single store-wide GPS point
  // for branches that haven't set their own location yet).
  function branchLocationsFor(staffMember) {
    const relevantBranches = (branches || []).filter(b =>
      !staffMember.branchIds?.length || staffMember.branchIds.includes(b.id)
    );
    const withGps = relevantBranches.filter(b => b.gpsLat != null && b.gpsLng != null);
    if (withGps.length > 0) return withGps.map(b => ({ lat: b.gpsLat, lng: b.gpsLng, name: b.name }));
    // No per-branch GPS set anywhere relevant — fall back to the legacy global point.
    if (attendanceSettings?.gpsLat != null) return [{ lat: attendanceSettings.gpsLat, lng: attendanceSettings.gpsLng, name: null }];
    return [];
  }

  useEffect(() => {
    return () => { streamRef.current?.getTracks().forEach(t => t.stop()); };
  }, []);

  async function openCamera() {
    setCameraError("");
    setCapturedPhoto(null);
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user" } });
      streamRef.current = stream;
      setCameraOn(true);
      setTimeout(() => { if (videoRef.current) videoRef.current.srcObject = stream; }, 0);
    } catch {
      setCameraError("เปิดกล้องไม่ได้ กรุณาอนุญาตการเข้าถึงกล้องของเบราว์เซอร์");
    }
  }
  function takePhoto() {
    const video = videoRef.current;
    if (!video) return;
    const canvas = document.createElement("canvas");
    canvas.width = video.videoWidth || 320;
    canvas.height = video.videoHeight || 240;
    canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
    setCapturedPhoto(canvas.toDataURL("image/jpeg", 0.8));
    streamRef.current?.getTracks().forEach(t => t.stop());
    setCameraOn(false);
  }
  function retakePhoto() {
    setCapturedPhoto(null);
    openCamera();
  }

  function getCurrentPosition() {
    return new Promise((resolve, reject) => {
      if (!navigator.geolocation) { reject(new Error("เบราว์เซอร์นี้ไม่รองรับ GPS")); return; }
      navigator.geolocation.getCurrentPosition(
        pos => resolve({ lat: pos.coords.latitude, lng: pos.coords.longitude }),
        err => reject(err),
        { enableHighAccuracy: true, timeout: 10000 }
      );
    });
  }
  function haversineMeters(lat1, lng1, lat2, lng2) {
    const R = 6371000;
    const toRad = d => (d * Math.PI) / 180;
    const dLat = toRad(lat2 - lat1), dLng = toRad(lng2 - lng1);
    const a = Math.sin(dLat / 2) ** 2 + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng / 2) ** 2;
    return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  }

  async function handlePunch() {
    const staffMember = staff.find(s => s.pin === pinInput && s.active);
    if (!staffMember) {
      setPunchMessage({ type: "error", text: "PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่" });
      setPinInput("");
      return;
    }

    if (attendanceSettings?.requirePhoto && !capturedPhoto) {
      setPunchMessage({ type: "error", text: "กรุณาถ่ายรูปก่อนลงเวลา" });
      return;
    }

    if (gpsEnabled) {
      const validLocations = branchLocationsFor(staffMember);
      if (validLocations.length === 0) {
        setPunchMessage({ type: "error", text: "ยังไม่ได้ตั้งค่าตำแหน่งร้าน กรุณาตั้งค่า GPS ก่อน" });
        return;
      }
      setLocating(true);
      try {
        const pos = await getCurrentPosition();
        const distances = validLocations.map(loc => ({ ...loc, distance: haversineMeters(loc.lat, loc.lng, pos.lat, pos.lng) }));
        const nearest = distances.reduce((min, d) => d.distance < min.distance ? d : min, distances[0]);
        setLocating(false);
        if (nearest.distance > gpsRadiusMeters) {
          const branchNote = nearest.name ? ` (ใกล้ที่สุด: ${nearest.name})` : "";
          setPunchMessage({ type: "error", text: `อยู่นอกพื้นที่ร้าน${branchNote} ห่างประมาณ ${Math.round(nearest.distance)} เมตร ไม่สามารถลงเวลาได้` });
          return;
        }
      } catch {
        setLocating(false);
        setPunchMessage({ type: "error", text: "ไม่สามารถอ่านตำแหน่งปัจจุบันได้ กรุณาอนุญาตการเข้าถึงตำแหน่งของเบราว์เซอร์" });
        return;
      }
    }

    const today = new Date().toISOString().slice(0, 10);
    const now = new Date();
    const nowTime = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
    const openRecord = attendance.find(a => a.staffId === staffMember.id && a.date === today && !a.clockOut);
    try {
      // Persists to the real database via thenuar-backend; the server
      // decides clock-in vs clock-out (same "first punch today = in, next =
      // out" rule) and hands back the saved record to merge in directly.
      const { action, record } = await api.punch(staffMember.id, capturedPhoto || null);
      if (action === "clock_out") {
        setAttendance(prev => prev.map(a => a.id === record.id ? record : a));
        setPunchMessage({ type: "out", text: `${staffMember.name} ลงเวลาออกงานแล้ว เวลา ${record.clockOut}` });
      } else {
        setAttendance(prev => [...prev, record]);
        setPunchMessage({ type: "in", text: `${staffMember.name} ลงเวลาเข้างานแล้ว เวลา ${record.clockIn}` });
      }
    } catch (err) {
      // API unreachable — still record the punch locally so the front desk
      // isn't blocked by a network hiccup; it just won't be saved to the
      // server until it's reachable again.
      console.error("บันทึกลงเวลาไปเซิร์ฟเวอร์ไม่สำเร็จ ใช้ข้อมูลในเครื่องแทนไปก่อน:", err);
      if (openRecord) {
        setAttendance(prev => prev.map(a => a.id === openRecord.id ? { ...a, clockOut: nowTime, clockOutPhoto: capturedPhoto || null } : a));
        setPunchMessage({ type: "out", text: `${staffMember.name} ลงเวลาออกงานแล้ว เวลา ${nowTime}` });
      } else {
        setAttendance(prev => [...prev, { id: "att" + Date.now(), staffId: staffMember.id, date: today, clockIn: nowTime, clockOut: null, clockInPhoto: capturedPhoto || null }]);
        setPunchMessage({ type: "in", text: `${staffMember.name} ลงเวลาเข้างานแล้ว เวลา ${nowTime}` });
      }
    }
    setPinInput("");
    setCapturedPhoto(null);
  }

  return (
    <div>
      <div className="text-center mb-6">
        <div className="text-xs font-semibold tracking-widest text-amber-700 uppercase mb-1">พนักงาน</div>
        <h1 className="text-2xl font-serif text-stone-900">ลงเวลาเข้า-ออกงาน</h1>
        <div className="text-sm text-stone-500 mt-1 font-mono">
          {nowClock.toLocaleTimeString("th-TH", { hour: "2-digit", minute: "2-digit", second: "2-digit" })}
        </div>
      </div>

      <Card className="p-8 max-w-sm mx-auto text-center">
        <Clock size={32} className="text-amber-600 mx-auto mb-3" />
        <div className="text-sm text-stone-500 mb-4">กรอก PIN 6 หลักของพนักงานเพื่อลงเวลาเข้า/ออกงาน</div>

        {attendanceSettings?.requirePhoto && (
          <div className="mb-4">
            {capturedPhoto ? (
              <div>
                <img src={capturedPhoto} alt="รูปถ่ายลงเวลา" className="w-32 h-32 object-cover rounded-lg mx-auto border border-stone-200" />
                <button onClick={retakePhoto} className="text-xs text-sky-700 hover:text-sky-900 mt-1.5">ถ่ายใหม่</button>
              </div>
            ) : cameraOn ? (
              <div>
                <video ref={videoRef} autoPlay playsInline className="w-full max-w-[220px] mx-auto rounded-lg bg-stone-900 aspect-square object-cover" />
                <Btn className="w-full justify-center mt-2" onClick={takePhoto}><ImageIcon size={14} /> ถ่ายรูป</Btn>
              </div>
            ) : (
              <Btn variant="ghost" className="w-full justify-center" onClick={openCamera}><ImageIcon size={14} /> เปิดกล้องถ่ายรูปก่อนลงเวลา</Btn>
            )}
            {cameraError && <div className="text-xs text-rose-500 mt-1.5">{cameraError}</div>}
          </div>
        )}

        <input type="password" inputMode="numeric" maxLength={6} autoFocus
          className="w-full text-center text-2xl tracking-[0.5em] rounded-lg border border-stone-300 px-3 py-3 focus:outline-none focus:ring-2 focus:ring-amber-400"
          value={pinInput} onChange={e => { setPinInput(e.target.value.replace(/\D/g, "").slice(0, 6)); setPunchMessage(null); }}
          onKeyDown={e => e.key === "Enter" && pinInput.length === 6 && handlePunch()}
          placeholder="••••••" />
        <Btn className="w-full justify-center mt-4" disabled={pinInput.length !== 6 || locating || (attendanceSettings?.requirePhoto && !capturedPhoto)} onClick={handlePunch}>
          {locating ? "กำลังตรวจสอบตำแหน่ง..." : "ลงเวลา"}
        </Btn>
        {gpsEnabled && (
          <div className="flex items-center justify-center gap-1.5 text-[11px] text-stone-400 mt-3">
            <MapPin size={12} /> ต้องอยู่ในรัศมี {gpsRadiusMeters} เมตรจากสาขาจึงลงเวลาได้
          </div>
        )}
        {punchMessage && (
          <div className={`mt-4 text-sm rounded-lg px-3 py-2.5 ${punchMessage.type === "error" ? "bg-rose-50 text-rose-600" : punchMessage.type === "out" ? "bg-sky-50 text-sky-700" : "bg-emerald-50 text-emerald-700"}`}>
            {punchMessage.text}
          </div>
        )}
      </Card>

      {gpsEnabled && (
        <p className="text-xs text-stone-400 max-w-sm mx-auto mt-3 text-center">
          ระบบตรวจสอบตำแหน่ง GPS ก่อนลงเวลา (ตั้งค่าได้ที่หน้า "ตั้งค่าการลงเวลา")
        </p>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ฝ่ายบุคคล — รายงานเวลาเข้า-ออกงาน
   ========================================================================= */

function AttendanceReportPage({ attendance, setAttendance, staff, workSchedules, ownerProfile, logActivity }) {
  const [staffFilter, setStaffFilter] = useState("");
  const [periodMode, setPeriodMode] = useState("month"); // "month" | "custom"
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [customFrom, setCustomFrom] = useState(new Date().toISOString().slice(0, 8) + "01");
  const [customTo, setCustomTo] = useState(new Date().toISOString().slice(0, 10));
  const [editingRecord, setEditingRecord] = useState(null);
  const [deletingRecord, setDeletingRecord] = useState(null);
  const [viewingPhotos, setViewingPhotos] = useState(null);

  function staffName(id) { return staff.find(s => s.id === id)?.name || "-"; }

  const filteredRecords = attendance
    .filter(a => {
      if (staffFilter && a.staffId !== staffFilter) return false;
      if (periodMode === "month") return !monthFilter || a.date.slice(0, 7) === monthFilter;
      return a.date >= customFrom && a.date <= customTo;
    })
    .sort((a, b) => b.date.localeCompare(a.date));

  function recordStatus(a) {
    if (!a.clockOut) return { label: "กำลังทำงาน", style: "bg-emerald-50 text-emerald-700 border-emerald-300" };
    const staffMember = staff.find(s => s.id === a.staffId);
    const schedule = workSchedules.find(s => s.id === staffMember?.scheduleId);
    if (!schedule) return { label: "ไม่มีตารางเวลา", style: "bg-stone-100 text-stone-400 border-stone-300" };
    const graceLimit = minutesBetween("00:00", schedule.startTime) + (schedule.graceMinutes || 0);
    const clockInMinutes = minutesBetween("00:00", a.clockIn);
    const late = clockInMinutes > graceLimit;
    const ot = minutesBetween(schedule.endTime, a.clockOut) > 0;
    if (late) return { label: "มาสาย", style: "bg-rose-50 text-rose-700 border-rose-300" };
    if (ot) return { label: "ทำงานล่วงเวลา", style: "bg-sky-50 text-sky-700 border-sky-300" };
    return { label: "ปกติ", style: "bg-stone-100 text-stone-500 border-stone-300" };
  }
  function computeLateOT(a) {
    if (!a.clockOut) return { lateMinutes: null, otMinutes: null };
    const staffMember = staff.find(s => s.id === a.staffId);
    const schedule = workSchedules.find(s => s.id === staffMember?.scheduleId);
    if (!schedule) return { lateMinutes: null, otMinutes: null };
    const startMinutes = minutesBetween("00:00", schedule.startTime);
    const clockInMinutes = minutesBetween("00:00", a.clockIn);
    const lateMinutes = Math.max(0, clockInMinutes - startMinutes);
    const otMinutes = Math.max(0, minutesBetween(schedule.endTime, a.clockOut));
    return { lateMinutes, otMinutes };
  }

  function openEdit(a) { setEditingRecord({ ...a }); }
  function saveEdit() {
    setAttendance(prev => prev.map(a => a.id === editingRecord.id ? editingRecord : a));
    setEditingRecord(null);
  }
  function confirmDelete() {
    setAttendance(prev => prev.filter(a => a.id !== deletingRecord.id));
    setDeletingRecord(null);
  }

  const exportRows = filteredRecords.map(a => {
    const mins = a.clockOut ? minutesBetween(a.clockIn, a.clockOut) : null;
    const { lateMinutes, otMinutes } = computeLateOT(a);
    return {
      "พนักงาน": staffName(a.staffId), "วันที่": fmtDate(a.date), "เวลาเข้า": a.clockIn,
      "เวลาออก": a.clockOut || "-", "ชั่วโมงทำงาน": mins != null ? Math.round((mins / 60) * 100) / 100 : "",
      "มาสาย (นาที)": lateMinutes != null ? lateMinutes : "", "OT (นาที)": otMinutes != null ? otMinutes : "",
      "สถานะ": recordStatus(a).label,
    };
  });

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="รายงานเวลาเข้า-ออกงาน" subtitle="ดูและแก้ไขประวัติการลงเวลาของพนักงาน" />

      <div className="flex flex-wrap items-center gap-3 mb-4">
        <select className={`${inputCls} max-w-[200px]`} value={staffFilter} onChange={e => setStaffFilter(e.target.value)}>
          <option value="">ทุกคน</option>
          {staff.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
        </select>
        <div className="flex rounded-lg border border-stone-300 overflow-hidden">
          <button onClick={() => setPeriodMode("month")} className={`px-3 py-2 text-sm ${periodMode === "month" ? "bg-stone-900 text-white" : "bg-white text-stone-600"}`}>รายเดือน</button>
          <button onClick={() => setPeriodMode("custom")} className={`px-3 py-2 text-sm ${periodMode === "custom" ? "bg-stone-900 text-white" : "bg-white text-stone-600"}`}>กำหนดเอง</button>
        </div>
        {periodMode === "month" ? (
          <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        ) : (
          <div className="flex items-center gap-2">
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customFrom} onChange={e => setCustomFrom(e.target.value)} />
            <span className="text-stone-400 text-sm">ถึง</span>
            <input type="date" className={`${inputCls} max-w-[160px]`} value={customTo} onChange={e => setCustomTo(e.target.value)} />
          </div>
        )}
        <div className="ml-auto">
          <ExportButton data={exportRows} filename="รายงานเวลาเข้า-ออกงาน" sheetName="Attendance" />
        </div>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">พนักงาน</th>
                <th className="px-4 py-3 font-medium">วันที่</th>
                <th className="px-4 py-3 font-medium">เวลาเข้า</th>
                <th className="px-4 py-3 font-medium">เวลาออก</th>
                <th className="px-4 py-3 font-medium">ชั่วโมงทำงาน</th>
                <th className="px-4 py-3 font-medium">มาสาย (นาที)</th>
                <th className="px-4 py-3 font-medium">OT (นาที)</th>
                <th className="px-4 py-3 font-medium">สถานะ</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {filteredRecords.map(a => {
                const mins = a.clockOut ? minutesBetween(a.clockIn, a.clockOut) : null;
                const status = recordStatus(a);
                const { lateMinutes, otMinutes } = computeLateOT(a);
                return (
                  <tr key={a.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 font-medium text-stone-800">{staffName(a.staffId)}</td>
                    <td className="px-4 py-3 text-stone-400">{fmtDate(a.date)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">{a.clockIn}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">{a.clockOut || "-"}</td>
                    <td className="px-4 py-3 font-mono text-stone-500">{fmtHoursMinutes(mins)}</td>
                    <td className={`px-4 py-3 font-mono ${lateMinutes > 0 ? "text-rose-600" : "text-stone-400"}`}>{lateMinutes != null ? lateMinutes : "-"}</td>
                    <td className={`px-4 py-3 font-mono ${otMinutes > 0 ? "text-sky-600" : "text-stone-400"}`}>{otMinutes != null ? otMinutes : "-"}</td>
                    <td className="px-4 py-3"><span className={`text-xs px-2 py-0.5 rounded border font-medium ${status.style}`}>{status.label}</span></td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-3">
                        {(a.clockInPhoto || a.clockOutPhoto) && (
                          <button onClick={() => setViewingPhotos(a)} className="text-stone-300 hover:text-sky-600" title="ดูรูปที่ถ่ายตอนลงเวลา"><ImageIcon size={15} /></button>
                        )}
                        <button onClick={() => openEdit(a)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                        <button onClick={() => setDeletingRecord(a)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {filteredRecords.length === 0 && (
                <tr><td colSpan={9} className="px-4 py-10 text-center text-stone-400">ไม่พบข้อมูลการลงเวลา</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-3">
        สถานะคำนวณจากตารางเวลาที่กำหนดให้พนักงานแต่ละคนในหน้า "กำหนดเวลาทำงาน" — พนักงานที่ยังไม่ได้กำหนดตารางเวลาจะไม่มีการตัดสิน "มาสาย/ล่วงเวลา" ให้
      </p>

      {/* Edit attendance record popup */}
      {editingRecord && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setEditingRecord(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขเวลา — {staffName(editingRecord.staffId)}</div>
              <button onClick={() => setEditingRecord(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="วันที่"><input type="date" className={inputCls} value={editingRecord.date} onChange={e => setEditingRecord(prev => ({ ...prev, date: e.target.value }))} /></Field>
              <Field label="เวลาเข้า"><input type="time" className={inputCls} value={editingRecord.clockIn} onChange={e => setEditingRecord(prev => ({ ...prev, clockIn: e.target.value }))} /></Field>
              <Field label="เวลาออก"><input type="time" className={inputCls} value={editingRecord.clockOut || ""} onChange={e => setEditingRecord(prev => ({ ...prev, clockOut: e.target.value || null }))} /></Field>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={saveEdit}>บันทึก</Btn>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingRecord && (
        <ConfirmDeletePin
          message={`ลบรายการลงเวลาของ "${staffName(deletingRecord.staffId)}" วันที่ ${fmtDate(deletingRecord.date)} ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingRecord(null)}
          onConfirm={confirmDelete}
          logActivity={logActivity} activityLabel={`ลบรายการลงเวลาของ ${staffName(deletingRecord.staffId)}`} activityCategory="พนักงาน"
        />
      )}

      {/* View clock-in/out photos popup */}
      {viewingPhotos && (
        <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setViewingPhotos(null)}>
          <div className="min-h-full flex items-start justify-center py-8">
          <div className="bg-white rounded-xl w-full max-w-lg p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">รูปตอนลงเวลา — {staffName(viewingPhotos.staffId)} ({fmtDate(viewingPhotos.date)})</div>
              <button onClick={() => setViewingPhotos(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div>
                <div className="text-xs text-stone-400 mb-1.5">เข้างาน {viewingPhotos.clockIn}</div>
                {viewingPhotos.clockInPhoto ? (
                  <img src={viewingPhotos.clockInPhoto} alt="รูปตอนเข้างาน" className="w-full rounded-lg border border-stone-200" />
                ) : (
                  <div className="aspect-square rounded-lg border border-dashed border-stone-200 flex items-center justify-center text-xs text-stone-300">ไม่มีรูป</div>
                )}
              </div>
              <div>
                <div className="text-xs text-stone-400 mb-1.5">ออกงาน {viewingPhotos.clockOut || "-"}</div>
                {viewingPhotos.clockOutPhoto ? (
                  <img src={viewingPhotos.clockOutPhoto} alt="รูปตอนออกงาน" className="w-full rounded-lg border border-stone-200" />
                ) : (
                  <div className="aspect-square rounded-lg border border-dashed border-stone-200 flex items-center justify-center text-xs text-stone-300">ไม่มีรูป</div>
                )}
              </div>
            </div>
          </div>
          </div>
        </div>
      )}
    </div>
  );
}


/* =========================================================================
   PAGE: พนักงาน — กำหนดเวลาทำงาน
   ========================================================================= */

function emptyWorkScheduleForm() {
  return { id: null, name: "", startTime: "09:00", endTime: "18:00", graceMinutes: 10 };
}

function WorkSchedulePage({ workSchedules, setWorkSchedules, staff, setStaff, lateAbsentPolicy, setLateAbsentPolicy, ownerProfile, logActivity }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(emptyWorkScheduleForm());
  const [deletingSchedule, setDeletingSchedule] = useState(null);
  const [lateCountInput, setLateCountInput] = useState(lateAbsentPolicy?.lateCountForAbsent ?? 3);
  const [policySaved, setPolicySaved] = useState(false);

  function savePolicy() {
    setLateAbsentPolicy({ lateCountForAbsent: Number(lateCountInput) || 0 });
    setPolicySaved(true);
    setTimeout(() => setPolicySaved(false), 1500);
  }

  function openAdd() {
    setForm(emptyWorkScheduleForm());
    setShowForm(true);
  }
  function openEdit(sch) {
    setForm({ ...sch });
    setShowForm(true);
  }
  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }
  function submit() {
    if (!form.name) return;
    if (form.id) {
      setWorkSchedules(prev => prev.map(s => s.id === form.id ? form : s));
    } else {
      setWorkSchedules(prev => [...prev, { ...form, id: "sch" + Date.now() }]);
    }
    setShowForm(false);
  }
  function countAssigned(schId) {
    return staff.filter(s => s.scheduleId === schId).length;
  }
  function confirmRemoveSchedule() {
    if (!deletingSchedule) return;
    setWorkSchedules(prev => prev.filter(s => s.id !== deletingSchedule.id));
    // Any staff assigned to the removed schedule fall back to unassigned.
    setStaff(prev => prev.map(s => s.scheduleId === deletingSchedule.id ? { ...s, scheduleId: "" } : s));
    setDeletingSchedule(null);
  }
  function assignSchedule(staffId, scheduleId) {
    setStaff(prev => prev.map(s => s.id === staffId ? { ...s, scheduleId } : s));
  }

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="กำหนดเวลาทำงาน" subtitle="ตั้งเวลาเข้า-ออกงานและกำหนดให้พนักงานแต่ละคน"
        right={<Btn onClick={openAdd}><Plus size={14} /> เพิ่มตารางเวลา</Btn>} />

      <Card className="p-4 mb-6 max-w-md">
        <div className="text-sm font-semibold text-stone-700 mb-1">นับมาสายเป็นวันขาดงาน</div>
        <p className="text-xs text-stone-400 mb-3">ใช้สำหรับนโยบายวินัยพนักงาน — มาสายครบตามจำนวนที่กำหนด ให้นับเทียบเท่าขาดงาน 1 วัน</p>
        <div className="flex items-center gap-2 text-sm text-stone-600">
          <span>กำหนด มาสาย</span>
          <input type="number" min={1} className="w-20 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-center"
            value={lateCountInput} onChange={e => setLateCountInput(e.target.value)} />
          <span>ครั้ง = ขาดงาน 1 วัน</span>
          <Btn onClick={savePolicy} className="ml-2">บันทึก</Btn>
          {policySaved && <span className="text-xs text-emerald-600">บันทึกแล้ว</span>}
        </div>
      </Card>

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ตารางเวลาทำงาน</div>
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 mb-6">
        {workSchedules.map(sch => (
          <Card key={sch.id} className="p-4">
            <div className="flex items-start justify-between mb-2">
              <div className="font-medium text-stone-800 text-sm">{sch.name}</div>
              <div className="flex items-center gap-2 flex-shrink-0">
                <button onClick={() => openEdit(sch)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
                <button onClick={() => setDeletingSchedule(sch)} className="text-stone-300 hover:text-rose-500"><Trash2 size={14} /></button>
              </div>
            </div>
            <div className="text-xs text-stone-500">เข้างาน {sch.startTime} · ออกงาน {sch.endTime}</div>
            <div className="text-xs text-stone-400 mt-1">มาสายถ้าเกิน {sch.graceMinutes} นาที</div>
            <div className="text-[11px] text-stone-300 mt-2">{countAssigned(sch.id)} คนใช้ตารางนี้</div>
          </Card>
        ))}
        {workSchedules.length === 0 && (
          <div className="col-span-full text-sm text-stone-400 text-center py-8 border border-dashed border-stone-300 rounded-lg">ยังไม่มีตารางเวลาทำงาน</div>
        )}
      </div>

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">กำหนดตารางเวลาให้พนักงานแต่ละคน</div>
      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">พนักงาน</th>
                <th className="px-4 py-3 font-medium">ตารางเวลาที่ใช้</th>
              </tr>
            </thead>
            <tbody>
              {staff.map(s => (
                <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 font-medium text-stone-800">{s.name}</td>
                  <td className="px-4 py-3">
                    <select className={`${inputCls} max-w-[260px]`} value={s.scheduleId || ""} onChange={e => assignSchedule(s.id, e.target.value)}>
                      <option value="">— ไม่ได้กำหนด —</option>
                      {workSchedules.map(sch => <option key={sch.id} value={sch.id}>{sch.name}</option>)}
                    </select>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Add / edit schedule popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขตารางเวลา" : "เพิ่มตารางเวลา"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อตารางเวลา"><input className={inputCls} value={form.name} onChange={e => set({ name: e.target.value })} placeholder="เช่น กะเช้า, กะบ่าย" /></Field>
              <div className="grid grid-cols-2 gap-3">
                <Field label="เวลาเข้างาน"><input type="time" className={inputCls} value={form.startTime} onChange={e => set({ startTime: e.target.value })} /></Field>
                <Field label="เวลาออกงาน"><input type="time" className={inputCls} value={form.endTime} onChange={e => set({ endTime: e.target.value })} /></Field>
              </div>
              <Field label="ถือว่ามาสายถ้าเข้าช้ากว่ากี่นาที">
                <input type="number" min={0} className={inputCls} value={form.graceMinutes} onChange={e => set({ graceMinutes: Number(e.target.value) || 0 })} />
              </Field>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "เพิ่มตารางเวลา"}</Btn>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingSchedule && (
        <ConfirmDeletePin
          message={`ลบ "${deletingSchedule.name}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingSchedule(null)}
          onConfirm={confirmRemoveSchedule}
          logActivity={logActivity} activityLabel={`ลบตารางกะ ${deletingSchedule.name}`} activityCategory="พนักงาน"
        />
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ฝ่ายบุคคล — กำหนดวันหยุด
   ========================================================================= */

function StaffDaysOffPage({ staff, setStaff, daysOff, setDaysOff, ownerProfile, positions, leaveTypes, currentBranchId, branches }) {
  const [viewDate, setViewDate] = useState(new Date());
  const [selectedDate, setSelectedDate] = useState(null); // "YYYY-MM-DD" | null
  const [removeApproval, setRemoveApproval] = useState(null); // { date, staffId, staffName, pin, error }
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const visibleStaff = staff.filter(s => !effectiveBranchId || !s.branchIds?.length || s.branchIds.includes(effectiveBranchId));
  // Color each staff member's day-off badge using their branch's own color —
  // if a specific branch is being viewed, use that branch's color for everyone
  // shown (they all belong to it); otherwise fall back to each staff member's
  // first assigned branch so mixed views stay visually distinguishable.
  function colorForStaff(s) {
    const branchId = effectiveBranchId || s.branchIds?.[0];
    return branches?.find(b => b.id === branchId)?.color || "#e11d48";
  }

  const THAI_MONTHS = ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"];
  const WEEKDAY_HEADERS = ["จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"];

  const year = viewDate.getFullYear();
  const month = viewDate.getMonth();
  const firstOfMonth = new Date(year, month, 1);
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const firstWeekday = (firstOfMonth.getDay() + 6) % 7; // Monday = 0

  const cells = [];
  for (let i = 0; i < firstWeekday; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  function dateKey(d) { return `${year}-${String(month + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`; }
  const todayKey = new Date().toISOString().slice(0, 10);

  function staffOffOn(key) {
    return daysOff.filter(d => d.date === key).map(d => visibleStaff.find(s => s.id === d.staffId)).filter(Boolean);
  }
  function isStaffOff(key, staffId) {
    return daysOff.some(d => d.date === key && d.staffId === staffId);
  }
  function toggleStaffOff(key, staffId) {
    setDaysOff(prev => {
      const exists = prev.some(d => d.date === key && d.staffId === staffId);
      if (exists) return prev.filter(d => !(d.date === key && d.staffId === staffId));
      return [...prev, { id: "do" + Date.now() + Math.random().toString(36).slice(2, 5), date: key, staffId, leaveType: leaveTypes[0]?.id || "" }];
    });
  }
  function setLeaveTypeFor(key, staffId, leaveTypeId) {
    setDaysOff(prev => prev.map(d => (d.date === key && d.staffId === staffId) ? { ...d, leaveType: leaveTypeId } : d));
  }
  function handleCheckboxToggle(key, staffId) {
    if (isStaffOff(key, staffId)) {
      // Removing an existing day off requires manager/owner approval.
      const s = staff.find(x => x.id === staffId);
      setRemoveApproval({ date: key, staffId, staffName: s?.name || "-", pin: "", error: "" });
    } else {
      toggleStaffOff(key, staffId);
    }
  }
  function requestRemoveFromList(date, staffId) {
    const s = staff.find(x => x.id === staffId);
    setRemoveApproval({ date, staffId, staffName: s?.name || "-", pin: "", error: "" });
  }
  function confirmRemoveApproval() {
    const manager = (staff || []).find(s => s.pin === removeApproval.pin && s.active);
    const isOwner = isOwnerPin(ownerProfile, removeApproval.pin);
    if (!manager && !isOwner) {
      setRemoveApproval(prev => ({ ...prev, error: "PIN ไม่ถูกต้อง ต้องเป็น PIN ผู้จัดการหรือเจ้าของร้าน" }));
      return;
    }
    if (manager && !isOwner) {
      const position = (positions || []).find(p => p.id === manager.positionId);
      if (!position?.pinPermissions?.includes("staffDaysOffDelete")) {
        setRemoveApproval(prev => ({ ...prev, error: `ตำแหน่ง "${position?.name || "-"}" ไม่มีสิทธิ์อนุมัติรายการนี้` }));
        return;
      }
    }
    toggleStaffOff(removeApproval.date, removeApproval.staffId);
    setRemoveApproval(null);
  }
  function changeMonth(delta) {
    setViewDate(new Date(year, month + delta, 1));
  }

  // Grouped, chronological list of days off within the month currently shown.
  const monthKeyPrefix = `${year}-${String(month + 1).padStart(2, "0")}`;
  const groupedList = Object.entries(
    daysOff
      .filter(d => d.date.startsWith(monthKeyPrefix))
      .reduce((acc, d) => {
        (acc[d.date] = acc[d.date] || []).push(d);
        return acc;
      }, {})
  ).sort((a, b) => a[0].localeCompare(b[0]));

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="กำหนดวันหยุด" subtitle="เลือกวันในปฏิทินเพื่อกำหนดว่าพนักงานคนไหนหยุดวันนั้น (หยุดพร้อมกันได้หลายคน)"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <div className="flex items-start gap-5">
      <div className="w-3/5 min-w-0">
      <Card className="p-5">
        <div className="flex items-center justify-between mb-4">
          <button onClick={() => changeMonth(-1)} className="w-8 h-8 flex items-center justify-center rounded-md border border-stone-300 text-stone-500 hover:bg-stone-50"><ChevronLeft size={16} /></button>
          <div className="font-semibold text-stone-800">{THAI_MONTHS[month]} {year + 543}</div>
          <button onClick={() => changeMonth(1)} className="w-8 h-8 flex items-center justify-center rounded-md border border-stone-300 text-stone-500 hover:bg-stone-50"><ChevronRight size={16} /></button>
        </div>

        <div className="grid grid-cols-7 gap-1.5 mb-1.5">
          {WEEKDAY_HEADERS.map(w => (
            <div key={w} className="text-center text-xs font-medium text-stone-400 py-1">{w}</div>
          ))}
        </div>
        <div className="grid grid-cols-7 gap-1.5">
          {cells.map((d, i) => {
            if (d == null) return <div key={i} />;
            const key = dateKey(d);
            const offStaff = staffOffOn(key);
            const isToday = key === todayKey;
            return (
              <button key={i} onClick={() => setSelectedDate(key)}
                className={`aspect-square rounded-lg border p-1.5 flex flex-col items-start text-left transition-colors ${isToday ? "border-amber-400 bg-amber-50" : "border-stone-200 hover:border-stone-300 hover:bg-stone-50"}`}>
                <span className={`text-xs font-medium ${isToday ? "text-amber-700" : "text-stone-600"}`}>{d}</span>
                <div className="flex-1 flex flex-col gap-0.5 mt-1 w-full overflow-hidden">
                  {offStaff.slice(0, 2).map(s => (
                    <span key={s.id} className="text-[10px] px-1 py-0.5 rounded truncate w-full"
                      style={{ backgroundColor: `${colorForStaff(s)}1a`, color: colorForStaff(s) }}>{s.name}</span>
                  ))}
                  {offStaff.length > 2 && <span className="text-[10px] text-stone-400">+{offStaff.length - 2} คน</span>}
                </div>
              </button>
            );
          })}
        </div>
      </Card>
      </div>

      <div className="w-2/5 flex-shrink-0">
        <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">รายการวันหยุดเดือนนี้</div>
        <Card className="p-4 max-h-[520px] overflow-y-auto">
          {groupedList.length === 0 && (
            <div className="text-sm text-stone-400 text-center py-8">ยังไม่มีวันหยุดในเดือนนี้</div>
          )}
          <div className="space-y-3">
            {groupedList.map(([date, entries]) => (
              <div key={date} className="pb-3 border-b border-stone-100 last:border-0 last:pb-0">
                <button onClick={() => setSelectedDate(date)} className="text-xs font-semibold text-stone-700 hover:text-amber-700 mb-1.5">
                  {fmtDate(date)}
                </button>
                <div className="flex flex-wrap gap-1.5">
                  {entries.map(e => {
                    const s = visibleStaff.find(x => x.id === e.staffId);
                    if (!s) return null;
                    const lt = leaveTypes.find(t => t.id === e.leaveType);
                    const c = colorForStaff(s);
                    return (
                      <span key={e.id} className="flex items-center gap-1 text-xs pl-2 pr-1 py-0.5 rounded-full"
                        style={{ backgroundColor: `${c}1a`, color: c }}>
                        {s.name}{lt && <span style={{ opacity: 0.7 }}>· {lt.name}</span>}
                        <button onClick={() => requestRemoveFromList(date, e.staffId)} className="hover:opacity-70"><X size={11} /></button>
                      </span>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>
      </div>

      {/* Assign staff off for the selected date */}
      {selectedDate && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setSelectedDate(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800">กำหนดวันหยุด</div>
              <button onClick={() => setSelectedDate(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-400 mb-4">{fmtDate(selectedDate)}</div>
            <div className="text-xs font-medium text-stone-500 mb-2">เลือกพนักงานที่หยุดวันนี้ (เลือกได้หลายคน)</div>
            <div className="space-y-1.5">
              {visibleStaff.map(s => {
                const isOff = isStaffOff(selectedDate, s.id);
                const entry = daysOff.find(d => d.date === selectedDate && d.staffId === s.id);
                const c = colorForStaff(s);
                return (
                  <div key={s.id} className="p-2.5 rounded-lg border border-stone-200">
                    <label className="flex items-center gap-2.5 cursor-pointer">
                      <input type="checkbox" checked={isOff} onChange={() => handleCheckboxToggle(selectedDate, s.id)} />
                      <span className="w-2 h-2 rounded-full flex-shrink-0" style={{ backgroundColor: c }} />
                      <span className="text-sm text-stone-700 flex-1">{s.name}</span>
                    </label>
                    {isOff && (
                      <select className="w-full mt-2 rounded-md border border-stone-300 px-2 py-1.5 text-xs"
                        value={entry?.leaveType || ""} onChange={e => setLeaveTypeFor(selectedDate, s.id, e.target.value)}>
                        {leaveTypes.map(lt => <option key={lt.id} value={lt.id}>{lt.name}</option>)}
                      </select>
                    )}
                  </div>
                );
              })}
            </div>
            <Btn className="w-full justify-center mt-4" onClick={() => setSelectedDate(null)}>เสร็จสิ้น</Btn>
          </div>
        </div>
      )}

      {/* PIN approval required to remove a day off */}
      {removeApproval && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setRemoveApproval(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 flex items-center gap-2"><ShieldCheck size={17} className="text-amber-600" /> ขออนุมัติลบวันหยุด</div>
              <button onClick={() => setRemoveApproval(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-500 mt-2 mb-4">ลบวันหยุดของ "{removeApproval.staffName}" วันที่ {fmtDate(removeApproval.date)}</div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} autoFocus className={inputCls}
                value={removeApproval.pin} onChange={e => setRemoveApproval(prev => ({ ...prev, pin: e.target.value.replace(/\D/g, "").slice(0, 6), error: "" }))}
                placeholder="••••••" />
            </Field>
            {removeApproval.error && <div className="text-xs text-rose-500 mt-1.5">{removeApproval.error}</div>}
            <Btn className="w-full justify-center mt-4" disabled={removeApproval.pin.length !== 6} onClick={confirmRemoveApproval}>ยืนยันลบวันหยุด</Btn>
          </div>
        </div>
      )}
    </div>
  );
}


/* =========================================================================
   PAGE: ตั้งค่าระบบ — โปรไฟล์เจ้าของ
   ========================================================================= */

function OwnerProfilePage({ ownerProfile, setOwnerProfile }) {
  const [showAddOwner, setShowAddOwner] = useState(false);
  const emptyOwnerForm = { name: "", phone: "", email: "", pin: "", confirmPin: "" };
  const [ownerForm, setOwnerForm] = useState(emptyOwnerForm);
  const [ownerFormError, setOwnerFormError] = useState("");
  const [deletingOwner, setDeletingOwner] = useState(null);

  const [editingOwner, setEditingOwner] = useState(null); // { isPrimary, id, name, phone, email, pin }
  const [editForm, setEditForm] = useState(null); // { name, phone, email, newPin, confirmPin }
  const [editError, setEditError] = useState("");

  function openAddOwner() {
    setOwnerForm(emptyOwnerForm);
    setOwnerFormError("");
    setShowAddOwner(true);
  }
  function saveNewOwner() {
    if (!ownerForm.name.trim()) { setOwnerFormError("กรุณากรอกชื่อเจ้าของ"); return; }
    if (ownerForm.pin.length !== 6) { setOwnerFormError("PIN ต้องเป็นตัวเลข 6 หลัก"); return; }
    if (ownerForm.pin !== ownerForm.confirmPin) { setOwnerFormError("PIN และ PIN ยืนยันไม่ตรงกัน"); return; }
    const allPins = [ownerProfile.pin, ...(ownerProfile.owners || []).map(o => o.pin)].filter(Boolean);
    if (allPins.includes(ownerForm.pin)) { setOwnerFormError("PIN นี้ถูกใช้แล้วโดยเจ้าของคนอื่น กรุณาตั้ง PIN ใหม่"); return; }
    setOwnerProfile(prev => ({
      ...prev,
      owners: [...(prev.owners || []), { id: "own" + Date.now(), name: ownerForm.name.trim(), phone: ownerForm.phone.trim(), email: ownerForm.email.trim(), pin: ownerForm.pin }],
    }));
    setShowAddOwner(false);
  }
  function confirmRemoveOwner() {
    setOwnerProfile(prev => ({ ...prev, owners: (prev.owners || []).filter(o => o.id !== deletingOwner.id) }));
    setDeletingOwner(null);
    setEditingOwner(null);
  }

  function openEdit(owner, isPrimary) {
    setEditingOwner({ ...owner, isPrimary });
    setEditForm({ name: owner.name, phone: owner.phone || "", email: owner.email || "", newPin: "", confirmPin: "" });
    setEditError("");
  }
  function saveEdit() {
    if (!editForm.name.trim()) { setEditError("กรุณากรอกชื่อเจ้าของ"); return; }
    let pinToSave = editingOwner.pin;
    if (editForm.newPin || editForm.confirmPin) {
      if (editForm.newPin.length !== 6) { setEditError("PIN ใหม่ต้องเป็นตัวเลข 6 หลัก"); return; }
      if (editForm.newPin !== editForm.confirmPin) { setEditError("PIN ใหม่และ PIN ยืนยันไม่ตรงกัน"); return; }
      const otherPins = [ownerProfile.pin, ...(ownerProfile.owners || []).map(o => o.pin)]
        .filter(p => p && p !== editingOwner.pin);
      if (otherPins.includes(editForm.newPin)) { setEditError("PIN นี้ถูกใช้แล้วโดยเจ้าของคนอื่น กรุณาตั้ง PIN ใหม่"); return; }
      pinToSave = editForm.newPin;
    }
    const updated = { name: editForm.name.trim(), phone: editForm.phone.trim(), email: editForm.email.trim(), pin: pinToSave };
    if (editingOwner.isPrimary) {
      setOwnerProfile(prev => ({ ...prev, ...updated }));
    } else {
      setOwnerProfile(prev => ({ ...prev, owners: (prev.owners || []).map(o => o.id === editingOwner.id ? { ...o, ...updated } : o) }));
    }
    setEditingOwner(null);
  }

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="โปรไฟล์เจ้าของ" subtitle="ข้อมูลเจ้าของร้านและ PIN สำหรับอนุมัติรายการสำคัญ"
        right={<Btn onClick={openAddOwner}><Plus size={14} /> เพิ่มเจ้าของ</Btn>} />

      <Card className="p-5 max-w-2xl">
        <div className="text-sm font-semibold text-stone-700 mb-1">รายชื่อเจ้าของทั้งหมด</div>
        <p className="text-xs text-stone-400 mb-3">
          เจ้าของแต่ละคนมี PIN ของตัวเอง ใช้ล็อกอินเข้าระบบและอนุมัติรายการสำคัญได้เหมือนกันทุกประการ — กด "จัดการ" เพื่อแก้ไขข้อมูลหรือเปลี่ยน PIN
        </p>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-3 py-2 font-medium">ชื่อ</th>
                <th className="px-3 py-2 font-medium">เบอร์โทร</th>
                <th className="px-3 py-2 font-medium">อีเมล</th>
                <th className="px-3 py-2 font-medium text-right">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              <tr className="border-b border-stone-100 hover:bg-stone-50">
                <td className="px-3 py-2.5 font-medium text-stone-800">
                  {ownerProfile.name}
                  <span className="ml-1.5 text-[10px] px-1.5 py-0.5 rounded-full bg-amber-50 text-amber-700 border border-amber-200 align-middle">หลัก</span>
                </td>
                <td className="px-3 py-2.5 text-stone-500">{ownerProfile.phone || "-"}</td>
                <td className="px-3 py-2.5 text-stone-500">{ownerProfile.email || "-"}</td>
                <td className="px-3 py-2.5 text-right">
                  <Btn variant="ghost" onClick={() => openEdit(ownerProfile, true)}>จัดการ</Btn>
                </td>
              </tr>
              {(ownerProfile.owners || []).map(o => (
                <tr key={o.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-3 py-2.5 font-medium text-stone-800">{o.name}</td>
                  <td className="px-3 py-2.5 text-stone-500">{o.phone || "-"}</td>
                  <td className="px-3 py-2.5 text-stone-500">{o.email || "-"}</td>
                  <td className="px-3 py-2.5 text-right">
                    <Btn variant="ghost" onClick={() => openEdit(o, false)}>จัดการ</Btn>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Add owner popup */}
      {showAddOwner && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowAddOwner(false)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">เพิ่มเจ้าของ</div>
              <button onClick={() => setShowAddOwner(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อ"><input className={inputCls} value={ownerForm.name} onChange={e => { setOwnerForm(f => ({ ...f, name: e.target.value })); setOwnerFormError(""); }} /></Field>
              <Field label="เบอร์โทร"><input className={inputCls} value={ownerForm.phone} onChange={e => setOwnerForm(f => ({ ...f, phone: e.target.value }))} /></Field>
              <Field label="อีเมล"><input type="email" className={inputCls} value={ownerForm.email} onChange={e => setOwnerForm(f => ({ ...f, email: e.target.value }))} /></Field>
              <Field label="PIN (6 หลัก)">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls} value={ownerForm.pin} onChange={e => { setOwnerForm(f => ({ ...f, pin: e.target.value.replace(/\D/g, "").slice(0, 6) })); setOwnerFormError(""); }} placeholder="••••••" />
              </Field>
              <Field label="ยืนยัน PIN">
                <input type="password" inputMode="numeric" maxLength={6} className={inputCls} value={ownerForm.confirmPin} onChange={e => { setOwnerForm(f => ({ ...f, confirmPin: e.target.value.replace(/\D/g, "").slice(0, 6) })); setOwnerFormError(""); }} placeholder="••••••" />
              </Field>
              {ownerFormError && <div className="text-xs text-rose-500">{ownerFormError}</div>}
            </div>
            <Btn className="w-full justify-center mt-4" onClick={saveNewOwner}>เพิ่มเจ้าของ</Btn>
          </div>
        </div>
      )}

      {/* Edit owner popup — used for both the primary owner and additional owners */}
      {editingOwner && editForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setEditingOwner(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขข้อมูลเจ้าของ</div>
              <button onClick={() => setEditingOwner(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อ"><input className={inputCls} value={editForm.name} onChange={e => { setEditForm(f => ({ ...f, name: e.target.value })); setEditError(""); }} /></Field>
              <Field label="เบอร์โทร"><input className={inputCls} value={editForm.phone} onChange={e => setEditForm(f => ({ ...f, phone: e.target.value }))} /></Field>
              <Field label="อีเมล"><input type="email" className={inputCls} value={editForm.email} onChange={e => setEditForm(f => ({ ...f, email: e.target.value }))} /></Field>

              <div className="pt-2 border-t border-stone-100">
                <div className="flex items-center gap-2 text-xs font-medium text-stone-500 mb-2">
                  <ShieldCheck size={14} className="text-amber-600" /> เปลี่ยน PIN (เว้นว่างไว้ถ้าไม่ต้องการเปลี่ยน)
                </div>
                <div className="space-y-3">
                  <Field label="PIN ใหม่ (6 หลัก)">
                    <input type="password" inputMode="numeric" maxLength={6} className={inputCls} value={editForm.newPin} onChange={e => { setEditForm(f => ({ ...f, newPin: e.target.value.replace(/\D/g, "").slice(0, 6) })); setEditError(""); }} placeholder="••••••" />
                  </Field>
                  <Field label="ยืนยัน PIN ใหม่">
                    <input type="password" inputMode="numeric" maxLength={6} className={inputCls} value={editForm.confirmPin} onChange={e => { setEditForm(f => ({ ...f, confirmPin: e.target.value.replace(/\D/g, "").slice(0, 6) })); setEditError(""); }} placeholder="••••••" />
                  </Field>
                </div>
              </div>
              {editError && <div className="text-xs text-rose-500">{editError}</div>}
            </div>

            <div className="flex items-center gap-2 mt-4">
              <Btn className="flex-1 justify-center" onClick={saveEdit}>บันทึก</Btn>
              {!editingOwner.isPrimary && (
                <button onClick={() => setDeletingOwner(editingOwner)} className="text-rose-500 hover:text-rose-700 p-2"><Trash2 size={18} /></button>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Confirm remove owner popup */}
      {deletingOwner && (
        <div className="fixed inset-0 bg-stone-900/50 flex items-center justify-center z-[60] p-4" onClick={() => setDeletingOwner(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="text-sm text-stone-700 mb-4">ลบเจ้าของ "{deletingOwner.name}" ใช่ไหม?</div>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setDeletingOwner(null)}>ยกเลิก</Btn>
              <Btn onClick={confirmRemoveOwner}>ยืนยันลบ</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ฝ่ายบุคคล — กำหนดสิทธิ์วันลา
   ========================================================================= */

function LeaveEntitlementsPage({ leaveTypes, setLeaveTypes, staff, setStaff, daysOff, ownerProfile, logActivity }) {
  const [showTypeForm, setShowTypeForm] = useState(false);
  const [typeForm, setTypeForm] = useState({ id: null, name: "", defaultQuotaDays: "" });
  const [deletingType, setDeletingType] = useState(null);
  const [editingQuotas, setEditingQuotas] = useState(null); // { staffId, staffName, quotas: {ltId: value}, pin, error }
  const currentYear = new Date().getFullYear();

  function openAddType() {
    setTypeForm({ id: null, name: "", defaultQuotaDays: "" });
    setShowTypeForm(true);
  }
  function openEditType(lt) {
    setTypeForm({ id: lt.id, name: lt.name, defaultQuotaDays: String(lt.defaultQuotaDays) });
    setShowTypeForm(true);
  }
  function submitType() {
    if (!typeForm.name) return;
    const payload = { id: typeForm.id || "lt" + Date.now(), name: typeForm.name, defaultQuotaDays: Number(typeForm.defaultQuotaDays) || 0 };
    if (typeForm.id) {
      setLeaveTypes(prev => prev.map(t => t.id === typeForm.id ? payload : t));
    } else {
      setLeaveTypes(prev => [...prev, payload]);
    }
    setShowTypeForm(false);
  }
  function confirmDeleteType() {
    setLeaveTypes(prev => prev.filter(t => t.id !== deletingType.id));
    setDeletingType(null);
  }

  function quotaFor(s, lt) {
    const custom = s.leaveQuotas?.[lt.id];
    return custom != null ? custom : lt.defaultQuotaDays;
  }
  function usedFor(s, lt) {
    return daysOff.filter(d => d.staffId === s.id && d.leaveType === lt.id && d.date.slice(0, 4) === String(currentYear)).length;
  }
  function openEditQuotas(s) {
    const quotas = {};
    leaveTypes.forEach(lt => { quotas[lt.id] = String(quotaFor(s, lt)); });
    setEditingQuotas({ staffId: s.id, staffName: s.name, quotas, pin: "", error: "" });
  }
  function setEditingQuotaValue(ltId, value) {
    setEditingQuotas(prev => ({ ...prev, quotas: { ...prev.quotas, [ltId]: value }, error: "" }));
  }
  function saveEditedQuotas() {
    const manager = (staff || []).find(s => s.pin === editingQuotas.pin && s.active);
    const isOwner = isOwnerPin(ownerProfile, editingQuotas.pin);
    if (!manager && !isOwner) {
      setEditingQuotas(prev => ({ ...prev, error: "PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่" }));
      return;
    }
    const newQuotas = {};
    Object.entries(editingQuotas.quotas).forEach(([ltId, val]) => { newQuotas[ltId] = Number(val) || 0; });
    setStaff(prev => prev.map(s => s.id === editingQuotas.staffId ? { ...s, leaveQuotas: newQuotas } : s));
    setEditingQuotas(null);
  }

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="กำหนดสิทธิ์วันลา" subtitle="กำหนดสิทธิ์วันลาป่วย ลากิจ ลาพักร้อน ให้พนักงานแต่ละคน"
        right={<Btn onClick={openAddType}><Plus size={14} /> เพิ่มประเภทวันลา</Btn>} />

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">ประเภทวันลา</div>
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 mb-6">
        {leaveTypes.map(lt => (
          <Card key={lt.id} className="p-4">
            <div className="flex items-start justify-between mb-1">
              <div className="font-medium text-stone-800 text-sm">{lt.name}</div>
              <div className="flex items-center gap-2 flex-shrink-0">
                <button onClick={() => openEditType(lt)} className="text-stone-300 hover:text-amber-700"><Pencil size={14} /></button>
                <button onClick={() => setDeletingType(lt)} className="text-stone-300 hover:text-rose-500"><Trash2 size={14} /></button>
              </div>
            </div>
            <div className="text-xs text-stone-400">สิทธิ์เริ่มต้น {lt.defaultQuotaDays} วัน/ปี</div>
          </Card>
        ))}
        {leaveTypes.length === 0 && (
          <div className="col-span-full text-sm text-stone-400 text-center py-8 border border-dashed border-stone-300 rounded-lg">ยังไม่มีประเภทวันลา</div>
        )}
      </div>

      <div className="text-xs font-semibold tracking-wide text-stone-400 uppercase mb-2">สิทธิ์วันลาคงเหลือรายบุคคล (ปี {currentYear + 543})</div>
      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">พนักงาน</th>
                {leaveTypes.map(lt => <th key={lt.id} className="px-4 py-3 font-medium">{lt.name}</th>)}
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {staff.map(s => (
                <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 font-medium text-stone-800 align-top">{s.name}</td>
                  {leaveTypes.map(lt => {
                    const quota = quotaFor(s, lt);
                    const used = usedFor(s, lt);
                    const remaining = quota - used;
                    return (
                      <td key={lt.id} className="px-4 py-3 align-top">
                        <div className="text-sm text-stone-700">{quota} วัน/ปี</div>
                        <div className="text-xs text-stone-400">ใช้ไป {used} วัน</div>
                        <div className={`text-xs font-medium ${remaining < 0 ? "text-rose-600" : "text-emerald-600"}`}>เหลือ {remaining} วัน</div>
                      </td>
                    );
                  })}
                  <td className="px-4 py-3 align-top">
                    <button onClick={() => openEditQuotas(s)} className="text-xs text-stone-400 hover:text-amber-700 flex items-center gap-1"><Pencil size={12} /> แก้ไข</button>
                  </td>
                </tr>
              ))}
              {staff.length === 0 && (
                <tr><td colSpan={leaveTypes.length + 2} className="px-4 py-10 text-center text-stone-400">ยังไม่มีพนักงาน</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-3">
        "ใช้ไป" คำนวณจากจำนวนวันที่ถูกกำหนดในหน้า "กำหนดวันหยุด" ที่ระบุประเภทวันลาตรงกัน ภายในปีปัจจุบัน — ถ้าไม่ได้กำหนดจำนวนสิทธิ์เอง ระบบจะใช้ค่าเริ่มต้นของประเภทวันลานั้น
      </p>

      {/* Add / edit leave type popup */}
      {showTypeForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowTypeForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{typeForm.id ? "แก้ไขประเภทวันลา" : "เพิ่มประเภทวันลา"}</div>
              <button onClick={() => setShowTypeForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อประเภทวันลา"><input className={inputCls} value={typeForm.name} onChange={e => setTypeForm(f => ({ ...f, name: e.target.value }))} placeholder="เช่น ลาบวช" /></Field>
              <Field label="สิทธิ์เริ่มต้น (วัน/ปี)"><input type="number" min={0} className={inputCls} value={typeForm.defaultQuotaDays} onChange={e => setTypeForm(f => ({ ...f, defaultQuotaDays: e.target.value }))} /></Field>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submitType}>{typeForm.id ? "บันทึกการแก้ไข" : "เพิ่มประเภทวันลา"}</Btn>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingType && (
        <ConfirmDeletePin
          message={`ลบ "${deletingType.name}" ใช่ไหม?`}
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingType(null)}
          onConfirm={confirmDeleteType}
          logActivity={logActivity} activityLabel={`ลบประเภทวันลา ${deletingType.name}`} activityCategory="พนักงาน"
        />
      )}

      {/* Edit quotas popup (requires PIN) */}
      {editingQuotas && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setEditingQuotas(null)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">แก้ไขสิทธิ์วันลา — {editingQuotas.staffName}</div>
              <button onClick={() => setEditingQuotas(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3 mb-4">
              {leaveTypes.map(lt => (
                <Field key={lt.id} label={`${lt.name} (วัน/ปี)`}>
                  <input type="number" min={0} className={inputCls} value={editingQuotas.quotas[lt.id] ?? ""} onChange={e => setEditingQuotaValue(lt.id, e.target.value)} />
                </Field>
              ))}
            </div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} className={inputCls}
                value={editingQuotas.pin} onChange={e => setEditingQuotas(prev => ({ ...prev, pin: e.target.value.replace(/\D/g, "").slice(0, 6), error: "" }))}
                placeholder="••••••" />
            </Field>
            {editingQuotas.error && <div className="text-xs text-rose-500 mt-1.5">{editingQuotas.error}</div>}
            <Btn className="w-full justify-center mt-4" disabled={editingQuotas.pin.length !== 6} onClick={saveEditedQuotas}>บันทึก</Btn>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: ฝ่ายบุคคล — จัดทำเงินเดือน
   ========================================================================= */

function PayrollPage({ staff, positions, attendance, daysOff, workSchedules, salesInputs, setSalesInputs, storeInfo, expenses, setExpenses, ownerProfile, currentBranchId, branches }) {
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [payslipStaff, setPayslipStaff] = useState(null);
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  const [ssRate, setSsRate] = useState(5); // % ของเงินเดือนพื้นฐาน
  const [ssCap, setSsCap] = useState(() => socialSecurityCapForYear(new Date().getFullYear() + 543));
  // Keep the cap in step with the government's phased schedule whenever the
  // payroll month (and therefore its year) changes — still overridable by hand.
  useEffect(() => {
    const buddhistYear = Number(monthFilter.slice(0, 4)) + 543;
    setSsCap(socialSecurityCapForYear(buddhistYear));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [monthFilter]);
  const [extraIncome, setExtraIncome] = useState([]); // [{id, label, amount}]
  const [extraDeductions, setExtraDeductions] = useState([]);
  const [confirmPay, setConfirmPay] = useState(null); // { pin, error } | null
  const [paidConfirmation, setPaidConfirmation] = useState(null); // expenseNumber once confirmed

  function openPayslip(s) {
    setPayslipStaff(s);
    setExtraIncome([]);
    setExtraDeductions([]);
    setConfirmPay(null);
    setPaidConfirmation(null);
  }
  function addExtraRow(setter) {
    setter(prev => [...prev, { id: "x" + Date.now() + Math.random().toString(36).slice(2, 5), label: "", amount: "" }]);
  }
  function updateExtraRow(setter, id, patch) {
    setter(prev => prev.map(r => r.id === id ? { ...r, ...patch } : r));
  }
  function removeExtraRow(setter, id) {
    setter(prev => prev.filter(r => r.id !== id));
  }

  function otMinutesInMonth(staffId) {
    const schedule = workSchedules.find(s => s.id === staff.find(x => x.id === staffId)?.scheduleId);
    if (!schedule) return 0;
    return attendance
      .filter(a => a.staffId === staffId && a.clockOut && a.date.slice(0, 7) === monthFilter)
      .reduce((sum, a) => sum + Math.max(0, minutesBetween(schedule.endTime, a.clockOut)), 0);
  }
  function hadLateInMonth(staffId) {
    const s = staff.find(x => x.id === staffId);
    const schedule = workSchedules.find(x => x.id === s?.scheduleId);
    if (!schedule) return false;
    const graceLimit = minutesBetween("00:00", schedule.startTime) + (schedule.graceMinutes || 0);
    return attendance.some(a => a.staffId === staffId && a.clockOut && a.date.slice(0, 7) === monthFilter && minutesBetween("00:00", a.clockIn) > graceLimit);
  }
  function hadLeaveInMonth(staffId) {
    return daysOff.some(d => d.staffId === staffId && d.date.slice(0, 7) === monthFilter);
  }
  function positionName(staffId) {
    const s = staff.find(x => x.id === staffId);
    return positions.find(p => p.id === s?.positionId)?.name || "-";
  }
  function salesKey(staffId) { return `${staffId}-${monthFilter}`; }
  function getSales(staffId) { return salesInputs[salesKey(staffId)] || "0"; }
  function setSales(staffId, value) {
    setSalesInputs(prev => ({ ...prev, [salesKey(staffId)]: value }));
  }

  function computePayroll(s) {
    const c = s.compensation || {};
    const base = Number(c.baseSalary) || 0;
    const posAllow = Number(c.positionAllowance) || 0;
    const travelAllow = Number(c.travelAllowance) || 0;
    const fuelAllow = Number(c.fuelAllowance) || 0;

    const sales = Number(getSales(s.id)) || 0;
    const minSales = Number(c.commission?.minSales) || 0;
    let commission = 0;
    if (c.commission && sales > minSales) {
      commission = c.commission.type === "percent"
        ? sales * ((Number(c.commission.value) || 0) / 100)
        : (Number(c.commission.value) || 0);
    }

    const otMinutes = otMinutesInMonth(s.id);
    const otHours = otMinutes / 60;
    const hourlyRate = base > 0 ? base / 30 / 8 : 0;
    const otMultiplier = Number(c.otMultiplier) || 1;
    const otPay = hourlyRate * otMultiplier * otHours;

    const conditions = c.diligenceBonus?.conditions || [];
    const passesLate = !conditions.includes("noLate") || !hadLateInMonth(s.id);
    const passesLeave = !conditions.includes("noLeave") || !hadLeaveInMonth(s.id);
    // "noAbsent" can't be verified from current data (no explicit absence tracking), so it's assumed satisfied.
    const diligenceBonus = (passesLate && passesLeave) ? (Number(c.diligenceBonus?.amount) || 0) : 0;

    const total = base + posAllow + travelAllow + fuelAllow + commission + otPay + diligenceBonus;

    let socialSecurity = 0;
    if (c.socialSecurityEnabled) {
      socialSecurity = c.socialSecurityAmount !== "" && c.socialSecurityAmount != null
        ? Number(c.socialSecurityAmount) || 0
        : Math.min(ssCap, base * (ssRate / 100)); // adjustable rate/cap (defaults to standard Thai 5% / 750 THB)
    }
    const netPay = total - socialSecurity;

    return { base, posAllow, travelAllow, fuelAllow, sales, commission, otHours, otPay, diligenceBonus, total, socialSecurity, netPay };
  }

  const activeStaff = staff.filter(s => s.active && (!effectiveBranchId || !s.branchIds?.length || s.branchIds.includes(effectiveBranchId)));
  const grandTotal = activeStaff.reduce((sum, s) => sum + computePayroll(s).netPay, 0);

  const exportRows = activeStaff.map(s => {
    const p = computePayroll(s);
    return {
      "พนักงาน": s.name, "ตำแหน่ง": positionName(s.id),
      "เงินเดือนพื้นฐาน": p.base, "ค่าตำแหน่ง": p.posAllow, "ค่าเดินทาง": p.travelAllow, "ค่าน้ำมัน": p.fuelAllow,
      "ยอดขาย": p.sales, "คอมมิชชั่น": Math.round(p.commission * 100) / 100,
      "ชม.OT": Math.round(p.otHours * 100) / 100, "ค่า OT": Math.round(p.otPay * 100) / 100,
      "เบี้ยขยัน": p.diligenceBonus, "รวมก่อนหัก": Math.round(p.total * 100) / 100,
      "หักประกันสังคม": Math.round(p.socialSecurity * 100) / 100, "ยอดจ่ายสุทธิ": Math.round(p.netPay * 100) / 100,
    };
  });

  return (
    <div>
      <PageHeader eyebrow="ฝ่ายบุคคล" title="จัดทำเงินเดือน" subtitle="คำนวณเงินเดือนจากอัตราค่าตอบแทนของพนักงานแต่ละคน"
        right={!currentBranchId && branches && branches.length > 0 ? (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        ) : null} />

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`เงินเดือน-${monthFilter}`} sheetName="Payroll" />
        </div>
      </div>

      <Card className="p-4 mb-5">
        <div className="text-sm font-semibold text-stone-700 mb-2 flex items-center gap-1.5"><ShieldCheck size={14} className="text-amber-600" /> อัตราหักประกันสังคม (ใช้กับพนักงานที่ไม่ได้ระบุจำนวนเองในโปรไฟล์)</div>
        <div className="flex flex-wrap items-center gap-4">
          <label className="flex items-center gap-2 text-sm text-stone-600">
            อัตรา
            <input type="number" min={0} step="0.1" className="w-20 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={ssRate} onChange={e => setSsRate(Number(e.target.value) || 0)} />
            %
          </label>
          <label className="flex items-center gap-2 text-sm text-stone-600">
            เพดานสูงสุด
            <input type="number" min={0} className="w-24 rounded-md border border-stone-300 px-2 py-1.5 text-sm text-right" value={ssCap} onChange={e => setSsCap(Number(e.target.value) || 0)} />
            บาท/เดือน
          </label>
        </div>
        <p className="text-[11px] text-stone-400 mt-2">
          เพดานตั้งตามตารางที่ประกาศไว้อัตโนมัติทุกครั้งที่เปลี่ยนเดือน: <strong>ปี 2569-2571</strong> เพดาน 875 บาท (ฐานสูงสุด 17,500 บาท) · <strong>ปี 2572-2574</strong> เพดาน 1,000 บาท (ฐานสูงสุด 20,000 บาท) · <strong>ปี 2575 เป็นต้นไป</strong> เพดาน 1,150 บาท (ฐานสูงสุด 23,000 บาท) — แก้ไขเองเพิ่มเติมได้ถ้าต้องการ
        </p>
      </Card>

      <Card className="p-4 mb-5 max-w-xs">
        <div className="text-xs text-stone-400">ยอดจ่ายสุทธิรวมทั้งหมดเดือนนี้</div>
        <div className="text-2xl font-serif text-stone-900 mt-1">฿{fmtMoney(grandTotal)}</div>
      </Card>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">พนักงาน</th>
                <th className="px-4 py-3 font-medium">เงินเดือนพื้นฐาน</th>
                <th className="px-4 py-3 font-medium">ค่าตำแหน่ง</th>
                <th className="px-4 py-3 font-medium">ค่าเดินทาง</th>
                <th className="px-4 py-3 font-medium">ค่าน้ำมัน</th>
                <th className="px-4 py-3 font-medium">ยอดขาย</th>
                <th className="px-4 py-3 font-medium">คอมมิชชั่น</th>
                <th className="px-4 py-3 font-medium">ชม. OT</th>
                <th className="px-4 py-3 font-medium">ค่า OT</th>
                <th className="px-4 py-3 font-medium">เบี้ยขยัน</th>
                <th className="px-4 py-3 font-medium">หัก ประกันสังคม</th>
                <th className="px-4 py-3 font-medium">ยอดจ่ายสุทธิ</th>
                <th className="px-4 py-3 font-medium">สลิป</th>
              </tr>
            </thead>
            <tbody>
              {activeStaff.map(s => {
                const p = computePayroll(s);
                return (
                  <tr key={s.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 align-top">
                      <div className="font-medium text-stone-800">{s.name}</div>
                      <div className="text-xs text-stone-400">{positionName(s.id)}</div>
                      {!effectiveBranchId && s.branchIds?.length > 0 && (
                        <div className="text-xs text-stone-400">{s.branchIds.map(id => branches?.find(b => b.id === id)?.name).filter(Boolean).join(", ")}</div>
                      )}
                    </td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.base)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.posAllow)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.travelAllow)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.fuelAllow)}</td>
                    <td className="px-4 py-3 align-top">
                      <input type="number" min={0} className="w-24 rounded-md border border-stone-300 px-2 py-1 text-sm text-right" value={getSales(s.id)} onChange={e => setSales(s.id, e.target.value)} />
                    </td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.commission)}</td>
                    <td className="px-4 py-3 font-mono text-stone-500 align-top">{Math.round(p.otHours * 100) / 100}</td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.otPay)}</td>
                    <td className="px-4 py-3 font-mono text-stone-700 align-top">{fmtMoney(p.diligenceBonus)}</td>
                    <td className="px-4 py-3 font-mono text-rose-600 align-top">{p.socialSecurity > 0 ? `-${fmtMoney(p.socialSecurity)}` : "-"}</td>
                    <td className="px-4 py-3 font-mono font-semibold text-stone-900 align-top">฿{fmtMoney(p.netPay)}</td>
                    <td className="px-4 py-3 align-top">
                      <button onClick={() => openPayslip(s)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1 whitespace-nowrap">
                        <FileText size={12} /> ดูสลิป
                      </button>
                    </td>
                  </tr>
                );
              })}
              {activeStaff.length === 0 && (
                <tr><td colSpan={13} className="px-4 py-10 text-center text-stone-400">ไม่มีพนักงานที่ใช้งานอยู่</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>

      <div className="text-xs text-stone-400 mt-4 space-y-1">
        <p>• <strong>ยอดขาย</strong> ต้องกรอกเองต่อคนต่อเดือน (ระบบยังไม่ได้ผูกยอดขายรายบิลเข้ากับพนักงานที่ขายโดยตรง) ใช้เทียบกับเป้ายอดขายขั้นต่ำเพื่อคิดคอมมิชชั่น</p>
        <p>• <strong>ค่า OT</strong> คำนวณจากชั่วโมงที่ออกงานเกินตารางเวลาที่กำหนด × อัตรา OT ที่ตั้งไว้ โดยประมาณค่าแรงต่อชั่วโมงจาก เงินเดือนพื้นฐาน ÷ 30 วัน ÷ 8 ชั่วโมง</p>
        <p>• <strong>เบี้ยขยัน</strong> เช็คเงื่อนไข "ไม่มาสาย" และ "ไม่ลา" จากข้อมูลจริงในเดือนนั้น ส่วนเงื่อนไข "ไม่ขาดงาน" ยังตรวจสอบอัตโนมัติไม่ได้ (ระบบไม่มีข้อมูลวันที่ควรมาทำงานแต่ขาด) จึงถือว่าผ่านเงื่อนไขนี้เสมอ</p>
        <p>• <strong>หักประกันสังคม</strong> เปิด/ปิดและกำหนดจำนวนเฉพาะคนได้ที่หน้า "รายชื่อพนักงาน" → แก้ไขพนักงาน → ส่วนค่าตอบแทน ถ้าไม่ระบุจำนวนเอง ระบบจะคำนวณจาก**อัตรา/เพดานที่ปรับได้ด้านบน**ของหน้านี้ (ค่าเริ่มต้น 5% เพดานปรับตามปีอัตโนมัติตามตารางที่ประกาศไว้)</p>
      </div>

      {/* Payslip modal */}
      {payslipStaff && (() => {
        const p = computePayroll(payslipStaff);
        const [y, m] = monthFilter.split("-");
        const thaiMonthName = ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"][Number(m) - 1];
        const extraIncomeTotal = extraIncome.reduce((sum, r) => sum + (Number(r.amount) || 0), 0);
        const extraDeductionTotal = extraDeductions.reduce((sum, r) => sum + (Number(r.amount) || 0), 0);
        const finalNetPay = p.netPay + extraIncomeTotal - extraDeductionTotal;

        const daysInMonth = new Date(Number(y), Number(m), 0).getDate();
        const payDate = `${String(daysInMonth).padStart(2, "0")}/${m}/${Number(y) + 543}`;
        const periodFrom = `01/${m}/${Number(y) + 543}`;
        const periodTo = `${String(daysInMonth).padStart(2, "0")}/${m}/${Number(y) + 543}`;
        const leaveCount = daysOff.filter(d => d.staffId === payslipStaff.id && d.date.slice(0, 7) === monthFilter).length;
        const schedule = workSchedules.find(w => w.id === payslipStaff.scheduleId);
        const lateCount = schedule ? attendance.filter(a => {
          if (a.staffId !== payslipStaff.id || a.date.slice(0, 7) !== monthFilter || !a.clockOut) return false;
          const graceLimit = minutesBetween("00:00", schedule.startTime) + (schedule.graceMinutes || 0);
          return minutesBetween("00:00", a.clockIn) > graceLimit;
        }).length : 0;

        const incomeRows = [
          ["เงินเดือน", p.base], ["ค่าตำแหน่ง", p.posAllow], ["ค่าเดินทาง", p.travelAllow], ["ค่าน้ำมัน", p.fuelAllow],
          ["คอมมิชชั่น", p.commission], [`ค่าล่วงเวลา (${Math.round(p.otHours * 100) / 100} ชม.)`, p.otPay], ["เบี้ยขยัน", p.diligenceBonus],
          ...extraIncome.filter(r => r.label && Number(r.amount)).map(r => [r.label, Number(r.amount)]),
        ].filter(([, amt]) => amt > 0 || true);
        const deductionRows = [
          ["ประกันสังคม", p.socialSecurity],
          ...extraDeductions.filter(r => r.label && Number(r.amount)).map(r => [r.label, Number(r.amount)]),
        ];
        const totalIncome = p.total + extraIncomeTotal;
        const totalDeductions = p.socialSecurity + extraDeductionTotal;

        function openConfirm() {
          setConfirmPay({ pin: "", error: "" });
        }
        function downloadPayslip() {
          const rowsHtml = incomeRows.map(([label, amt]) => `<tr><td style="padding:3px 6px;">${label}</td><td style="padding:3px 6px;text-align:right;">${fmtMoney(amt)}</td></tr>`).join("");
          const deductRowsHtml = deductionRows.map(([label, amt]) => `<tr><td style="padding:3px 6px;">${label}</td><td style="padding:3px 6px;text-align:right;">${fmtMoney(amt)}</td></tr>`).join("");
          const html = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>สลิปเงินเดือน ${payslipStaff.name}</title></head>
<body style="font-family:'Sarabun',sans-serif;color:#1c1917;padding:24px;">
<div style="max-width:800px;margin:0 auto;border:3px double #2563eb;padding:16px 24px;">
  <div style="display:flex;justify-content:space-between;align-items:flex-start;">
    <div style="font-size:13px;color:#78716c;">${storeInfo?.name || ""}</div>
    <div style="font-size:24px;font-weight:700;color:#c2410c;text-align:center;flex:1;">ใบรับเงินเดือน (Pay Slip)</div>
    <table style="font-size:12px;text-align:left;">
      <tr><td style="color:#78716c;padding-right:8px;">รหัสพนักงาน</td><td>${payslipStaff.id}</td></tr>
      <tr><td style="color:#78716c;padding-right:8px;">ชื่อพนักงาน</td><td>${payslipStaff.name}</td></tr>
      <tr><td style="color:#78716c;padding-right:8px;">ตำแหน่ง</td><td>${positionName(payslipStaff.id)}</td></tr>
    </table>
  </div>
  <div style="display:flex;justify-content:space-between;border-top:1px solid #2563eb;border-bottom:1px solid #2563eb;padding:6px 0;margin:10px 0;font-size:13px;">
    <span><strong>วันที่จ่าย</strong> ${payDate}</span>
    <span><strong>งวดวันที่</strong> ${periodFrom} ถึง ${periodTo}</span>
  </div>
  <div style="display:flex;justify-content:space-between;font-size:12px;color:#78716c;margin-bottom:12px;">
    <span>จำนวนวันที่ลา ${leaveCount} วัน</span>
    <span>จำนวนครั้งที่มาสาย ${lateCount} ครั้ง</span>
  </div>
  <div style="display:flex;gap:24px;">
    <div style="flex:1;">
      <div style="color:#c2410c;font-weight:600;border-bottom:2px solid #c2410c;padding-bottom:4px;margin-bottom:6px;">รายได้</div>
      <table style="width:100%;border-collapse:collapse;font-size:13px;">${rowsHtml}
        <tr style="border-top:1px solid #78716c;font-weight:700;"><td style="padding:6px;">รวมรายได้</td><td style="padding:6px;text-align:right;">${fmtMoney(totalIncome)}</td></tr>
      </table>
    </div>
    <div style="flex:1;">
      <div style="color:#c2410c;font-weight:600;border-bottom:2px solid #c2410c;padding-bottom:4px;margin-bottom:6px;">รายการหัก</div>
      <table style="width:100%;border-collapse:collapse;font-size:13px;">${deductRowsHtml}
        <tr style="border-top:1px solid #78716c;font-weight:700;"><td style="padding:6px;">รวมรายการหัก</td><td style="padding:6px;text-align:right;">${fmtMoney(totalDeductions)}</td></tr>
      </table>
    </div>
  </div>
  <div style="display:flex;justify-content:space-between;align-items:flex-end;margin-top:12px;">
    <div style="font-size:12px;color:#57534e;">
      ${(payslipStaff.bankInfo?.bankName || payslipStaff.bankInfo?.accountNumber) ? `
        <div><strong>ธนาคาร:</strong> ${payslipStaff.bankInfo.bankName || "-"}</div>
        <div><strong>เลขที่บัญชี:</strong> ${payslipStaff.bankInfo.accountNumber || "-"}</div>
        ${payslipStaff.bankInfo.accountName ? `<div><strong>ชื่อบัญชี:</strong> ${payslipStaff.bankInfo.accountName}</div>` : ""}
      ` : `<span style="color:#d6d3d1;">ยังไม่ได้บันทึกบัญชีธนาคาร</span>`}
    </div>
    <div style="text-align:right;">
      <div style="font-size:13px;color:#78716c;">รายได้สุทธิ</div>
      <div style="font-size:22px;font-weight:700;color:#c2410c;">${fmtMoney(finalNetPay)}</div>
    </div>
  </div>
  <div style="margin-top:32px;text-align:center;font-size:12px;">
    ลงชื่อผู้รับเงิน.................................................. วันที่รับเงิน ____/____/____<br/>
    ( &nbsp;${payslipStaff.name}&nbsp; )
  </div>
</div>
</body></html>`;
          const blob = new Blob([html], { type: "text/html;charset=utf-8;" });
          const url = URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.href = url;
          a.download = `สลิปเงินเดือน-${payslipStaff.name}-${monthFilter}.html`;
          document.body.appendChild(a);
          a.click();
          a.remove();
          URL.revokeObjectURL(url);
        }
        function confirmAndCreateExpenseBill() {
          const manager = (staff || []).find(s2 => s2.pin === confirmPay.pin && s2.active);
          const isOwner = isOwnerPin(ownerProfile, confirmPay.pin);
          if (!manager && !isOwner) {
            setConfirmPay(prev => ({ ...prev, error: "PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่" }));
            return;
          }
          const expenseNumber = nextExpenseNumber(expenses);
          const lines = [
            { id: "exl-net", description: `เงินเดือนสุทธิ - ${payslipStaff.name} (เดือน${thaiMonthName} ${Number(y) + 543})`, category: "เงินเดือนพนักงาน", qty: "1", unit: "เดือน", unitPrice: String(finalNetPay) },
          ];
          const noteParts = [`รวมรายได้ก่อนหัก ฿${fmtMoney(totalIncome)}`];
          if (p.socialSecurity > 0) noteParts.push(`หักประกันสังคม ฿${fmtMoney(p.socialSecurity)}`);
          extraIncome.filter(r => r.label && Number(r.amount)).forEach(r => noteParts.push(`รายได้อื่นๆ: ${r.label} ฿${fmtMoney(r.amount)}`));
          extraDeductions.filter(r => r.label && Number(r.amount)).forEach(r => noteParts.push(`รายการหักอื่นๆ: ${r.label} ฿${fmtMoney(r.amount)}`));
          setExpenses(prev => [...prev, {
            id: "exp" + Date.now(), expenseNumber,
            branchId: effectiveBranchId || payslipStaff.branchIds?.[0] || null,
            vendorId: "", address: "", date: new Date().toISOString().slice(0, 10), creditDays: "0",
            reference: "", reference2: `จ่ายเงินเดือนพนักงาน ${payslipStaff.name}`, priceMode: "excl",
            lines,
            discountPercent: "0", vatEnabled: false, vatRate: 7,
            note: noteParts.join(" · "),
            internalNote: "", paymentStatus: "pending", payment: null,
          }]);
          setPaidConfirmation(expenseNumber);
          setConfirmPay(null);
        }

        return (
          <div className="fixed inset-0 bg-stone-900/40 z-50 overflow-y-auto p-4" onClick={() => setPayslipStaff(null)}>
            <div className="min-h-full flex items-start justify-center py-8">
            <div className="bg-white rounded-xl w-full max-w-3xl p-5" onClick={e => e.stopPropagation()}>
              <div className="flex items-center justify-end gap-2 mb-3">
                <Btn variant="ghost" onClick={() => printA4Page()}><Printer size={14} /> พิมพ์</Btn>
                <Btn variant="ghost" onClick={downloadPayslip}><Download size={14} /> ดาวน์โหลด</Btn>
                <button onClick={() => setPayslipStaff(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
              </div>

              {/* Bordered pay-slip document */}
              <div className="border-4 border-double border-blue-600 p-5">
                <div className="flex items-start justify-between gap-4 mb-2">
                  <div className="text-xs text-stone-400 flex-1">{storeInfo?.name}</div>
                  <div className="text-xl sm:text-2xl font-bold text-orange-700 text-center flex-1">ใบรับเงินเดือน (Pay Slip)</div>
                  <table className="text-xs flex-1 ml-auto">
                    <tbody>
                      <tr><td className="text-stone-400 pr-2">รหัสพนักงาน</td><td className="font-medium">{payslipStaff.id}</td></tr>
                      <tr><td className="text-stone-400 pr-2">ชื่อพนักงาน</td><td className="font-medium">{payslipStaff.name}</td></tr>
                      <tr><td className="text-stone-400 pr-2">ตำแหน่ง</td><td className="font-medium">{positionName(payslipStaff.id)}</td></tr>
                    </tbody>
                  </table>
                </div>

                <div className="flex flex-wrap justify-between text-sm border-y border-blue-600 py-1.5 my-2 gap-2">
                  <span><strong>วันที่จ่าย</strong> {payDate}</span>
                  <span><strong>งวดวันที่</strong> {periodFrom} ถึง {periodTo}</span>
                </div>
                <div className="flex flex-wrap justify-between text-xs text-stone-400 mb-3 gap-2">
                  <span>จำนวนวันที่ลา {leaveCount} วัน</span>
                  <span>จำนวนครั้งที่มาสาย {lateCount} ครั้ง</span>
                </div>

                <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
                  <div>
                    <div className="text-orange-700 font-semibold border-b-2 border-orange-700 pb-1 mb-1.5">รายได้</div>
                    <div className="space-y-0.5 text-sm">
                      {incomeRows.map(([label, amt], i) => (
                        <div key={i} className="flex justify-between"><span className="text-stone-600">{label}</span><span className="font-mono">{fmtMoney(amt)}</span></div>
                      ))}
                      {extraIncome.map(r => (
                        <div key={r.id} className="flex items-center gap-2">
                          <input className="flex-1 min-w-0 rounded-md border border-stone-300 px-2 py-1 text-xs" placeholder="ระบุรายได้อื่นๆ" value={r.label} onChange={e => updateExtraRow(setExtraIncome, r.id, { label: e.target.value })} />
                          <input type="number" className="w-20 flex-shrink-0 rounded-md border border-stone-300 px-2 py-1 text-xs text-right" placeholder="0.00" value={r.amount} onChange={e => updateExtraRow(setExtraIncome, r.id, { amount: e.target.value })} />
                          <button onClick={() => removeExtraRow(setExtraIncome, r.id)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={13} /></button>
                        </div>
                      ))}
                      <button onClick={() => addExtraRow(setExtraIncome)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1 pt-1">
                        <Plus size={11} /> รายได้อื่นๆ
                      </button>
                      <div className="flex justify-between font-bold border-t border-stone-400 pt-1.5 mt-1.5"><span>รวมรายได้</span><span className="font-mono">{fmtMoney(totalIncome)}</span></div>
                    </div>
                  </div>

                  <div>
                    <div className="text-orange-700 font-semibold border-b-2 border-orange-700 pb-1 mb-1.5">รายการหัก</div>
                    <div className="space-y-0.5 text-sm">
                      {deductionRows.map(([label, amt], i) => (
                        <div key={i} className="flex justify-between"><span className="text-stone-600">{label}</span><span className="font-mono">{fmtMoney(amt)}</span></div>
                      ))}
                      {extraDeductions.map(r => (
                        <div key={r.id} className="flex items-center gap-2">
                          <input className="flex-1 min-w-0 rounded-md border border-stone-300 px-2 py-1 text-xs" placeholder="ระบุรายการหักอื่นๆ" value={r.label} onChange={e => updateExtraRow(setExtraDeductions, r.id, { label: e.target.value })} />
                          <input type="number" className="w-20 flex-shrink-0 rounded-md border border-stone-300 px-2 py-1 text-xs text-right" placeholder="0.00" value={r.amount} onChange={e => updateExtraRow(setExtraDeductions, r.id, { amount: e.target.value })} />
                          <button onClick={() => removeExtraRow(setExtraDeductions, r.id)} className="text-stone-300 hover:text-rose-500 flex-shrink-0"><X size={13} /></button>
                        </div>
                      ))}
                      <button onClick={() => addExtraRow(setExtraDeductions)} className="text-xs text-sky-700 hover:text-sky-900 flex items-center gap-1 pt-1">
                        <Plus size={11} /> รายการหักอื่นๆ
                      </button>
                      <div className="flex justify-between font-bold border-t border-stone-400 pt-1.5 mt-1.5"><span>รวมรายการหัก</span><span className="font-mono">{fmtMoney(totalDeductions)}</span></div>
                    </div>
                  </div>
                </div>

                <div className="flex flex-wrap justify-between items-end mt-4 gap-3">
                  <div className="text-xs text-stone-500">
                    {(payslipStaff.bankInfo?.bankName || payslipStaff.bankInfo?.accountNumber) ? (
                      <>
                        <div><strong>ธนาคาร:</strong> {payslipStaff.bankInfo.bankName || "-"}</div>
                        <div><strong>เลขที่บัญชี:</strong> {payslipStaff.bankInfo.accountNumber || "-"}</div>
                        {payslipStaff.bankInfo.accountName && <div><strong>ชื่อบัญชี:</strong> {payslipStaff.bankInfo.accountName}</div>}
                      </>
                    ) : (
                      <span className="text-stone-300">ยังไม่ได้บันทึกบัญชีธนาคาร</span>
                    )}
                  </div>
                  <div className="text-right">
                    <div className="text-xs text-stone-400">รายได้สุทธิ</div>
                    <div className="text-2xl font-bold text-orange-700">฿{fmtMoney(finalNetPay)}</div>
                  </div>
                </div>

                <div className="text-center text-xs text-stone-500 mt-8 pt-4 border-t border-stone-200">
                  ลงชื่อผู้รับเงิน.................................................. วันที่รับเงิน ____/____/____<br />
                  ( {payslipStaff.name} )
                </div>
              </div>

              {paidConfirmation ? (
                <div className="mt-4 text-sm text-emerald-700 bg-emerald-50 rounded-lg px-3 py-2.5 flex items-center gap-2">
                  <CheckCircle2 size={15} /> สร้างบิลค่าใช้จ่ายเงินเดือนแล้ว ({paidConfirmation}) — ไปดำเนินการชำระต่อได้ที่หน้า "ค่าใช้จ่าย"
                </div>
              ) : (
                <Btn className="w-full justify-center mt-4" onClick={openConfirm}><ShieldCheck size={14} /> ยืนยันจ่ายเงินเดือน</Btn>
              )}
            </div>
            </div>
          </div>
        );
      })()}

      {/* PIN confirmation before creating the payroll expense bill */}
      {confirmPay && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setConfirmPay(null)}>
          <div className="bg-white rounded-xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-stone-800 flex items-center gap-2"><ShieldCheck size={17} className="text-amber-600" /> ยืนยันจ่ายเงินเดือน</div>
              <button onClick={() => setConfirmPay(null)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="text-xs text-stone-500 mt-2 mb-4">ระบบจะสร้างบิลค่าใช้จ่ายเงินเดือนของ "{payslipStaff?.name}" ในหน้า "ค่าใช้จ่าย"</div>
            <Field label="PIN ผู้จัดการ หรือ เจ้าของร้าน (6 หลัก)">
              <input type="password" inputMode="numeric" maxLength={6} autoFocus className={inputCls}
                value={confirmPay.pin} onChange={e => setConfirmPay(prev => ({ ...prev, pin: e.target.value.replace(/\D/g, "").slice(0, 6), error: "" }))}
                placeholder="••••••" />
            </Field>
            {confirmPay.error && <div className="text-xs text-rose-500 mt-1.5">{confirmPay.error}</div>}
          </div>
        </div>
      )}

      {/* Hidden printable payslip */}
      {payslipStaff && (() => {
        const p = computePayroll(payslipStaff);
        const [y, m] = monthFilter.split("-");
        const thaiMonthName = ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"][Number(m) - 1];
        return (
          <div className="print-po">
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
              <div>
                <div style={{ fontSize: 20, fontWeight: 600 }}>สลิปเงินเดือน</div>
                <div style={{ fontSize: 13 }}>{storeInfo?.name || ""}</div>
              </div>
              <div style={{ textAlign: "right", fontSize: 13 }}>
                <div>{payslipStaff.name}</div>
                <div>{positionName(payslipStaff.id)}</div>
                <div>เดือน{thaiMonthName} {Number(y) + 543}</div>
              </div>
            </div>
            <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13, marginBottom: 16 }}>
              <tbody>
                <tr><td style={{ padding: "4px 0" }}>เงินเดือนพื้นฐาน</td><td style={{ textAlign: "right" }}>{fmtMoney(p.base)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>ค่าตำแหน่ง</td><td style={{ textAlign: "right" }}>{fmtMoney(p.posAllow)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>ค่าเดินทาง</td><td style={{ textAlign: "right" }}>{fmtMoney(p.travelAllow)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>ค่าน้ำมัน</td><td style={{ textAlign: "right" }}>{fmtMoney(p.fuelAllow)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>คอมมิชชั่น</td><td style={{ textAlign: "right" }}>{fmtMoney(p.commission)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>ค่าล่วงเวลา</td><td style={{ textAlign: "right" }}>{fmtMoney(p.otPay)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>เบี้ยขยัน</td><td style={{ textAlign: "right" }}>{fmtMoney(p.diligenceBonus)}</td></tr>
                <tr style={{ borderTop: "1px solid #333" }}><td style={{ padding: "6px 0", fontWeight: 600 }}>รวมรายได้</td><td style={{ textAlign: "right", fontWeight: 600 }}>{fmtMoney(p.total)}</td></tr>
                <tr><td style={{ padding: "4px 0" }}>หัก ประกันสังคม</td><td style={{ textAlign: "right" }}>-{fmtMoney(p.socialSecurity)}</td></tr>
              </tbody>
            </table>
            <div style={{ display: "flex", justifyContent: "space-between", paddingTop: 12, borderTop: "2px solid #333", fontWeight: 600, fontSize: 16 }}>
              <span>ยอดจ่ายสุทธิ</span><span>฿{fmtMoney(p.netPay)}</span>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

/* =========================================================================
   PAGE: การจัดการสต๊อก — บันทึกของเสีย
   ========================================================================= */

function emptyWasteForm() {
  return { id: null, date: new Date().toISOString().slice(0, 10), stockItemId: "", qty: "", reason: WASTE_REASONS[0], note: "" };
}

function WastePage({ wasteLog, setWasteLog, stockItems, setStockItems, currentBranchId, branches, staff, ownerProfile, logActivity }) {
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState(emptyWasteForm());
  const [deletingEntry, setDeletingEntry] = useState(null);
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  function branchNameFor(id) { return branches?.find(b => b.id === id)?.name; }

  function openAdd() {
    setForm({ ...emptyWasteForm(), stockItemId: stockItems[0]?.id || "", branchId: currentBranchId || null });
    setShowForm(true);
  }
  function openEdit(entry) {
    setForm({ ...entry, qty: String(entry.qty) });
    setShowForm(true);
  }
  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }

  function adjustStock(stockItemId, delta, branchId = currentBranchId) {
    adjustBranchStock(setStockItems, stockItemId, branchId, delta);
  }

  function submit() {
    if (!form.stockItemId || !Number(form.qty)) return;
    const payload = { ...form, qty: Number(form.qty) };
    if (form.id) {
      const old = wasteLog.find(w => w.id === form.id);
      if (old) {
        // Undo the old deduction (restore), then apply the new one — covers changes to item/qty/branch.
        adjustStock(old.stockItemId, old.qty, old.branchId);
      }
      adjustStock(payload.stockItemId, -payload.qty, payload.branchId);
      setWasteLog(prev => prev.map(w => w.id === form.id ? payload : w));
    } else {
      adjustStock(payload.stockItemId, -payload.qty, payload.branchId);
      setWasteLog(prev => [{ ...payload, id: "wl" + Date.now() }, ...prev]);
    }
    setShowForm(false);
  }
  function confirmDelete() {
    adjustStock(deletingEntry.stockItemId, deletingEntry.qty, deletingEntry.branchId); // restore the stock that was deducted
    setWasteLog(prev => prev.filter(w => w.id !== deletingEntry.id));
    setDeletingEntry(null);
  }

  function stockItemFor(id) { return stockItems.find(s => s.id === id); }
  function wasteCost(entry) {
    const item = stockItemFor(entry.stockItemId);
    return item ? entry.qty * item.costPerUnit : 0;
  }

  const filtered = wasteLog
    .filter(w => w.date.slice(0, 7) === monthFilter)
    .filter(w => !effectiveBranchId || !w.branchId || w.branchId === effectiveBranchId);
  const totalCostThisMonth = filtered.reduce((sum, w) => sum + wasteCost(w), 0);

  const exportRows = filtered.map(w => {
    const item = stockItemFor(w.stockItemId);
    return {
      "วันที่": fmtDate(w.date), "สาขา": branchNameFor(w.branchId) || "-", "สินค้า": item?.name || "-", "จำนวน": w.qty, "หน่วย": item?.unit || "-",
      "สาเหตุ": w.reason, "มูลค่าความเสียหาย": Math.round(wasteCost(w) * 100) / 100, "หมายเหตุ": w.note || "",
    };
  });

  return (
    <div>
      <PageHeader eyebrow="การจัดการสต๊อก" title="บันทึกของเสีย" subtitle="บันทึกวัตถุดิบที่เสียหาย ทำหก หรือหมดอายุ แยกจากยอดขายปกติ"
        right={<Btn onClick={openAdd}><Plus size={14} /> บันทึกของเสีย</Btn>} />

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        {!currentBranchId && branches && branches.length > 0 && (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        )}
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`บันทึกของเสีย-${monthFilter}`} sheetName="Waste" />
        </div>
      </div>

      <Card className="p-4 mb-5 max-w-xs">
        <div className="text-xs text-stone-400">มูลค่าของเสียรวมเดือนนี้</div>
        <div className="text-2xl font-serif text-rose-600 mt-1">฿{fmtMoney(totalCostThisMonth)}</div>
      </Card>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">วันที่</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา</th>}
                <th className="px-4 py-3 font-medium">สินค้า</th>
                <th className="px-4 py-3 font-medium">จำนวน</th>
                <th className="px-4 py-3 font-medium">สาเหตุ</th>
                <th className="px-4 py-3 font-medium">มูลค่าความเสียหาย</th>
                <th className="px-4 py-3 font-medium">หมายเหตุ</th>
                <th className="px-4 py-3 font-medium">จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {filtered.slice().reverse().map(w => {
                const item = stockItemFor(w.stockItemId);
                return (
                  <tr key={w.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                    <td className="px-4 py-3 text-stone-400">{fmtDate(w.date)}</td>
                    {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchNameFor(w.branchId) || "-"}</td>}
                    <td className="px-4 py-3 font-medium text-stone-800">{item?.name || "-"}</td>
                    <td className="px-4 py-3 font-mono text-stone-700">{w.qty} {item?.unit}</td>
                    <td className="px-4 py-3">
                      <span className="text-xs px-2 py-0.5 rounded border font-medium bg-rose-50 text-rose-700 border-rose-300">{w.reason}</span>
                    </td>
                    <td className="px-4 py-3 font-mono text-rose-600">฿{fmtMoney(wasteCost(w))}</td>
                    <td className="px-4 py-3 text-stone-500">{w.note || "-"}</td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-3">
                        <button onClick={() => openEdit(w)} className="text-stone-300 hover:text-amber-700"><Pencil size={15} /></button>
                        <button onClick={() => setDeletingEntry(w)} className="text-stone-300 hover:text-rose-500"><Trash2 size={15} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
              {filtered.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 7 : 8} className="px-4 py-10 text-center text-stone-400">ยังไม่มีบันทึกของเสียในเดือนนี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-3">
        บันทึกของเสียจะ**หักออกจากสต็อกทันที** แยกต่างหากจากการตัดสต็อกอัตโนมัติตอนขายอาหาร ช่วยให้เห็นภาพว่าของหายไปเพราะขายจริง หรือเพราะเสียหาย/ทำหก/หมดอายุ
      </p>

      {/* Add / edit waste entry popup */}
      {showForm && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowForm(false)}>
          <div className="bg-white rounded-xl w-full max-w-sm p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">{form.id ? "แก้ไขบันทึกของเสีย" : "บันทึกของเสีย"}</div>
              <button onClick={() => setShowForm(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="วันที่"><input type="date" className={inputCls} value={form.date} onChange={e => set({ date: e.target.value })} /></Field>
              {!currentBranchId && branches && branches.length > 0 && (
                <Field label="สาขา">
                  <select className={inputCls} value={form.branchId || ""} onChange={e => set({ branchId: e.target.value || null })}>
                    <option value="">ไม่ระบุ (ไม่ผูกสาขา)</option>
                    {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
                  </select>
                </Field>
              )}
              <Field label="สินค้า/วัตถุดิบ">
                <select className={inputCls} value={form.stockItemId} onChange={e => set({ stockItemId: e.target.value })}>
                  {stockItems.map(s => <option key={s.id} value={s.id}>{s.name} ({s.unit})</option>)}
                </select>
              </Field>
              <Field label="จำนวนที่เสีย"><input type="number" step="any" min={0} className={inputCls} value={form.qty} onChange={e => set({ qty: e.target.value })} /></Field>
              <Field label="สาเหตุ">
                <select className={inputCls} value={form.reason} onChange={e => set({ reason: e.target.value })}>
                  {WASTE_REASONS.map(r => <option key={r} value={r}>{r}</option>)}
                </select>
              </Field>
              <Field label="หมายเหตุ"><textarea rows={2} className={inputCls} value={form.note} onChange={e => set({ note: e.target.value })} /></Field>
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submit}>{form.id ? "บันทึกการแก้ไข" : "บันทึก"}</Btn>
          </div>
        </div>
      )}

      {/* Confirm delete popup */}
      {deletingEntry && (
        <ConfirmDeletePin
          message="ลบบันทึกของเสียนี้ใช่ไหม? (ระบบจะคืนสต็อกที่หักไปกลับให้)"
          staff={staff} ownerProfile={ownerProfile}
          onCancel={() => setDeletingEntry(null)}
          onConfirm={confirmDelete}
          logActivity={logActivity} activityLabel="ลบบันทึกของเสีย" activityCategory="สต๊อก"
        />
      )}
    </div>
  );
}

/* =========================================================================
   LOGIN
   ========================================================================= */

function BrandFontStyle() {
  return (
    <style>{`
      @import url('https://fonts.googleapis.com/css2?family=Prompt:wght@300;400;500;600;700&family=Sarabun:wght@300;400;500;600;700&display=swap');
      .liff-font { font-family: 'Prompt','Sarabun',sans-serif; }
      .liff-font .font-serif { font-family: 'Prompt','Sarabun',sans-serif; font-weight: 600; letter-spacing: 0.01em; }
    `}</style>
  );
}

function LoginPage({ staff, ownerProfile, storeInfo, onLogin, branches, onAttendanceMode }) {
  const [pin, setPin] = useState("");
  const [error, setError] = useState("");
  const [pendingOwnerLogin, setPendingOwnerLogin] = useState(null); // matched owner object, or null when not active
  const [pendingStaffMatch, setPendingStaffMatch] = useState(null); // staff object, when they work multiple branches
  const activeBranches = (branches || []).filter(b => b.active);

  // Let staff type the PIN on a physical keyboard too, not just tap the
  // on-screen pad — must be registered unconditionally (before any early
  // returns below) to satisfy the rules of hooks.
  useEffect(() => {
    function onKeyDown(e) {
      if (e.key >= "0" && e.key <= "9") { pressDigit(e.key); return; }
      if (e.key === "Backspace") { pressBackspace(); return; }
    }
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [pin]);

  function attemptLogin(pinValue = pin) {
    if (isOwnerPin(ownerProfile, pinValue)) {
      const owner = matchingOwner(ownerProfile, pinValue);
      if (activeBranches.length > 1) {
        setPendingOwnerLogin(owner);
        return;
      }
      onLogin({ type: "owner", name: owner?.name || "เจ้าของร้าน", branchId: activeBranches[0]?.id || null });
      return;
    }
    const match = staff.find(s => s.pin === pinValue && s.active);
    if (match) {
      const staffActiveBranches = activeBranches.filter(b => !match.branchIds?.length || match.branchIds.includes(b.id));
      if (staffActiveBranches.length > 1) {
        setPendingStaffMatch(match);
        return;
      }
      onLogin({ type: "staff", staffId: match.id, name: match.name, positionId: match.positionId, branchId: staffActiveBranches[0]?.id || activeBranches[0]?.id || null });
      return;
    }
    setError("PIN ไม่ถูกต้อง หรือพนักงานไม่ได้ใช้งานอยู่");
    setPin("");
  }
  function chooseBranchAndLogin(branchId) {
    onLogin({ type: "owner", name: pendingOwnerLogin?.name || "เจ้าของร้าน", branchId });
  }
  function chooseCentralAndLogin() {
    onLogin({ type: "owner", name: pendingOwnerLogin?.name || "เจ้าของร้าน", branchId: null, isCentral: true });
  }
  function chooseStaffBranchAndLogin(branchId) {
    onLogin({ type: "staff", staffId: pendingStaffMatch.id, name: pendingStaffMatch.name, positionId: pendingStaffMatch.positionId, branchId });
  }

  if (pendingOwnerLogin) {
    const BRANCH_EMOJIS = ["🏢", "🏯", "🏰", "🏛️", "🏬", "🏪"];
    return (
      <div className="liff-font min-h-screen flex items-center justify-center bg-stone-50 p-4">
        <BrandFontStyle />
        <div className="w-full max-w-3xl">
          <div className="text-center mb-8">
            <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-full object-cover mx-auto mb-3" />
            <div className="font-serif text-xl text-stone-800">สวัสดี {pendingOwnerLogin?.name || "เจ้าของร้าน"}</div>
            <p className="text-sm text-stone-400 mt-1">เลือกสาขาที่จะเข้าใช้งาน</p>
          </div>
          <div className="flex flex-wrap items-stretch justify-center gap-4">
            <button onClick={chooseCentralAndLogin}
              className="w-44 bg-white rounded-2xl shadow-sm hover:shadow-md border border-stone-100 p-6 text-center transition-shadow">
              <div className="text-4xl mb-3">🔑</div>
              <div className="font-semibold text-stone-800 text-sm">ระบบกลาง</div>
              <div className="text-xs text-stone-400 mt-1">เข้าถึงได้ทุกสาขา</div>
            </button>
            {activeBranches.map((b, i) => (
              <button key={b.id} onClick={() => chooseBranchAndLogin(b.id)}
                className="w-44 bg-white rounded-2xl shadow-sm hover:shadow-md border border-stone-100 p-6 text-center transition-shadow">
                <div className="text-4xl mb-3">{BRANCH_EMOJIS[i % BRANCH_EMOJIS.length]}</div>
                <div className="font-semibold text-stone-800 text-sm">{b.name}</div>
                <div className="text-xs text-stone-400 mt-1 leading-snug">{b.address}</div>
              </button>
            ))}
          </div>
          <button onClick={() => setPendingOwnerLogin(null)} className="text-xs text-stone-400 hover:text-stone-600 mt-8 block mx-auto">ย้อนกลับ</button>
        </div>
      </div>
    );
  }

  if (pendingStaffMatch) {
    const BRANCH_EMOJIS = ["🏢", "🏯", "🏰", "🏛️", "🏬", "🏪"];
    const staffBranches = activeBranches.filter(b => !pendingStaffMatch.branchIds?.length || pendingStaffMatch.branchIds.includes(b.id));
    return (
      <div className="liff-font min-h-screen flex items-center justify-center bg-stone-50 p-4">
        <BrandFontStyle />
        <div className="w-full max-w-3xl">
          <div className="text-center mb-8">
            <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-full object-cover mx-auto mb-3" />
            <div className="font-serif text-xl text-stone-800">สวัสดี {pendingStaffMatch.displayName || pendingStaffMatch.name}</div>
            <p className="text-sm text-stone-400 mt-1">วันนี้เข้างานที่สาขาไหน?</p>
          </div>
          <div className="flex flex-wrap items-stretch justify-center gap-4">
            {staffBranches.map((b, i) => (
              <button key={b.id} onClick={() => chooseStaffBranchAndLogin(b.id)}
                className="w-44 bg-white rounded-2xl shadow-sm hover:shadow-md border border-stone-100 p-6 text-center transition-shadow">
                <div className="text-4xl mb-3">{BRANCH_EMOJIS[i % BRANCH_EMOJIS.length]}</div>
                <div className="font-semibold text-stone-800 text-sm">{b.name}</div>
                <div className="text-xs text-stone-400 mt-1 leading-snug">{b.address}</div>
              </button>
            ))}
          </div>
          <button onClick={() => setPendingStaffMatch(null)} className="text-xs text-stone-400 hover:text-stone-600 mt-8 block mx-auto">ย้อนกลับ</button>
        </div>
      </div>
    );
  }

  function pressDigit(d) {
    if (pin.length >= 6) return;
    const next = pin + d;
    setPin(next);
    setError("");
    if (next.length === 6) {
      setTimeout(() => attemptLogin(next), 150);
    }
  }
  function pressBackspace() {
    setPin(p => p.slice(0, -1));
    setError("");
  }

  return (
    <div className="liff-font min-h-screen flex bg-stone-50">
      <BrandFontStyle />

      {/* Left half — branding */}
      <div className="hidden sm:flex flex-1 flex-col items-center justify-center text-white p-8 relative"
        style={{ backgroundImage: `linear-gradient(rgba(10,20,30,0.55), rgba(10,20,30,0.55)), url(${LOGIN_BG_DATA_URI})`, backgroundSize: "cover", backgroundPosition: "center" }}>
        <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-24 h-24 rounded-2xl object-cover mb-5 shadow-lg" />
        <div className="font-serif text-3xl">{storeInfo?.name}</div>
        <div className="text-sm text-white/80 tracking-wide mt-1">{storeInfo?.tagline}</div>
        <div className="text-xs text-white/50 mt-8 tracking-widest uppercase">ระบบหลังร้าน</div>
      </div>

      {/* Right half — numeric keypad (built for tapping on iPad) */}
      <div className="flex-1 flex flex-col items-center justify-center p-6">
        {/* Logo shown on small screens where the left panel is hidden */}
        <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-14 h-14 rounded-xl object-cover mb-3 sm:hidden" />

        <div className="w-full max-w-xs">
          <div className="text-center text-sm text-stone-500 mb-5">กรอก PIN 6 หลักเพื่อเข้าสู่ระบบ</div>

          {/* PIN dots */}
          <div className="flex items-center justify-center gap-3 mb-6">
            {Array.from({ length: 6 }).map((_, i) => (
              <span key={i} className={`w-3.5 h-3.5 rounded-full border-2 ${i < pin.length ? "bg-stone-900 border-stone-900" : "border-stone-300"}`} />
            ))}
          </div>

          {error && <div className="text-xs text-rose-500 text-center mb-3">{error}</div>}

          {/* Numeric keypad */}
          <div className="grid grid-cols-3 gap-3">
            {["1", "2", "3", "4", "5", "6", "7", "8", "9"].map(d => (
              <button key={d} onClick={() => pressDigit(d)}
                className="aspect-square rounded-2xl bg-white border border-stone-200 shadow-sm text-2xl font-medium text-stone-800 hover:bg-stone-50 active:bg-stone-100 transition-colors">
                {d}
              </button>
            ))}
            <div />
            <button onClick={() => pressDigit("0")}
              className="aspect-square rounded-2xl bg-white border border-stone-200 shadow-sm text-2xl font-medium text-stone-800 hover:bg-stone-50 active:bg-stone-100 transition-colors">
              0
            </button>
            <button onClick={pressBackspace}
              className="aspect-square rounded-2xl bg-white border border-stone-200 shadow-sm flex items-center justify-center text-stone-500 text-xl hover:bg-stone-50 active:bg-stone-100 transition-colors">
              ⌫
            </button>
          </div>

          <button onClick={onAttendanceMode} className="text-xs text-stone-400 hover:text-amber-700 flex items-center gap-1 mt-8 mx-auto">
            <Clock size={12} /> Check In - Check Out
          </button>
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   PAGE: ลูกค้า — เช็คคะแนนของฉัน (self-service, no staff PIN needed)
   ========================================================================= */

/* =========================================================================
   PAGE: Public — thenuar.com/job (all open positions, no login needed)
   ========================================================================= */

/* =========================================================================
   PAGE: Public — thenuar.com/register (customer self-registration, no login needed)
   ========================================================================= */

function PublicMemberRegisterPage({ members, setMembers, storeInfo }) {
  const emptyForm = { name: "", phone: "", birthday: "", nationalId: "" };
  const [form, setForm] = useState(emptyForm);
  const [error, setError] = useState("");
  const [registered, setRegistered] = useState(null); // the newly created member

  function submit() {
    if (!form.name.trim() || !form.phone.trim()) {
      setError("กรุณากรอกชื่อและเบอร์โทรศัพท์");
      return;
    }
    const normalizedPhone = form.phone.replace(/[^0-9]/g, "");
    const existing = members.find(m => m.phone.replace(/[^0-9]/g, "") === normalizedPhone);
    if (existing) {
      setError("เบอร์นี้เป็นสมาชิกอยู่แล้ว — ลองเช็คคะแนนที่หน้า \"เช็คคะแนนของฉัน\" แทนได้เลย");
      return;
    }
    const nextNum = members.length + 1;
    const id = "MB" + String(nextNum).padStart(3, "0");
    const today = new Date().toISOString().slice(0, 10);
    const newMember = {
      id, name: form.name.trim(), phone: form.phone.trim(), birthday: form.birthday,
      nationalId: form.nationalId, tier: "Silver", points: 0, joined: today,
      taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" },
    };
    setMembers(prev => [...prev, newMember]);
    setRegistered(newMember);
  }

  return (
    <div className="liff-font min-h-screen bg-stone-50 p-4 py-10">
      <BrandFontStyle />
      <div className="w-full max-w-md mx-auto">
        <div className="text-center mb-8">
          <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-2xl object-cover mx-auto mb-3 shadow-sm" />
          <div className="font-serif text-xl text-stone-800">{storeInfo?.name}</div>
          <div className="text-xs text-amber-600 tracking-wide mt-0.5">สมัครสมาชิกบัตรสะสมแต้ม</div>
        </div>

        {registered ? (
          <div className="bg-white rounded-2xl shadow-sm p-6 text-center">
            <div className="text-4xl mb-2">🎉</div>
            <div className="font-semibold text-stone-800 text-lg mb-1">สมัครสมาชิกสำเร็จ!</div>
            <div className="text-sm text-stone-500 mb-4">ยินดีต้อนรับคุณ {registered.name}</div>
            <div className="bg-stone-50 rounded-xl p-4">
              <div className="text-xs text-stone-400">รหัสสมาชิก</div>
              <div className="font-mono text-lg text-stone-800">{registered.id}</div>
              <div className="text-xs text-stone-400 mt-2">ระดับสมาชิก</div>
              <div className="text-sm font-medium text-stone-700">Silver</div>
            </div>
            <p className="text-xs text-stone-400 mt-4">แจ้งเบอร์โทรศัพท์นี้กับพนักงานทุกครั้งที่มาใช้บริการ เพื่อสะสมแต้มได้เลยค่ะ</p>
          </div>
        ) : (
          <div className="bg-white rounded-2xl shadow-sm p-6">
            <div className="space-y-3">
              <Field label="ชื่อ-นามสกุล"><input className={inputCls} value={form.name} onChange={e => { setForm(f => ({ ...f, name: e.target.value })); setError(""); }} placeholder="ชื่อ-นามสกุล" autoFocus /></Field>
              <Field label="เบอร์โทรศัพท์"><input className={inputCls} value={form.phone} onChange={e => { setForm(f => ({ ...f, phone: e.target.value })); setError(""); }} inputMode="tel" placeholder="08x-xxx-xxxx" /></Field>
              <Field label="วันเกิด (ถ้ามี)"><input type="date" className={inputCls} value={form.birthday} onChange={e => setForm(f => ({ ...f, birthday: e.target.value }))} /></Field>
              <Field label="เลขบัตรประชาชน (ถ้ามี)">
                <input className={inputCls} value={form.nationalId} onChange={e => setForm(f => ({ ...f, nationalId: e.target.value.replace(/\D/g, "").slice(0, 13) }))} placeholder="เลข 13 หลัก" />
              </Field>
            </div>
            {error && <div className="text-xs text-rose-500 mt-3">{error}</div>}
            <p className="text-xs text-stone-400 mt-3">สมาชิกใหม่จะเริ่มที่ระดับ Silver ด้วยแต้มสะสม 0 แต้ม</p>
            <Btn className="w-full justify-center mt-4" onClick={submit}>สมัครสมาชิก</Btn>
          </div>
        )}
      </div>
    </div>
  );
}

function PublicJobsPage({ jobs, storeInfo, setApplicants }) {
  const openJobs = (jobs || []).filter(j => j.active !== false);
  const [selectedJob, setSelectedJob] = useState(null);
  const [showApply, setShowApply] = useState(false);

  return (
    <div className="liff-font min-h-screen bg-stone-50 p-4 py-10">
      <BrandFontStyle />
      <div className="w-full max-w-lg mx-auto">
        <div className="text-center mb-8">
          <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-2xl object-cover mx-auto mb-3 shadow-sm" />
          <div className="font-serif text-xl text-stone-800">{storeInfo?.name}</div>
          <div className="text-xs text-amber-600 tracking-wide mt-0.5">ตำแหน่งงานที่เปิดรับสมัคร</div>
        </div>

        {!selectedJob ? (
          <>
            <div className="space-y-3">
              {openJobs.map(j => (
                <button key={j.id} onClick={() => setSelectedJob(j)} className="w-full text-left bg-white rounded-2xl shadow-sm p-5 hover:shadow-md transition-shadow">
                  <div className="flex items-start justify-between gap-3">
                    <div className="min-w-0">
                      <div className="font-semibold text-stone-800 text-lg">{j.title}</div>
                      {j.workLocation && (
                        <div className="text-xs text-sky-600 mt-1 flex items-center gap-1"><MapPin size={12} className="flex-shrink-0" /> <span className="truncate">{j.workLocation}</span></div>
                      )}
                      <div className="text-sm text-stone-600 mt-2 flex items-center gap-1">
                        <Banknote size={14} className="text-stone-400" /> {j.salaryMin}{j.salaryMax ? `–${j.salaryMax}` : ""} {j.salaryUnit}
                      </div>
                    </div>
                    <ChevronRight size={20} className="text-stone-300 flex-shrink-0 mt-1" />
                  </div>
                </button>
              ))}
              {openJobs.length === 0 && (
                <div className="bg-white rounded-2xl shadow-sm p-8 text-center text-sm text-stone-400">
                  ขณะนี้ยังไม่มีตำแหน่งงานที่เปิดรับสมัคร
                </div>
              )}
            </div>
            {openJobs.length > 0 && (
              <p className="text-xs text-stone-400 text-center mt-6">แตะที่ตำแหน่งที่สนใจเพื่อดูรายละเอียดและสมัครงาน</p>
            )}
          </>
        ) : (
          <div className="bg-white rounded-2xl shadow-sm p-6">
            <button onClick={() => setSelectedJob(null)} className="text-xs text-stone-400 hover:text-stone-600 flex items-center gap-1 mb-4">
              <ChevronLeft size={14} /> ตำแหน่งงานทั้งหมด
            </button>

            <div className="font-semibold text-stone-800 text-xl">{selectedJob.title}</div>
            {selectedJob.workLocation && (
              <div className="text-sm text-stone-600 mt-1.5 flex items-start gap-1.5">
                <MapPin size={15} className="text-stone-400 flex-shrink-0 mt-0.5" />
                <span>
                  {selectedJob.workLocation}
                  {selectedJob.mapUrl && (
                    <a href={selectedJob.mapUrl} target="_blank" rel="noreferrer" className="text-sky-600 hover:text-sky-800 ml-1.5 inline-flex items-center gap-0.5">
                      ดูแผนที่ <ExternalLink size={11} />
                    </a>
                  )}
                </span>
              </div>
            )}
            <div className="text-sm text-stone-600 mt-2 flex items-center gap-1.5">
              <Banknote size={15} className="text-stone-400" /> {selectedJob.salaryMin}{selectedJob.salaryMax ? `–${selectedJob.salaryMax}` : ""} {selectedJob.salaryUnit}
            </div>

            {selectedJob.qualifications?.length > 0 && (
              <div className="mt-5">
                <div className="text-sm font-semibold text-stone-700 mb-2">คุณสมบัติที่ต้องการ</div>
                <ul className="text-sm text-stone-500 space-y-1.5 list-disc list-inside">
                  {selectedJob.qualifications.map((q, i) => <li key={i}>{q}</li>)}
                </ul>
              </div>
            )}

            {selectedJob.contactChannels?.length > 0 && (
              <div className="mt-5 pt-4 border-t border-stone-100">
                <div className="text-sm font-semibold text-stone-700 mb-2">ติดต่อ</div>
                <div className="flex flex-wrap gap-2">
                  {selectedJob.contactChannels.map((c, i) => (
                    <span key={i} className="text-xs px-2.5 py-1 rounded-full bg-stone-50 text-stone-600 border border-stone-200">{c.type}: {c.value}</span>
                  ))}
                </div>
              </div>
            )}

            <Btn className="w-full justify-center mt-6" onClick={() => setShowApply(true)}>สมัครงาน</Btn>
          </div>
        )}
      </div>

      {showApply && selectedJob && (
        <JobApplicationPreview job={selectedJob} storeInfo={storeInfo} setApplicants={setApplicants} onClose={() => setShowApply(false)} isPreview={false} />
      )}
    </div>
  );
}

function MobileOrderPage({ tableId, token, sessions, setSessions, tables, menu, categories, storeInfo, paymentSettings, branches, currentBranchId, printers, skipSyncRef, financeAccounts, members }) {
  const session = sessions[tableId];
  const table = tables.find(t => t.id === tableId);
  const validSession = session && table && session.qrToken === token;

  const [tab, setTab] = useState("menu");
  const [activeCat, setActiveCat] = useState(categories[0]?.id);
  const [cart, setCart] = useState([]);
  const [justSubmitted, setJustSubmitted] = useState(false);
  const [orderError, setOrderError] = useState("");
  const [callSent, setCallSent] = useState(false);
  const [slipUploaded, setSlipUploaded] = useState(false);
  const [memberPhoneInput, setMemberPhoneInput] = useState("");
  const [memberLinkError, setMemberLinkError] = useState("");
  const [memberLinking, setMemberLinking] = useState(false);
  // Menu items with optionGroups (e.g. "ข้าวผัดกุ้ง เล็ก/กลาง/ใหญ่") must go
  // through this picker instead of the quick +/- stepper, mirroring the
  // staff-side POS Order picker (openPicker/toggleChoice/pickerAddonTotal/
  // pickerMissingRequired there) — otherwise a customer's phone silently
  // adds the item at its base price with no size (or other required option)
  // recorded at all, and the kitchen never finds out which size to make.
  const [picker, setPicker] = useState(null); // { item, selections, qty }

  if (!validSession) {
    return (
      <div className="liff-font min-h-screen bg-stone-50 flex items-center justify-center p-6">
        <BrandFontStyle />
        <div className="text-center max-w-xs">
          <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-2xl object-cover mx-auto mb-4" />
          <div className="font-semibold text-stone-800 mb-1">ไม่พบโต๊ะนี้</div>
          <p className="text-sm text-stone-500">ลิงก์นี้อาจหมดอายุแล้ว กรุณาสแกน QR Code ที่โต๊ะอีกครั้ง หรือแจ้งพนักงาน</p>
        </div>
      </div>
    );
  }

  const catItems = menu
    .filter(m => m.catId === activeCat)
    .filter(m => !m.branchIds?.length || m.branchIds.includes(table.branchId || currentBranchId));

  function genCartLineId() { return "cl" + Date.now() + Math.random().toString(36).slice(2, 6); }
  // Total quantity of a menu item across all cart lines (a plain add-only
  // item has exactly one line; an item ordered with different option
  // selections — e.g. one "เล็ก" and one "ใหญ่" ข้าวผัดกุ้ง — has several).
  // Used only for the little "(n)" badge on the menu grid card.
  function qtyInCart(menuId) { return cart.filter(c => c.menuId === menuId).reduce((s, c) => s + c.qty, 0); }
  // The single "plain" cart line for this menu item (no chosen options),
  // if any — used by the quick +/- stepper on the menu grid card. A line
  // that only has a kitchen note (no optionGroups selections) still counts
  // as "plain" here, so the quick stepper keeps adjusting that same line
  // instead of creating a duplicate.
  function simpleLineFor(menuId) { return cart.find(c => c.menuId === menuId && !(c.optionSummary && c.optionSummary.length)); }
  function addItem(item) {
    setCart(prev => {
      const existing = prev.find(c => c.menuId === item.id && !(c.optionSummary && c.optionSummary.length));
      if (existing) return prev.map(c => c.cartLineId === existing.cartLineId ? { ...c, qty: c.qty + 1 } : c);
      return [...prev, { cartLineId: genCartLineId(), menuId: item.id, name: item.name, unitPrice: item.price, qty: 1, catId: item.catId }];
    });
  }
  function incLine(cartLineId) {
    setCart(prev => prev.map(c => c.cartLineId === cartLineId ? { ...c, qty: c.qty + 1 } : c));
  }
  function decItem(cartLineId) {
    if (!cartLineId) return;
    setCart(prev => prev.map(c => c.cartLineId === cartLineId ? { ...c, qty: c.qty - 1 } : c).filter(c => c.qty > 0));
  }

  // Opens the option/note picker for a NEW instance of this menu item —
  // mirrors openPicker/toggleChoice/pickerAddonTotal/pickerMissingRequired/
  // confirmAdd in the staff-side POS Order page (PosOrderPage), including
  // the always-available "หมายเหตุถึงครัว (ถ้ามี)" field, so a customer can
  // leave a kitchen note the same way staff can when they place an order.
  function openPicker(item) {
    const selections = {};
    (item.optionGroups || []).forEach(g => { selections[g.id] = g.type === "single" ? "" : []; });
    setPicker({ item, selections, note: "", qty: 1, editingCartLineId: null });
  }
  // Re-opens the picker prefilled with an existing cart line's selections/
  // note/qty so the customer can change them — mirrors editCartLine on the
  // staff side (triggered there by the pencil icon on a cart line).
  function editCartLine(line) {
    const item = menu.find(m => m.id === line.menuId);
    if (!item) return;
    const selections = {};
    (item.optionGroups || []).forEach(g => { selections[g.id] = line.selections?.[g.id] ?? (g.type === "single" ? "" : []); });
    setPicker({ item, selections, note: line.note || "", qty: line.qty, editingCartLineId: line.cartLineId });
  }
  // Used by the small note/pencil button next to a no-options menu item: if
  // it's already in the cart, reopen (and edit) that same line instead of
  // adding a duplicate; otherwise start a fresh add.
  function openNoteFor(item) {
    const existing = simpleLineFor(item.id);
    if (existing) editCartLine(existing);
    else openPicker(item);
  }
  function toggleChoice(group, choiceId) {
    setPicker(prev => {
      if (!prev) return prev;
      const selections = { ...prev.selections };
      if (group.type === "single") {
        selections[group.id] = selections[group.id] === choiceId ? "" : choiceId;
      } else {
        const cur = selections[group.id] || [];
        if (cur.includes(choiceId)) selections[group.id] = cur.filter(id => id !== choiceId);
        else if (cur.length < (group.max || 99)) selections[group.id] = [...cur, choiceId];
      }
      return { ...prev, selections };
    });
  }
  function pickerAddonTotal() {
    if (!picker) return 0;
    return (picker.item.optionGroups || []).reduce((sum, g) => {
      const sel = picker.selections[g.id];
      if (g.type === "single") {
        const c = g.choices.find(ch => ch.id === sel);
        return sum + (c ? c.price : 0);
      }
      return sum + (sel || []).reduce((s2, id) => {
        const c = g.choices.find(ch => ch.id === id);
        return s2 + (c ? c.price : 0);
      }, 0);
    }, 0);
  }
  function pickerMissingRequired() {
    if (!picker) return false;
    return (picker.item.optionGroups || []).some(g => g.type === "single" && g.required && !picker.selections[g.id]);
  }
  function confirmPickerAdd() {
    if (!picker || pickerMissingRequired()) return;
    const { item, selections, note, qty, editingCartLineId } = picker;
    const optionSummary = [];
    (item.optionGroups || []).forEach(g => {
      const sel = selections[g.id];
      const names = g.type === "single"
        ? (sel ? [g.choices.find(c => c.id === sel)?.name] : [])
        : (sel || []).map(id => g.choices.find(c => c.id === id)?.name);
      names.filter(Boolean).forEach(n => optionSummary.push(n));
    });
    const unitPrice = item.price + pickerAddonTotal();
    if (editingCartLineId) {
      setCart(prev => prev.map(c => c.cartLineId === editingCartLineId
        ? { ...c, unitPrice, qty, optionSummary, note: note.trim(), selections }
        : c));
    } else {
      setCart(prev => [...prev, {
        cartLineId: genCartLineId(), menuId: item.id, name: item.name, unitPrice, qty, catId: item.catId, optionSummary, note: note.trim(), selections,
      }]);
    }
    setPicker(null);
  }

  const cartCount = cart.reduce((s, c) => s + c.qty, 0);
  const cartTotal = cart.reduce((s, c) => s + c.unitPrice * c.qty, 0);

  // submitOrder/callStaff/uploadSlip all write straight to dedicated atomic
  // backend endpoints (append-order / call-staff / slip) instead of relying
  // on the app's usual "whole-collection sync" (setSessions → useEffect →
  // PUT the entire posSessions object back). This customer's phone only
  // ever fetched posSessions ONCE, when the QR code was scanned, and never
  // refreshes it — if the staff POS terminal is open on this same table at
  // the same time and pushes its own (by-then-stale) full snapshot right
  // after, that whole-object push would silently overwrite/erase whatever
  // this customer just ordered. The atomic endpoints instead read-modify-
  // write directly against this one table's row in the database, so the
  // order can't be lost that way. skipSyncRef suppresses this component's
  // own follow-on setSessions() from also triggering that risky whole-
  // object push — the atomic call has already durably saved the change.
  async function submitOrder() {
    if (cart.length === 0) return;
    setOrderError("");
    const ticketId = Math.floor(Math.random() * 900) + 100;
    const branchIdForPrint = table.branchId || currentBranchId || null;
    const foodItems = cart.filter(c => categories.find(cat => cat.id === c.catId)?.kind !== "drink");
    const drinkItems = cart.filter(c => categories.find(cat => cat.id === c.catId)?.kind === "drink");
    const newTickets = [];
    // status: "queued" is required here — KitchenBoard filters tickets into
    // its queued/cooking/done columns with a strict t.status === col.key
    // check, so a ticket saved without a status field never matches any
    // column and silently never appears on the board at all (even though
    // it's saved fine and sitting in the array). The staff-side sendToKitchen()
    // already sets this; this customer-side path was missing it.
    // options: i.optionSummary and note: i.note here (not hardcoded [] / "")
    // — otherwise a customer-picked size/option or kitchen note (from the
    // picker below) would still save correctly to the bill but never reach
    // the kitchen ticket, so the kitchen wouldn't know which size to make or
    // see "ไม่ใส่ผัก"/"ไม่เผ็ด" etc.
    const fmtTicketItem = i => ({ name: i.name, qty: i.qty, options: i.optionSummary || [], note: i.note || "" });
    if (foodItems.length) newTickets.push({ boardType: "food", ticket: { id: ticketId, table: tableId, branchId: branchIdForPrint, kitchenLabel: "ครัวอาหาร", status: "queued", time: "เมื่อสักครู่", items: foodItems.map(fmtTicketItem) } });
    if (drinkItems.length) newTickets.push({ boardType: "drink", ticket: { id: ticketId + 1, table: tableId, branchId: branchIdForPrint, kitchenLabel: "ครัวเครื่องดื่ม", status: "queued", time: "เมื่อสักครู่", items: drinkItems.map(fmtTicketItem) } });

    let nextSession;
    try {
      nextSession = await api.appendTableOrder(tableId, cart, cartTotal);
    } catch (err) {
      console.error("ส่งออเดอร์ไม่สำเร็จ:", err);
      setOrderError("ส่งออเดอร์ไม่สำเร็จ กรุณาลองใหม่อีกครั้ง หรือแจ้งพนักงาน");
      return; // keep the cart intact so the customer can retry
    }

    // Save the new kitchen ticket(s) the same atomic way, so they reach the
    // Kitchen Board even if this table's board data was stale on this phone.
    for (const { boardType, ticket } of newTickets) {
      try { await api.createKitchenTicket(boardType, ticket); }
      catch (err) { console.error("บันทึกตั๋วครัวไม่สำเร็จ:", err); }
    }

    if (skipSyncRef?.current) skipSyncRef.current.posSessions = true;
    setSessions(prev => ({ ...prev, [tableId]: nextSession }));
    setCart([]);
    setJustSubmitted(true);
    setTab("menu");
    setTimeout(() => setJustSubmitted(false), 4000);

    // Print straight to the kitchen printer, same eligibility check used for
    // staff-side "ส่งเข้าครัว" — only fires if a connected printer for this
    // branch has ครัว/เครื่องดื่ม printing turned on in ตั้งค่าเครื่องพิมพ์.
    // NOTE: this only works if the customer's phone can actually reach the
    // print agent (e.g. on the restaurant's own Wi-Fi) — on mobile data it
    // won't connect, since the agent runs on a device on the local network.
    for (const { ticket: t } of newTickets) {
      const toggleKey = t.kitchenLabel === "ครัวเครื่องดื่ม" ? "drinkEnabled" : "kitchenEnabled";
      const eligiblePrinter = (printers || []).find(p => p.connected && p[toggleKey] && (!p.branchId || p.branchId === branchIdForPrint));
      if (eligiblePrinter) {
        await printViaAgent("kitchen", buildKitchenTicketDoc(t));
      }
    }
  }

  async function callStaff(reason) {
    try {
      const nextSession = await api.callStaffForTable(tableId, reason);
      if (skipSyncRef?.current) skipSyncRef.current.posSessions = true;
      setSessions(prev => ({ ...prev, [tableId]: nextSession }));
      setCallSent(true);
      setTimeout(() => setCallSent(false), 4000);
    } catch (err) {
      console.error("แจ้งพนักงานไม่สำเร็จ:", err);
    }
  }

  function uploadSlip(file) {
    const reader = new FileReader();
    reader.onload = async () => {
      try {
        const nextSession = await api.uploadSlipForTable(tableId, reader.result);
        if (skipSyncRef?.current) skipSyncRef.current.posSessions = true;
        setSessions(prev => ({ ...prev, [tableId]: nextSession }));
        setSlipUploaded(true);
      } catch (err) {
        console.error("อัปโหลดสลิปไม่สำเร็จ:", err);
      }
    };
    reader.readAsDataURL(file);
  }

  // Looks the phone number up against the members list already loaded for
  // the whole app (read-only lookup — no writes to the members collection
  // itself, so this can't collide with the whole-collection member sync).
  // Only actually links the found member's id to THIS table's session, via
  // the same atomic read-modify-write pattern as callStaff/uploadSlip above,
  // so it can't be clobbered by — or clobber — a stale staff POS snapshot.
  function linkMemberByPhone() {
    setMemberLinkError("");
    const phone = memberPhoneInput.trim();
    if (!phone) return;
    const found = (members || []).find(m => m.phone === phone);
    if (!found) { setMemberLinkError("ไม่พบสมาชิกเบอร์นี้ในระบบ"); return; }
    setMemberLinking(true);
    api.linkMemberForTable(tableId, found.id)
      .then(nextSession => {
        if (skipSyncRef?.current) skipSyncRef.current.posSessions = true;
        setSessions(prev => ({ ...prev, [tableId]: nextSession }));
        setMemberPhoneInput("");
      })
      .catch(err => {
        console.error("ผูกสมาชิกไม่สำเร็จ:", err);
        setMemberLinkError("ผูกสมาชิกไม่สำเร็จ กรุณาลองใหม่อีกครั้ง");
      })
      .finally(() => setMemberLinking(false));
  }
  function unlinkMember() {
    api.linkMemberForTable(tableId, null)
      .then(nextSession => {
        if (skipSyncRef?.current) skipSyncRef.current.posSessions = true;
        setSessions(prev => ({ ...prev, [tableId]: nextSession }));
      })
      .catch(err => console.error("ยกเลิกผูกสมาชิกไม่สำเร็จ:", err));
  }

  const branch = branches?.find(b => b.id === (table.branchId || currentBranchId));
  // Mirrors the same two-tier PromptPay lookup used in the staff-side
  // precheck bill (PosOrderPage): a branch can have PromptPay configured
  // either via its own simple promptPayEnabled/promptPayId fields (ตั้งค่า
  // สาขา), OR via a finance account of type "other"/channelType "พร้อมเพย์"
  // (ตั้งค่า → การเงิน) — a shop may have only filled in ONE of these two
  // separate places. This page used to check ONLY the branch-level fields,
  // so a shop that set PromptPay up via the finance-accounts screen (like
  // the one already offered as a payment method on the staff POS) would
  // still see "ร้านยังไม่ได้เปิดใช้งาน PromptPay" here even though it really
  // is enabled — falling back to finance accounts fixes that mismatch.
  let promptPayId = branch?.promptPayEnabled ? branch.promptPayId : null;
  if (!promptPayId) {
    const enabledIds = paymentSettings?.enabledFinanceAccountIds || [];
    const promptPayAccounts = (financeAccounts || []).filter(a =>
      a.type === "other" && a.channelType === "พร้อมเพย์" && a.promptPayId && enabledIds.includes(a.id)
    );
    const acc = promptPayAccounts.find(a => a.ourBranchId === (table.branchId || currentBranchId)) || promptPayAccounts.find(a => !a.ourBranchId);
    if (acc) promptPayId = acc.promptPayId;
  }
  const linkedMemberForTable = (members || []).find(m => m.id === session.memberId) || null;

  return (
    <div className="liff-font min-h-screen bg-stone-50 pb-20">
      <BrandFontStyle />

      <div className="bg-white border-b border-stone-100 px-4 py-3 flex items-center gap-3 sticky top-0 z-10">
        <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-9 h-9 rounded-lg object-cover" />
        <div className="min-w-0">
          <div className="font-semibold text-stone-800 text-sm truncate">{storeInfo?.name}</div>
          <div className="text-xs text-amber-600">โต๊ะ {tableId?.replace(/^T/, "")}</div>
        </div>
      </div>

      {justSubmitted && (
        <div className="mx-4 mt-3 p-3 rounded-lg bg-emerald-50 border border-emerald-200 text-emerald-700 text-sm text-center">
          ส่งออเดอร์แล้ว! ทางร้านกำลังจัดเตรียมให้ค่ะ
        </div>
      )}

      {tab === "menu" && (
        <div>
          <div className="flex gap-2 overflow-x-auto px-4 py-3 sticky top-[57px] bg-stone-50 z-10">
            {categories.map(c => (
              <button key={c.id} onClick={() => setActiveCat(c.id)}
                className={`px-3.5 py-1.5 rounded-full text-sm font-medium whitespace-nowrap ${activeCat === c.id ? "bg-stone-900 text-white" : "bg-white border border-stone-200 text-stone-600"}`}>
                {c.name}
              </button>
            ))}
          </div>
          <div className="px-4 grid grid-cols-2 gap-3">
            {catItems.map(item => {
              const qty = qtyInCart(item.id);
              const hasOptions = (item.optionGroups || []).length > 0;
              return (
                <div key={item.id} className="bg-white rounded-xl shadow-sm overflow-hidden">
                  <div className="aspect-square bg-stone-100 flex items-center justify-center">
                    {item.imageDataUrl ? <img src={item.imageDataUrl} alt={item.name} className="w-full h-full object-cover" /> : <UtensilsCrossed size={28} className="text-stone-300" />}
                  </div>
                  <div className="p-2.5">
                    <div className="flex items-center gap-1.5">
                      <div className="text-sm font-medium text-stone-800 truncate">{item.name}</div>
                      {hasOptions && <span className="text-[9px] px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200 flex-shrink-0">ตัวเลือก</span>}
                    </div>
                    <div className="text-sm font-mono text-amber-700 mt-0.5">฿{fmtMoney(item.price)}</div>
                    {hasOptions ? (
                      // Items with option groups (e.g. size เล็ก/กลาง/ใหญ่) must
                      // always go through the picker so a required option can
                      // never be skipped — no quick +/- stepper here, since a
                      // single menu item can end up as several cart lines with
                      // different selections (see openPicker/confirmPickerAdd).
                      <button onClick={() => openPicker(item)} className="w-full mt-2 py-1.5 rounded-lg bg-stone-900 text-white text-xs font-medium">
                        เลือกตัวเลือก{qty > 0 ? ` (${qty})` : ""}
                      </button>
                    ) : qty === 0 ? (
                      <div className="flex items-center gap-1.5 mt-2">
                        <button onClick={() => addItem(item)} className="flex-1 py-1.5 rounded-lg bg-stone-900 text-white text-xs font-medium">+ เพิ่ม</button>
                        {/* Opens the same note+qty picker used for option items, minus
                            the options section — lets a customer leave a kitchen note
                            (เช่น "ไม่ใส่ผัก") on a plain menu item too, same as staff
                            can from POS Order, without slowing down the common quick-add. */}
                        <button onClick={() => openNoteFor(item)} title="เพิ่มหมายเหตุถึงครัว" className="w-8 h-8 flex-shrink-0 flex items-center justify-center rounded-lg border border-stone-200 text-stone-400 hover:text-stone-600"><Pencil size={13} /></button>
                      </div>
                    ) : (
                      <div className="flex items-center gap-1.5 mt-2">
                        <div className="flex-1 flex items-center justify-between bg-stone-50 rounded-lg">
                          <button onClick={() => decItem(simpleLineFor(item.id)?.cartLineId)} className="w-8 h-8 flex items-center justify-center text-stone-600 font-bold">−</button>
                          <span className="text-sm font-medium">{qty}</span>
                          <button onClick={() => addItem(item)} className="w-8 h-8 flex items-center justify-center text-stone-600 font-bold">+</button>
                        </div>
                        <button onClick={() => openNoteFor(item)} title="เพิ่มหมายเหตุถึงครัว" className="w-8 h-8 flex-shrink-0 flex items-center justify-center rounded-lg border border-stone-200 text-stone-400 hover:text-stone-600"><Pencil size={13} /></button>
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {tab === "cart" && (
        <div className="px-4 py-4">
          <div className="font-semibold text-stone-800 mb-3">ตะกร้าของฉัน</div>
          {cart.length === 0 ? (
            <div className="text-sm text-stone-400 text-center py-10">ยังไม่มีรายการในตะกร้า</div>
          ) : (
            <>
              <div className="bg-white rounded-xl shadow-sm divide-y divide-stone-100">
                {cart.map(c => (
                  <div key={c.cartLineId} className="p-3 flex items-center justify-between gap-2">
                    <div className="min-w-0">
                      <div className="text-sm font-medium text-stone-800 truncate">{c.name}</div>
                      {c.optionSummary && c.optionSummary.length > 0 && (
                        <div className="text-xs text-amber-600 truncate">{c.optionSummary.join(", ")}</div>
                      )}
                      {c.note && <div className="text-[11px] text-rose-500 italic truncate">หมายเหตุ: {c.note}</div>}
                      <div className="text-xs text-stone-400">฿{fmtMoney(c.unitPrice)} x {c.qty}</div>
                    </div>
                    <div className="flex items-center gap-2 flex-shrink-0">
                      <button onClick={() => editCartLine(c)} title="แก้ไขรายการ" className="w-7 h-7 flex items-center justify-center rounded-full border border-stone-200 text-stone-400 hover:text-stone-600"><Pencil size={12} /></button>
                      <button onClick={() => decItem(c.cartLineId)} className="w-7 h-7 rounded-full bg-stone-100 text-stone-600 font-bold">−</button>
                      <span className="text-sm w-5 text-center">{c.qty}</span>
                      <button onClick={() => incLine(c.cartLineId)} className="w-7 h-7 rounded-full bg-stone-100 text-stone-600 font-bold">+</button>
                    </div>
                  </div>
                ))}
              </div>
              <div className="flex items-center justify-between mt-4 text-stone-700">
                <span className="font-medium">ยอดรวม</span>
                <span className="font-mono font-semibold">฿{fmtMoney(cartTotal)}</span>
              </div>
              {orderError && <div className="mt-3 p-2.5 rounded-lg bg-rose-50 border border-rose-200 text-rose-600 text-xs text-center">{orderError}</div>}
              <Btn className="w-full justify-center mt-4" onClick={submitOrder}>ส่งออเดอร์</Btn>
            </>
          )}

          {(session.sentItems || []).length > 0 && (
            <div className="mt-6 pt-4 border-t border-stone-200">
              <div className="text-xs font-semibold text-stone-400 uppercase tracking-wide mb-2">รายการที่สั่งไปแล้ว</div>
              <div className="bg-white rounded-xl shadow-sm divide-y divide-stone-100">
                {session.sentItems.map((it, i) => (
                  <div key={i} className="p-3 flex items-center justify-between text-sm">
                    <span className="text-stone-600">
                      {it.name} x{it.qty}
                      {it.optionSummary && it.optionSummary.length > 0 && (
                        <span className="block text-xs text-amber-600">{it.optionSummary.join(", ")}</span>
                      )}
                    </span>
                    <span className="font-mono text-stone-500">฿{fmtMoney(it.unitPrice * it.qty)}</span>
                  </div>
                ))}
              </div>
              <div className="flex items-center justify-between mt-3 text-stone-700">
                <span className="font-medium">ยอดรวมทั้งหมด</span>
                <span className="font-mono font-semibold">฿{fmtMoney(session.billTotal || 0)}</span>
              </div>
            </div>
          )}
        </div>
      )}
      {tab === "call" && (
        <div className="px-4 py-4">
          <div className="font-semibold text-stone-800 mb-1">เรียกพนักงาน</div>
          <p className="text-sm text-stone-500 mb-4">กดเพื่อแจ้งพนักงานให้มาที่โต๊ะของคุณ</p>
          {callSent ? (
            <div className="p-4 rounded-xl bg-emerald-50 border border-emerald-200 text-emerald-700 text-sm text-center">
              แจ้งพนักงานแล้ว กรุณารอสักครู่ค่ะ
            </div>
          ) : (
            <div className="space-y-2.5">
              <button onClick={() => callStaff("ต้องการความช่วยเหลือทั่วไป")} className="w-full p-4 rounded-xl bg-white shadow-sm text-left flex items-center gap-3">
                <MessageCircle size={20} className="text-amber-600 flex-shrink-0" />
                <span className="text-sm font-medium text-stone-700">ต้องการความช่วยเหลือทั่วไป</span>
              </button>
              <button onClick={() => callStaff("ขอน้ำ/อุปกรณ์เพิ่มเติม")} className="w-full p-4 rounded-xl bg-white shadow-sm text-left flex items-center gap-3">
                <GlassWater size={20} className="text-sky-600 flex-shrink-0" />
                <span className="text-sm font-medium text-stone-700">ขอน้ำ/อุปกรณ์เพิ่มเติม</span>
              </button>
            </div>
          )}
        </div>
      )}
      {tab === "pay" && (
        <div className="px-4 py-4">
          <div className="font-semibold text-stone-800 mb-1">ชำระเงิน</div>
          <div className="flex items-center justify-between p-3 rounded-lg bg-white shadow-sm mb-4">
            <span className="text-sm text-stone-500">ยอดที่ต้องชำระ</span>
            <span className="font-mono font-semibold text-lg">฿{fmtMoney(session.billTotal || 0)}</span>
          </div>

          <div className="p-3 rounded-lg bg-white shadow-sm mb-4">
            <div className="text-sm font-medium text-stone-700 mb-2">ผูกสมาชิก (ถ้ามี)</div>
            {linkedMemberForTable ? (
              <div className="flex items-center justify-between">
                <div className="text-sm text-stone-600">
                  <span className="font-medium text-stone-800">{linkedMemberForTable.name}</span>
                  <span className="text-stone-400"> · {linkedMemberForTable.tier}</span>
                </div>
                <button onClick={unlinkMember} className="text-xs text-stone-400 hover:text-rose-500">ยกเลิก</button>
              </div>
            ) : (
              <>
                <div className="flex gap-2">
                  <input inputMode="numeric" placeholder="เบอร์โทรศัพท์สมาชิก" className="flex-1 px-3 py-2 rounded-lg border border-stone-200 text-sm"
                    value={memberPhoneInput} onChange={e => { setMemberPhoneInput(e.target.value.replace(/\D/g, "").slice(0, 10)); setMemberLinkError(""); }} />
                  <button onClick={linkMemberByPhone} disabled={!memberPhoneInput || memberLinking}
                    className="px-4 rounded-lg bg-stone-800 text-white text-sm font-medium disabled:opacity-40">
                    {memberLinking ? "..." : "ผูก"}
                  </button>
                </div>
                {memberLinkError && <p className="text-xs text-rose-500 mt-1.5">{memberLinkError}</p>}
              </>
            )}
          </div>

          {session.paymentStatus === "pending_verification" ? (
            <div className="p-4 rounded-xl bg-amber-50 border border-amber-200 text-center">
              <div className="text-sm font-medium text-amber-800">ส่งสลิปแล้ว กำลังรอพนักงานตรวจสอบ</div>
              <p className="text-xs text-amber-600 mt-1">เมื่อพนักงานตรวจสอบเรียบร้อย จะมาปิดโต๊ะให้ค่ะ</p>
            </div>
          ) : (
            <div className="space-y-3">
              <button onClick={() => callStaff("ชำระเงิน — ขอให้พนักงานมาเก็บที่โต๊ะ")}
                className="w-full p-4 rounded-xl bg-white shadow-sm text-left flex items-center gap-3">
                <Banknote size={20} className="text-emerald-600 flex-shrink-0" />
                <div>
                  <div className="text-sm font-medium text-stone-700">เรียกพนักงานมาเก็บเงินที่โต๊ะ</div>
                  <div className="text-xs text-stone-400">ชำระเงินสดหรือบัตรกับพนักงาน</div>
                </div>
              </button>

              {promptPayId ? (
                <div className="p-4 rounded-xl bg-white shadow-sm">
                  <div className="flex items-center gap-3 mb-3">
                    <QrCode size={20} className="text-sky-600 flex-shrink-0" />
                    <div className="text-sm font-medium text-stone-700">ชำระผ่าน PromptPay</div>
                  </div>
                  <img src={promptPayQrImageUrl(promptPayId, session.billTotal || 0, 220)} alt="PromptPay QR" className="w-48 h-48 mx-auto rounded-lg border border-stone-100" />
                  <p className="text-xs text-stone-400 text-center mt-2 mb-3">สแกนจ่ายแล้ว แนบสลิปยืนยันด้านล่าง</p>
                  <label className="block w-full text-center py-2.5 rounded-lg border border-dashed border-stone-300 text-sm text-stone-500 cursor-pointer hover:bg-stone-50">
                    {slipUploaded ? "แนบสลิปแล้ว ✓ (แตะเพื่อเปลี่ยน)" : "แนบสลิปยืนยันการโอน"}
                    <input type="file" accept="image/*" className="hidden" onChange={e => e.target.files?.[0] && uploadSlip(e.target.files[0])} />
                  </label>
                </div>
              ) : (
                <div className="p-4 rounded-xl bg-stone-100 text-xs text-stone-400 text-center">ร้านยังไม่ได้เปิดใช้งาน PromptPay สำหรับสาขานี้</div>
              )}
            </div>
          )}
        </div>
      )}

      <div className="fixed bottom-0 left-0 right-0 bg-white border-t border-stone-200 flex items-stretch z-20">
        {[
          { key: "menu", label: "เมนู", icon: UtensilsCrossed },
          { key: "cart", label: "ตะกร้า", icon: ShoppingCart, badge: cartCount },
          { key: "call", label: "เรียกพนักงาน", icon: MessageCircle },
          { key: "pay", label: "ชำระเงิน", icon: CreditCard },
        ].map(t => (
          <button key={t.key} onClick={() => setTab(t.key)}
            className={`flex-1 flex flex-col items-center gap-0.5 py-2.5 relative ${tab === t.key ? "text-amber-700" : "text-stone-400"}`}>
            <t.icon size={19} />
            <span className="text-[10px] font-medium">{t.label}</span>
            {t.badge > 0 && (
              <span className="absolute top-1 right-1/4 bg-rose-500 text-white text-[9px] rounded-full w-4 h-4 flex items-center justify-center">{t.badge}</span>
            )}
          </button>
        ))}
      </div>

      {picker && (
        <div className="fixed inset-0 z-50 bg-black/40 flex items-end justify-center" onClick={() => setPicker(null)}>
          <div className="bg-white rounded-t-2xl w-full max-w-md max-h-[85vh] overflow-y-auto p-4" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-3">
              <div>
                {picker.editingCartLineId && <div className="text-[10px] font-semibold text-amber-600 uppercase tracking-wide mb-0.5">แก้ไขรายการ</div>}
                <div className="font-semibold text-stone-800">{picker.item.name}</div>
              </div>
              <button onClick={() => setPicker(null)} className="w-8 h-8 flex items-center justify-center rounded-lg text-stone-400 hover:bg-stone-100"><X size={18} /></button>
            </div>
            <div className="space-y-4">
              {(picker.item.optionGroups || []).map(g => (
                <div key={g.id}>
                  <div className="flex items-center gap-1.5 mb-2">
                    <span className="text-sm font-medium text-stone-700">{g.name}</span>
                    {g.required && <span className="text-[10px] px-1.5 py-0.5 rounded bg-rose-50 text-rose-500 border border-rose-200">ต้องระบุ</span>}
                  </div>
                  <div className="space-y-1.5">
                    {g.choices.map(c => {
                      const sel = picker.selections[g.id];
                      const checked = g.type === "single" ? sel === c.id : (sel || []).includes(c.id);
                      return (
                        <button key={c.id} onClick={() => toggleChoice(g, c.id)}
                          className={`w-full flex items-center justify-between px-3 py-2.5 rounded-lg border text-sm ${checked ? "border-amber-400 bg-amber-50 text-amber-800" : "border-stone-200 text-stone-600"}`}>
                          <span>{c.name}</span>
                          <span className="font-mono text-xs">{c.price > 0 ? `+฿${fmtMoney(c.price)}` : ""}</span>
                        </button>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
            <div className="border-t border-stone-100 pt-3 mt-3">
              <Field label="หมายเหตุถึงครัว (ถ้ามี)">
                <input className={inputCls} placeholder="เช่น ไม่ใส่ผัก ไม่เผ็ด" value={picker.note} onChange={e => setPicker(prev => ({ ...prev, note: e.target.value }))} />
              </Field>
            </div>
            <div className="flex items-center gap-3 mt-5">
              <button onClick={() => setPicker(prev => ({ ...prev, qty: Math.max(1, prev.qty - 1) }))} className="w-9 h-9 rounded-full bg-stone-100 text-stone-600 font-bold">−</button>
              <span className="text-sm font-medium w-6 text-center">{picker.qty}</span>
              <button onClick={() => setPicker(prev => ({ ...prev, qty: prev.qty + 1 }))} className="w-9 h-9 rounded-full bg-stone-100 text-stone-600 font-bold">+</button>
              <Btn className="flex-1 justify-center" disabled={pickerMissingRequired()} onClick={confirmPickerAdd}>
                {picker.editingCartLineId ? "บันทึกการแก้ไข" : "เพิ่มลงตะกร้า"} · ฿{fmtMoney((picker.item.price + pickerAddonTotal()) * picker.qty)}
              </Btn>
            </div>
            {pickerMissingRequired() && <div className="text-[11px] text-rose-500 mt-2 text-center">กรุณาเลือกตัวเลือกที่ต้องระบุก่อนเพิ่มลงตะกร้า</div>}
          </div>
        </div>
      )}
    </div>
  );
}

function CustomerSelfServicePage({ members, setMembers, tiers, promotions, rewards, setRewards, history, storeInfo, onBack, pendingRedemptions, setPendingRedemptions, menu, logActivity }) {
  const [query, setQuery] = useState("");
  const [error, setError] = useState("");
  const [foundMember, setFoundMember] = useState(null);
  const [redeeming, setRedeeming] = useState(null); // reward object
  const [redeemToast, setRedeemToast] = useState(""); // brief success message
  const [tab, setTab] = useState("home"); // "home" | "rewards" | "coupons" | "promos"
  const [, forceTick] = useState(0);
  const REVEAL_WINDOW_MS = 90 * 60 * 1000; // 90 minutes
  useEffect(() => {
    const timer = setInterval(() => forceTick(t => t + 1), 1000); // refresh countdown every second
    return () => clearInterval(timer);
  }, []);
  function revealCode(code) {
    if (setPendingRedemptions) {
      setPendingRedemptions(prev => prev.map(r => r.code === code ? { ...r, revealedAt: Date.now() } : r));
    }
  }

  function normalizePhone(v) { return v.replace(/[^0-9]/g, ""); }

  function search() {
    setError("");
    const q = query.trim();
    if (!q) return;
    const match = members.find(m =>
      normalizePhone(m.phone) === normalizePhone(q) ||
      (m.lineUserId && m.lineUserId === q)
    );
    if (!match) {
      setError("ไม่พบข้อมูลสมาชิก — กรุณาตรวจสอบเบอร์โทร หรือติดต่อพนักงานเพื่อสมัครสมาชิก");
      setFoundMember(null);
      return;
    }
    setFoundMember(match);
    setTab("home");
  }

  const [showRegister, setShowRegister] = useState(false);
  const emptyRegisterForm = { name: "", phone: "", birthday: "" };
  const [registerForm, setRegisterForm] = useState(emptyRegisterForm);
  const [registerError, setRegisterError] = useState("");

  function openRegister() {
    setRegisterForm({ ...emptyRegisterForm, phone: query.trim() });
    setRegisterError("");
    setShowRegister(true);
  }
  function submitRegister() {
    if (!registerForm.name.trim()) { setRegisterError("กรุณากรอกชื่อ-นามสกุล"); return; }
    const phoneDigits = normalizePhone(registerForm.phone);
    if (phoneDigits.length < 9) { setRegisterError("กรุณากรอกเบอร์โทรศัพท์ให้ถูกต้อง"); return; }
    if (!registerForm.birthday) { setRegisterError("กรุณากรอกวันเดือนปีเกิด"); return; }
    const existing = members.find(m => normalizePhone(m.phone) === phoneDigits);
    if (existing) { setRegisterError("เบอร์นี้เป็นสมาชิกอยู่แล้ว กรุณาเช็คคะแนนด้วยเบอร์นี้แทน"); return; }
    const nextNum = members.length + 1;
    const newMember = {
      id: "MB" + String(nextNum).padStart(3, "0"),
      name: registerForm.name.trim(), phone: registerForm.phone.trim(), birthday: registerForm.birthday,
      tier: "Silver", points: 0, joined: new Date().toISOString().slice(0, 10),
      nationalId: "", address: "", lineUserId: "",
      taxInvoiceInfo: { name: "", address: "", taxId: "", branch: "สำนักงานใหญ่" },
    };
    setMembers(prev => [...prev, newMember]);
    if (logActivity) logActivity({ category: "บัตรสะสมแต้ม", action: `สมัครสมาชิกใหม่ (สมัครเอง) ${newMember.name}`, detail: `รหัสสมาชิก ${newMember.id} · เบอร์ ${newMember.phone}` });
    setShowRegister(false);
    setFoundMember(newMember);
    setTab("home");
  }

  const tier = foundMember ? tiers.find(t => t.name === foundMember.tier) : null;
  const sortedTiers = [...(tiers || [])].sort((a, b) => a.minPoints - b.minPoints);
  const nextTier = foundMember ? sortedTiers.find(t => t.minPoints > foundMember.points) : null;
  const tierProgress = foundMember && nextTier
    ? Math.min(100, Math.round(((foundMember.points - (tier?.minPoints || 0)) / (nextTier.minPoints - (tier?.minPoints || 0))) * 100))
    : 100;
  const todayStr = new Date().toISOString().slice(0, 10);

  const activePromotions = (promotions || []).filter(p => p.active !== false);

  const TIER_ICON = { Silver: "🥈", Gold: "🥇", Platinum: "💎" };
  const TIER_GRADIENT = {
    Silver: "from-stone-500 to-stone-700",
    Gold: "from-amber-400 to-amber-600",
    Platinum: "from-sky-500 to-indigo-600",
  };

  function rewardEligibility(r) {
    if (!foundMember) return { ok: false, reason: "-" };
    if (r.startDate && todayStr < r.startDate) return { ok: false, reason: "ยังไม่เริ่มโปรโมชั่น" };
    if (r.endDate && todayStr > r.endDate) return { ok: false, reason: "หมดเขตแล้ว" };
    if (r.quota !== "" && r.quota != null && r.usedCount >= Number(r.quota)) return { ok: false, reason: "ของรางวัลหมดแล้ว" };
    const usedByMember = r.redemptionsByMember?.[foundMember.id] || 0;
    if (r.limitPerMember !== "" && r.limitPerMember != null && usedByMember >= Number(r.limitPerMember)) return { ok: false, reason: "แลกครบสิทธิ์ของคุณแล้ว", exhausted: true };
    if (foundMember.points < r.points) return { ok: false, reason: "แต้มไม่พอ" };
    return { ok: true, reason: "" };
  }
  // Rewards this customer has personally used up their allotted redemptions for
  // (limitPerMember reached) are hidden entirely — no longer relevant to them —
  // while other ineligible reasons (insufficient points, quota, dates) still
  // show grayed out so they know the reward exists.
  const visibleRewardsForMember = (rewards || []).filter(r => !rewardEligibility(r).exhausted);

  function confirmRedeem() {
    if (!redeeming || !foundMember) return;
    const r = redeeming;
    const updatedMember = { ...foundMember, points: foundMember.points - r.points };
    setMembers(prev => prev.map(m => m.id === foundMember.id ? updatedMember : m));
    setFoundMember(updatedMember);
    if (setRewards) {
      setRewards(prev => prev.map(rw => rw.id === r.id
        ? { ...rw, usedCount: (rw.usedCount || 0) + 1, redemptionsByMember: { ...rw.redemptionsByMember, [foundMember.id]: (rw.redemptionsByMember?.[foundMember.id] || 0) + 1 } }
        : rw));
    }
    const code = `RD${Date.now().toString().slice(-6)}`;
    if (setPendingRedemptions) {
      setPendingRedemptions(prev => [...prev, {
        code, memberId: foundMember.id, memberName: foundMember.name,
        rewardId: r.id, rewardName: r.name, createdAt: new Date().toISOString(), used: false, revealedAt: null,
      }]);
    }
    setRedeeming(null);
    setRedeemToast(`เก็บ "${r.name}" ไว้ใน "คูปองของฉัน" แล้ว`);
    setTab("coupons");
    setTimeout(() => setRedeemToast(""), 3000);
  }

  const myCoupons = foundMember
    ? (pendingRedemptions || []).filter(r => r.memberId === foundMember.id).sort((a, b) => b.createdAt.localeCompare(a.createdAt))
    : [];

  function menuName(id) { return menu?.find(m => m.id === id)?.name; }

  function describePromotion(p) {
    if (p.type === "minSpend") {
      const d = p.minSpend || {};
      const discountText = d.discountType === "percent" ? `${d.value}%` : `฿${d.value}`;
      return { text: `ซื้อครบ ฿${d.amount?.toLocaleString()} รับส่วนลด ${discountText}`, items: [] };
    }
    if (p.type === "bundle") {
      const d = p.bundle || {};
      const items = [...(d.foodItemIds || []), ...(d.drinkItemIds || [])].map(menuName).filter(Boolean);
      const text = d.promoMode === "percent"
        ? `เซ็ตสุดคุ้ม ลด ${d.promoPercent}% จากราคาปกติ ฿${d.fullPrice?.toLocaleString()}`
        : `เซ็ตสุดคุ้ม ราคาพิเศษเพียง ฿${d.promoPrice?.toLocaleString()} (จากราคาปกติ ฿${d.fullPrice?.toLocaleString()})`;
      return { text, items };
    }
    if (p.type === "happyHour") {
      const d = p.happyHour || {};
      const discountText = d.discountType === "percent" ? `${d.value}%` : `฿${d.value}`;
      return { text: `ช่วงเวลา ${d.startTime}–${d.endTime} น. รับส่วนลด ${discountText}`, items: [] };
    }
    if (p.type === "mixMatch") {
      const d = p.mixMatch || {};
      const items = (d.itemIds || []).map(menuName).filter(Boolean);
      return { text: `เลือก ${d.chooseCount} รายการจากเมนูร่วมรายการ ในราคาเดียว ฿${d.price?.toLocaleString()}`, items };
    }
    if (p.type === "points") {
      const d = p.points || {};
      const when = d.trigger === "birthdayMonth" ? "ในเดือนเกิดของคุณ" : "เมื่อเข้าเงื่อนไข";
      const text = d.rewardType === "multiplier" ? `รับแต้มสะสม x${d.multiplier} ${when}` : `รับโบนัส ${d.bonusPoints} แต้ม เมื่อซื้อครบ ฿${d.thresholdAmount?.toLocaleString()} ${when}`;
      return { text, items: [] };
    }
    return { text: "", items: [] };
  }

  const RewardIcon = ({ type }) => (
    <span className="w-11 h-11 rounded-xl bg-amber-50 flex items-center justify-center flex-shrink-0 text-lg">
      {type === "food" ? "🍽️" : type === "discount" ? "🏷️" : "🎁"}
    </span>
  );

  return (
    <div className="liff-font min-h-screen bg-stone-100">
      <BrandFontStyle />
      <div className="w-full max-w-md mx-auto min-h-screen bg-stone-50 shadow-sm relative pb-8">

        {!foundMember ? (
          <div className="px-5 pt-14 pb-8">
            <div className="text-center mb-8">
              <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-2xl object-cover mx-auto mb-3 shadow-sm" />
              <div className="font-serif text-xl text-stone-800">{storeInfo?.name}</div>
              <div className="text-xs text-amber-600 tracking-wide mt-0.5">เช็คคะแนนสมาชิกของฉัน</div>
            </div>
            <div className="bg-white rounded-2xl shadow-sm p-6">
              <div className="text-sm text-stone-600 mb-3 text-center">กรอกเบอร์โทรศัพท์ที่สมัครสมาชิกไว้</div>
              <input className="w-full rounded-xl border border-stone-300 px-3 py-3.5 text-center text-lg tracking-wide focus:outline-none focus:ring-2 focus:ring-amber-400"
                value={query} onChange={e => setQuery(e.target.value)} onKeyDown={e => e.key === "Enter" && search()}
                inputMode="tel" placeholder="08x-xxx-xxxx" autoFocus />
              {error && <div className="text-xs text-rose-500 mt-2 text-center">{error}</div>}
              <Btn className="w-full justify-center mt-4" onClick={search}>ค้นหาแต้มของฉัน</Btn>
              <button onClick={openRegister} className="text-xs text-stone-400 hover:text-amber-700 mt-4 block mx-auto">
                ยังไม่เป็นสมาชิก? สมัครสมาชิกที่นี่
              </button>
            </div>
          </div>
        ) : (
          <>
            {/* Hero member card */}
            <div className={`bg-gradient-to-br ${TIER_GRADIENT[foundMember.tier] || TIER_GRADIENT.Silver} px-5 pt-10 pb-16 text-white relative`}>
              <button onClick={() => { setFoundMember(null); setQuery(""); setError(""); }} className="absolute left-4 top-4 text-white/70 hover:text-white text-xs">
                ← เปลี่ยนเบอร์
              </button>
              <div className="text-center">
                <div className="w-14 h-14 rounded-full bg-white/20 backdrop-blur flex items-center justify-center text-2xl font-serif mx-auto mb-2 border-2 border-white/40">
                  {foundMember.name.charAt(0)}
                </div>
                <div className="font-semibold text-lg">{foundMember.name}</div>
                <div className="text-xs text-white/80 flex items-center justify-center gap-1 mt-0.5">
                  {TIER_ICON[foundMember.tier] || "⭐"} ระดับ {foundMember.tier}
                </div>
                <div className="text-5xl font-serif mt-4">{foundMember.points.toLocaleString()}</div>
                <div className="text-xs text-white/70">แต้มคงเหลือ</div>
              </div>
            </div>

            {/* Floating content card, overlapping hero */}
            <div className="px-4 -mt-8 relative">
              <div className="bg-white rounded-2xl shadow-md p-4">
                {nextTier ? (
                  <>
                    <div className="flex justify-between text-xs text-stone-500 mb-1.5">
                      <span>ระดับ {nextTier.name}</span>
                      <span>อีก {(nextTier.minPoints - foundMember.points).toLocaleString()} แต้ม</span>
                    </div>
                    <div className="w-full h-2 rounded-full bg-stone-100 overflow-hidden">
                      <div className="h-full rounded-full bg-amber-500 transition-all" style={{ width: `${tierProgress}%` }} />
                    </div>
                  </>
                ) : (
                  <div className="text-xs text-center text-amber-600">🎉 คุณอยู่ระดับสูงสุดแล้ว!</div>
                )}
                {tier?.birthdayDiscount?.enabled && (
                  <div className="text-[11px] text-stone-400 mt-3 flex items-center gap-1">🎂 สิทธิพิเศษวันเกิด: ส่วนลด {tier.birthdayDiscount.percent}%</div>
                )}
              </div>
            </div>

            {/* Tabs */}
            <div className="flex gap-1 px-4 mt-5 mb-1">
              {[
                { key: "home", label: "หน้าหลัก" },
                { key: "rewards", label: "แลกของรางวัล" },
                { key: "coupons", label: `คูปองของฉัน${myCoupons.filter(c => !c.used).length > 0 ? ` (${myCoupons.filter(c => !c.used).length})` : ""}` },
                { key: "promos", label: "โปรโมชั่น" },
              ].map(t => (
                <button key={t.key} onClick={() => setTab(t.key)}
                  className={`flex-1 text-xs sm:text-sm py-2.5 rounded-lg font-medium transition-colors ${tab === t.key ? "bg-stone-900 text-white" : "text-stone-500 hover:bg-stone-100"}`}>
                  {t.label}
                </button>
              ))}
            </div>

            {redeemToast && (
              <div className="mx-4 mt-2 bg-emerald-50 border border-emerald-200 text-emerald-700 text-xs rounded-lg px-3 py-2 text-center">{redeemToast}</div>
            )}

            <div className="px-4 pt-3 space-y-3">
              {tab === "home" && (
                <>
                  <div className="bg-white rounded-2xl shadow-sm p-4">
                    <div className="text-sm font-semibold text-stone-700 mb-2">ของรางวัลแนะนำ</div>
                    <div className="space-y-2">
                      {visibleRewardsForMember.slice(0, 2).map(r => {
                        const elig = rewardEligibility(r);
                        return (
                          <div key={r.id} className="flex items-center gap-3 p-2.5 rounded-lg border border-stone-100">
                            <RewardIcon type={r.type} />
                            <div className="min-w-0 flex-1">
                              <div className="text-sm font-medium text-stone-800 truncate">{r.name}</div>
                              <div className="text-xs text-stone-400">{r.points.toLocaleString()} แต้ม</div>
                            </div>
                            <Btn className="flex-shrink-0 text-xs px-2.5 py-1.5" disabled={!elig.ok} onClick={() => setRedeeming(r)}>แลก</Btn>
                          </div>
                        );
                      })}
                    </div>
                    <button onClick={() => setTab("rewards")} className="text-xs text-amber-700 hover:text-amber-900 mt-3 block mx-auto">ดูของรางวัลทั้งหมด →</button>
                  </div>
                  {activePromotions.length > 0 && (
                    <div className="bg-white rounded-2xl shadow-sm p-4">
                      <div className="text-sm font-semibold text-stone-700 mb-2">โปรโมชั่นวันนี้</div>
                      <div className="p-2.5 rounded-lg bg-amber-50 border border-amber-100">
                        <div className="text-sm text-stone-700 font-medium">{activePromotions[0].name}</div>
                        <div className="text-xs text-stone-500 mt-0.5">{describePromotion(activePromotions[0]).text}</div>
                      </div>
                      <button onClick={() => setTab("promos")} className="text-xs text-amber-700 hover:text-amber-900 mt-3 block mx-auto">ดูโปรโมชั่นทั้งหมด →</button>
                    </div>
                  )}
                </>
              )}

              {tab === "rewards" && (
                <div className="bg-white rounded-2xl shadow-sm p-4">
                  <div className="space-y-2">
                    {visibleRewardsForMember.map(r => {
                      const elig = rewardEligibility(r);
                      return (
                        <div key={r.id} className={`flex items-center gap-3 p-3 rounded-xl border ${elig.ok ? "border-stone-200" : "border-stone-100 opacity-60"}`}>
                          <RewardIcon type={r.type} />
                          <div className="min-w-0 flex-1">
                            <div className="text-sm font-medium text-stone-800 truncate">{r.name}</div>
                            <div className="text-xs text-stone-400">{r.points.toLocaleString()} แต้ม{!elig.ok && <span className="text-rose-400"> · {elig.reason}</span>}</div>
                          </div>
                          <Btn className="flex-shrink-0" disabled={!elig.ok} onClick={() => setRedeeming(r)}>แลก</Btn>
                        </div>
                      );
                    })}
                    {visibleRewardsForMember.length === 0 && (
                      <div className="text-xs text-stone-400 text-center py-6">ยังไม่มีของรางวัลให้แลกตอนนี้</div>
                    )}
                  </div>
                </div>
              )}

              {tab === "coupons" && (
                <div className="bg-white rounded-2xl shadow-sm p-4">
                  <div className="space-y-2.5">
                    {myCoupons.map(c => {
                      const rw = rewards.find(x => x.id === c.rewardId);
                      return (
                      <div key={c.code} className={`p-3 rounded-xl border ${c.used ? "border-stone-100 bg-stone-50" : "border-amber-200 bg-amber-50"}`}>
                        <div className="flex items-start justify-between gap-2">
                          <div className="min-w-0">
                            <div className={`text-sm font-medium truncate ${c.used ? "text-stone-400" : "text-stone-800"}`}>{c.rewardName}</div>
                            <div className="text-[11px] text-stone-400 mt-0.5">ได้รับเมื่อ {fmtDate(c.createdAt.slice(0, 10))}</div>
                            {rw?.endDate && (
                              <div className="text-[11px] text-stone-400">ใช้ได้ถึงวันที่ {fmtDate(rw.endDate)}</div>
                            )}
                          </div>
                          <span className={`text-[10px] px-2 py-0.5 rounded-full flex-shrink-0 font-medium ${c.used ? "bg-stone-200 text-stone-500" : "bg-emerald-100 text-emerald-700"}`}>
                            {c.used ? "ใช้แล้ว" : "พร้อมใช้"}
                          </span>
                        </div>
                        {!c.used && (() => {
                          const msLeft = c.revealedAt ? REVEAL_WINDOW_MS - (Date.now() - c.revealedAt) : 0;
                          if (c.revealedAt && msLeft > 0) {
                            const minsLeft = Math.floor(msLeft / 60000);
                            const secsLeft = Math.floor((msLeft % 60000) / 1000);
                            return (
                              <div className="mt-2 pt-2 border-t border-dashed border-amber-300 text-center">
                                <div className="text-[10px] text-stone-400">แสดงรหัสนี้กับพนักงานตอนชำระเงิน</div>
                                <div className="font-mono text-lg tracking-widest text-amber-700 font-semibold">{c.code}</div>
                                <div className="text-[10px] text-rose-500 mt-1">รหัสจะหมดอายุใน {minsLeft}:{String(secsLeft).padStart(2, "0")} นาที</div>
                              </div>
                            );
                          }
                          return (
                            <div className="mt-2">
                              <p className="text-[11px] text-amber-700 text-center mb-1.5">
                                กรุณากด "ใช้รหัส" ตอนชำระเงิน เนื่องจากรหัสจะหมดอายุภายใน 90 นาที
                              </p>
                              <Btn className="w-full justify-center" onClick={() => revealCode(c.code)}>
                                ใช้รหัส
                              </Btn>
                            </div>
                          );
                        })()}
                      </div>
                      );
                    })}
                    {myCoupons.length === 0 && (
                      <div className="text-xs text-stone-400 text-center py-6">
                        ยังไม่มีคูปอง — ไปที่แท็บ "แลกของรางวัล" เพื่อแลกแต้มเป็นคูปองเก็บไว้ก่อนได้เลย
                      </div>
                    )}
                  </div>
                </div>
              )}

              {tab === "promos" && (
                <div className="bg-white rounded-2xl shadow-sm p-4">
                  <div className="space-y-2.5">
                    {activePromotions.map(p => {
                      const desc = describePromotion(p);
                      return (
                      <div key={p.id} className="p-3.5 rounded-xl bg-stone-50 border border-stone-100">
                        <div className="text-sm font-semibold text-stone-800">{p.name}</div>
                        <div className="text-sm text-stone-600 mt-1">{desc.text}</div>
                        {desc.items.length > 0 && (
                          <div className="flex flex-wrap gap-1.5 mt-2">
                            {desc.items.map((name, i) => (
                              <span key={i} className="text-[11px] px-2 py-0.5 rounded-full bg-white border border-stone-200 text-stone-600">{name}</span>
                            ))}
                          </div>
                        )}
                        {(p.start || p.end) && (
                          <div className="text-[11px] text-stone-400 mt-1.5">ใช้ได้ถึงวันที่ {fmtDate(p.end)}</div>
                        )}
                      </div>
                      );
                    })}
                    {activePromotions.length === 0 && (
                      <div className="text-xs text-stone-400 text-center py-6">ยังไม่มีโปรโมชั่นตอนนี้</div>
                    )}
                  </div>
                </div>
              )}
            </div>
          </>
        )}

        <button onClick={onBack} className="text-[10px] text-stone-300 hover:text-stone-500 mt-8 block mx-auto">
          (สำหรับทดสอบ) กลับสู่หน้าพนักงาน
        </button>
      </div>

      {/* Confirm redeem popup */}
      {redeeming && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setRedeeming(null)}>
          <div className="bg-white rounded-2xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="font-semibold text-stone-800 mb-1">ยืนยันแลกของรางวัล</div>
            <p className="text-sm text-stone-500 mb-4">แลก "{redeeming.name}" ด้วย {redeeming.points.toLocaleString()} แต้ม ใช่หรือไม่?</p>
            <div className="flex justify-end gap-2">
              <Btn variant="ghost" onClick={() => setRedeeming(null)}>ยกเลิก</Btn>
              <Btn onClick={confirmRedeem}>ยืนยันแลก</Btn>
            </div>
          </div>
        </div>
      )}

      {/* Self-registration popup */}
      {showRegister && (
        <div className="fixed inset-0 bg-stone-900/40 flex items-center justify-center z-50 p-4" onClick={() => setShowRegister(false)}>
          <div className="bg-white rounded-2xl w-full max-w-xs p-5" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <div className="font-semibold text-stone-800">สมัครสมาชิก</div>
              <button onClick={() => setShowRegister(false)} className="text-stone-400 hover:text-stone-600"><X size={18} /></button>
            </div>
            <div className="space-y-3">
              <Field label="ชื่อ-นามสกุล">
                <input className={inputCls} value={registerForm.name} onChange={e => { setRegisterForm(f => ({ ...f, name: e.target.value })); setRegisterError(""); }} placeholder="ชื่อ นามสกุล" autoFocus />
              </Field>
              <Field label="เบอร์โทรศัพท์">
                <input className={inputCls} inputMode="tel" value={registerForm.phone} onChange={e => { setRegisterForm(f => ({ ...f, phone: e.target.value })); setRegisterError(""); }} placeholder="08x-xxx-xxxx" />
              </Field>
              <Field label="วันเดือนปีเกิด">
                <input type="date" className={inputCls} value={registerForm.birthday} onChange={e => { setRegisterForm(f => ({ ...f, birthday: e.target.value })); setRegisterError(""); }} />
              </Field>
              {registerError && <div className="text-xs text-rose-500">{registerError}</div>}
            </div>
            <Btn className="w-full justify-center mt-4" onClick={submitRegister}>สมัครสมาชิก</Btn>
            <p className="text-[11px] text-stone-400 text-center mt-3">สมัครแล้วเริ่มสะสมแต้มได้ทันที ไม่มีค่าใช้จ่าย</p>
          </div>
        </div>
      )}
    </div>
  );
}

/* =========================================================================
   PAGE: บัตรสะสมแต้ม — ตั้งค่า LINE OA
   ========================================================================= */

function LineOaSettingsPage({ settings, setSettings }) {
  const [form, setForm] = useState(settings);
  const [saved, setSaved] = useState(false);
  const [showSecret, setShowSecret] = useState(false);
  const [showToken, setShowToken] = useState(false);

  function set(patch) { setForm(prev => ({ ...prev, ...patch })); }
  function save() {
    setSettings(form);
    setSaved(true);
    setTimeout(() => setSaved(false), 2000);
  }

  const isConfigured = !!(form.liffId && form.channelAccessToken);

  return (
    <div>
      <PageHeader eyebrow="บัตรสะสมแต้ม" title="ตั้งค่า LINE OA" subtitle="ใส่ข้อมูล Token/LIFF เพื่อให้สมาชิกเชื่อมต่อผ่าน LINE ได้" />

      <Card className="p-4 mb-5 max-w-2xl border-amber-200 bg-amber-50">
        <div className="text-sm text-amber-800 font-medium mb-1">⚠️ ข้อมูลนี้จะถูกบันทึกไว้เป็นการตั้งค่าเท่านั้น</div>
        <p className="text-xs text-amber-700 leading-relaxed">
          ระบบนี้เป็นหน้าเว็บฝั่ง client เดี่ยวๆ ไม่มี backend server ที่จะเรียกใช้ LINE Login API, Messaging API หรือตรวจสอบ Token จริงได้
          การกรอกค่าด้านล่างนี้จะ<strong>ยังไม่ทำให้ระบบเชื่อมต่อกับ LINE ได้จริง</strong> — เป็นเพียงที่เก็บค่าที่ต้องใช้ไว้ล่วงหน้า
          เผื่อว่าในอนาคตมีการพัฒนา backend จริงมาเชื่อมต่อกับระบบนี้ (เช่น ผ่าน Claude Code หรือทีมพัฒนา) จะได้มีค่าที่จำเป็นครบพร้อมใช้งานทันที
        </p>
      </Card>

      <Card className="p-5 max-w-2xl space-y-4">
        <div className="flex items-center gap-2 mb-1">
          <span className={`w-2.5 h-2.5 rounded-full ${isConfigured ? "bg-emerald-500" : "bg-stone-300"}`} />
          <span className="text-sm text-stone-600">{isConfigured ? "กรอกข้อมูลหลักครบแล้ว (LIFF ID + Access Token)" : "ยังกรอกข้อมูลไม่ครบ"}</span>
        </div>

        <Field label="LIFF ID">
          <input className={inputCls} value={form.liffId} onChange={e => set({ liffId: e.target.value })} placeholder="เช่น 1234567890-AbCdEfGh" />
        </Field>
        <p className="text-[11px] text-stone-400 -mt-2">สร้างได้ที่ LINE Developers Console → LIFF → Add</p>

        <Field label="LINE Official Account Basic ID">
          <input className={inputCls} value={form.oaBasicId} onChange={e => set({ oaBasicId: e.target.value })} placeholder="@thenur" />
        </Field>

        <Field label="Channel ID">
          <input className={inputCls} value={form.channelId} onChange={e => set({ channelId: e.target.value })} placeholder="เลข Channel ID" />
        </Field>

        <Field label="Channel Secret">
          <div className="flex gap-2">
            <input type={showSecret ? "text" : "password"} className={`${inputCls} flex-1`} value={form.channelSecret} onChange={e => set({ channelSecret: e.target.value })} placeholder="Channel Secret" />
            <button onClick={() => setShowSecret(v => !v)} className="text-stone-400 hover:text-stone-600 px-2"><Eye size={16} /></button>
          </div>
        </Field>

        <Field label="Channel Access Token (long-lived)">
          <div className="flex gap-2">
            <input type={showToken ? "text" : "password"} className={`${inputCls} flex-1 font-mono text-xs`} value={form.channelAccessToken} onChange={e => set({ channelAccessToken: e.target.value })} placeholder="Channel Access Token" />
            <button onClick={() => setShowToken(v => !v)} className="text-stone-400 hover:text-stone-600 px-2"><Eye size={16} /></button>
          </div>
        </Field>

        <Field label="ลิงก์เช็คคะแนน (สำหรับปักไว้ใน Rich Menu ของ LINE OA)">
          <input readOnly className={`${inputCls} bg-stone-50 text-stone-400`} value={form.liffId ? `https://liff.line.me/${form.liffId}` : "กรอก LIFF ID ก่อนเพื่อดูลิงก์"} />
        </Field>

        <Field label="Domain ของ backend (สำหรับคำนวณ Webhook URL — ยังไม่มีผลจริงจนกว่าจะมี backend)">
          <input className={inputCls} value={form.backendDomain || ""} onChange={e => set({ backendDomain: e.target.value })} placeholder="เช่น https://pos.thenuar.com" />
        </Field>
        <Field label="Webhook URL (เอาไปกรอกในหน้า Messaging API ของ LINE Developers Console)">
          <input readOnly className={`${inputCls} bg-stone-50 text-stone-400 font-mono text-xs`} value={form.backendDomain ? `${form.backendDomain.replace(/\/$/, "")}/webhook/line` : "กรอก domain ของ backend ก่อนเพื่อดูลิงก์"} />
        </Field>
        <p className="text-[11px] text-stone-400 -mt-2">ลิงก์นี้เป็นแค่ตัวอย่างไว้อ้างอิงสำหรับตอนสร้าง backend จริง (ตาม brief ที่ร่างไว้) — ต้องมี backend รับ webhook ที่ path นี้จริงก่อนถึงจะใช้งานได้</p>

        <div className="flex items-center gap-3 pt-2">
          <Btn onClick={save}>บันทึก</Btn>
          {saved && <span className="text-xs text-emerald-600">บันทึกแล้ว</span>}
        </div>
      </Card>

      <Card className="p-5 max-w-2xl mt-5">
        <div className="text-sm font-semibold text-stone-700 mb-2">ขั้นตอนเชื่อมต่อจริง (ทำนอกระบบนี้)</div>
        <ol className="text-xs text-stone-500 space-y-1.5 list-decimal list-inside">
          <li>สร้าง LINE Official Account ที่ LINE Official Account Manager</li>
          <li>เปิดใช้ Messaging API และสร้าง LIFF App ที่ LINE Developers Console</li>
          <li>คัดลอกค่า LIFF ID, Channel ID, Channel Secret, Channel Access Token มากรอกด้านบน</li>
          <li>ตั้งค่า Rich Menu ของ LINE OA ให้ปุ่ม "เช็คคะแนน" ลิงก์ไปที่ลิงก์ LIFF ด้านบน</li>
          <li>พัฒนา backend server (นอกอาร์ติแฟกต์นี้) รับการยืนยันตัวตนจาก LIFF SDK แล้วผูก LINE User ID เข้ากับสมาชิกในฐานข้อมูลจริงอัตโนมัติ</li>
        </ol>
      </Card>
    </div>
  );
}

/* =========================================================================
   PAGE: Log — Log Login
   ========================================================================= */

/* =========================================================================
   PAGE: ตั้งค่าระบบ — ธีมและการแสดงผล
   ========================================================================= */

function ThemeSettingsPage({ themeSettings, setThemeSettings }) {
  const PRESET_COLORS = ["#d97706", "#dc2626", "#059669", "#2563eb", "#7c3aed", "#db2777", "#0891b2"];

  return (
    <div>
      <PageHeader eyebrow="ตั้งค่าระบบ" title="ธีมและการแสดงผล" subtitle="ปรับโหมดมืด/สว่าง และสีธีมของระบบเอง" />

      <Card className="p-5 max-w-md mb-5">
        <label className="flex items-center justify-between cursor-pointer">
          <div>
            <div className="text-sm font-semibold text-stone-700">โหมดมืด (Dark mode)</div>
            <p className="text-xs text-stone-400 mt-1 max-w-xs">สลับพื้นหลัง/ตัวอักษรของทั้งระบบให้เป็นโทนมืด เหมาะกับการใช้งานในที่แสงน้อย</p>
          </div>
          <button onClick={() => setThemeSettings(prev => ({ ...prev, darkMode: !prev.darkMode }))}
            className={`relative w-11 h-6 rounded-full transition-colors flex-shrink-0 ml-4 ${themeSettings.darkMode ? "bg-emerald-500" : "bg-stone-300"}`}>
            <span className={`absolute left-0.5 top-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform ${themeSettings.darkMode ? "translate-x-5" : "translate-x-0"}`} />
          </button>
        </label>
      </Card>

      <Card className="p-5 max-w-md">
        <div className="text-sm font-semibold text-stone-700 mb-1 flex items-center gap-1.5"><Palette size={15} /> สีธีมหลัก</div>
        <p className="text-xs text-stone-400 mb-3 max-w-xs">ใช้แทนสีเหลืองอำพัน (amber) เดิมทั่วทั้งระบบ เช่น ปุ่มหลัก ป้ายไฮไลต์ และเส้นขอบเน้นสี</p>

        <div className="flex items-center gap-3 mb-4">
          <input type="color" className="w-12 h-10 rounded-md border border-stone-300 cursor-pointer" value={themeSettings.accentColor}
            onChange={e => setThemeSettings(prev => ({ ...prev, accentColor: e.target.value }))} />
          <input className={inputCls} value={themeSettings.accentColor} onChange={e => setThemeSettings(prev => ({ ...prev, accentColor: e.target.value }))} />
        </div>

        <div className="flex flex-wrap gap-2">
          {PRESET_COLORS.map(c => (
            <button key={c} onClick={() => setThemeSettings(prev => ({ ...prev, accentColor: c }))}
              className={`w-8 h-8 rounded-full border-2 ${themeSettings.accentColor === c ? "border-stone-800" : "border-transparent"}`}
              style={{ backgroundColor: c }} title={c} />
          ))}
        </div>

        <div className="mt-4 pt-4 border-t border-stone-200">
          <div className="text-xs text-stone-400 mb-2">ตัวอย่าง</div>
          <Btn>ปุ่มหลัก</Btn>
        </div>
      </Card>
    </div>
  );
}

/* =========================================================================
   PAGE: Log — All Activity
   ========================================================================= */

const ACTIVITY_CATEGORIES = ["ทั้งหมด", "ลบข้อมูล", "แก้ไขสถานะ", "การเงิน", "สต๊อก", "พนักงาน", "POS", "บัตรสะสมแต้ม", "ตั้งค่าระบบ", "เข้าสู่ระบบ", "อื่นๆ"];

function ActivityLogPage({ activityLog, currentBranchId, branches }) {
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [categoryFilter, setCategoryFilter] = useState("ทั้งหมด");
  const [query, setQuery] = useState("");
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  function branchLabel(e) {
    if (e.isCentral) return "ระบบส่วนกลาง";
    return branches?.find(b => b.id === e.branchId)?.name || "-";
  }

  const filtered = activityLog
    .filter(e => e.date.slice(0, 7) === monthFilter)
    .filter(e => categoryFilter === "ทั้งหมด" || e.category === categoryFilter)
    .filter(e => !effectiveBranchId || e.branchId === effectiveBranchId)
    .filter(e => !query || e.action.includes(query) || e.detail.includes(query) || e.userName.includes(query));

  const exportRows = filtered.map(e => ({
    "วันที่": fmtDate(e.date), "เวลา": e.time, "ผู้ใช้": e.userName,
    "สาขา/ระบบ": branchLabel(e), "หมวดหมู่": e.category, "การกระทำ": e.action, "รายละเอียด": e.detail,
  }));

  return (
    <div>
      <PageHeader eyebrow="Log" title="All Activity" subtitle="ประวัติการกระทำทั้งหมดในระบบ เก็บย้อนหลังสูงสุด 3 เดือน" />

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        <select className={`${inputCls} max-w-[160px]`} value={categoryFilter} onChange={e => setCategoryFilter(e.target.value)}>
          {ACTIVITY_CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
        </select>
        {!currentBranchId && branches && branches.length > 0 && (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        )}
        <div className="relative flex-1 min-w-[160px] max-w-xs">
          <Search size={14} className="absolute left-2.5 top-1/2 -translate-y-1/2 text-stone-400" />
          <input className={`${inputCls} pl-8`} value={query} onChange={e => setQuery(e.target.value)} placeholder="ค้นหาการกระทำ/ผู้ใช้" />
        </div>
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`activity-log-${monthFilter}`} sheetName="Activity" />
        </div>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">วันที่/เวลา</th>
                <th className="px-4 py-3 font-medium">ผู้ใช้</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา/ระบบ</th>}
                <th className="px-4 py-3 font-medium">หมวดหมู่</th>
                <th className="px-4 py-3 font-medium">การกระทำ</th>
                <th className="px-4 py-3 font-medium">รายละเอียด</th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(e => (
                <tr key={e.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 text-stone-400">{fmtDate(e.date)}<div className="text-[11px]">{e.time} น.</div></td>
                  <td className="px-4 py-3 text-stone-700">{e.userName}</td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchLabel(e)}</td>}
                  <td className="px-4 py-3"><span className="text-[11px] px-2 py-0.5 rounded-full bg-stone-100 text-stone-600">{e.category}</span></td>
                  <td className="px-4 py-3 font-medium text-stone-800">{e.action}</td>
                  <td className="px-4 py-3 text-stone-500">{e.detail || "-"}</td>
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 5 : 6} className="px-4 py-10 text-center text-stone-400">ไม่มีประวัติการกระทำในเดือนนี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-4">
        หมายเหตุ: ระบบเก็บ log เฉพาะการกระทำสำคัญที่อาจกระทบข้อมูล (การลบ, การเปลี่ยนสถานะ, การเงิน, การเข้าสู่ระบบ ฯลฯ) ไม่ได้บันทึกทุกคลิกในระบบ และเก็บย้อนหลังได้สูงสุด 3 เดือนเท่านั้น ข้อมูลเก่ากว่านั้นจะถูกลบทิ้งอัตโนมัติ
      </p>
    </div>
  );
}

function LoginLogPage({ loginLog, currentBranchId, branches }) {
  const [monthFilter, setMonthFilter] = useState(new Date().toISOString().slice(0, 7));
  const [centralBranchFilter, setCentralBranchFilter] = useState(""); // only used/shown in Central mode
  const effectiveBranchId = currentBranchId || centralBranchFilter || null;
  function branchLabel(l) {
    if (l.isCentral) return "ระบบส่วนกลาง";
    return branches?.find(b => b.id === l.branchId)?.name || "-";
  }

  const filtered = loginLog
    .filter(l => !monthFilter || l.date.slice(0, 7) === monthFilter)
    .filter(l => !effectiveBranchId || l.branchId === effectiveBranchId);

  const exportRows = filtered.map(l => ({
    "วันที่": fmtDate(l.date), "เวลา": l.time, "ชื่อผู้ใช้": l.userName,
    "ประเภท": l.userType === "owner" ? "เจ้าของร้าน" : "พนักงาน", "ตำแหน่ง": l.positionName, "สาขา/ระบบ": branchLabel(l),
  }));

  return (
    <div>
      <PageHeader eyebrow="Log" title="Log Login" subtitle="ประวัติการเข้าสู่ระบบของพนักงานและเจ้าของร้าน" />

      <div className="flex flex-wrap items-center gap-3 mb-5">
        <input type="month" className={`${inputCls} max-w-[160px]`} value={monthFilter} onChange={e => setMonthFilter(e.target.value)} />
        {!currentBranchId && branches && branches.length > 0 && (
          <select className={`${inputCls} max-w-[180px]`} value={centralBranchFilter} onChange={e => setCentralBranchFilter(e.target.value)}>
            <option value="">ทุกสาขา</option>
            {branches.filter(b => b.active).map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
          </select>
        )}
        <div className="ml-auto">
          <ExportButton data={exportRows} filename={`login-log-${monthFilter}`} sheetName="LoginLog" />
        </div>
      </div>

      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="text-left text-xs text-stone-400 uppercase tracking-wide border-b border-stone-200">
                <th className="px-4 py-3 font-medium">วันที่</th>
                <th className="px-4 py-3 font-medium">เวลา</th>
                <th className="px-4 py-3 font-medium">ชื่อผู้ใช้</th>
                <th className="px-4 py-3 font-medium">ประเภท</th>
                <th className="px-4 py-3 font-medium">ตำแหน่ง</th>
                {!effectiveBranchId && <th className="px-4 py-3 font-medium">สาขา/ระบบ</th>}
              </tr>
            </thead>
            <tbody>
              {filtered.map(l => (
                <tr key={l.id} className="border-b border-stone-100 last:border-0 hover:bg-stone-50">
                  <td className="px-4 py-3 text-stone-400">{fmtDate(l.date)}</td>
                  <td className="px-4 py-3 font-mono text-stone-700">{l.time}</td>
                  <td className="px-4 py-3 font-medium text-stone-800">{l.userName}</td>
                  <td className="px-4 py-3">
                    <span className={`text-xs px-2 py-0.5 rounded border font-medium ${l.userType === "owner" ? "bg-amber-50 text-amber-700 border-amber-300" : "bg-sky-50 text-sky-700 border-sky-300"}`}>
                      {l.userType === "owner" ? "เจ้าของร้าน" : "พนักงาน"}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-stone-500">{l.positionName}</td>
                  {!effectiveBranchId && <td className="px-4 py-3 text-stone-500">{branchLabel(l)}</td>}
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr><td colSpan={effectiveBranchId ? 5 : 6} className="px-4 py-10 text-center text-stone-400">ยังไม่มีประวัติการเข้าสู่ระบบในเดือนนี้</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </Card>
      <p className="text-xs text-stone-400 mt-3">
        บันทึกอัตโนมัติทุกครั้งที่มีการกรอก PIN เข้าสู่ระบบสำเร็จ
      </p>
    </div>
  );
}

/* =========================================================================
   GENERIC BACKEND-COLLECTION SYNC HOOK
   =========================================================================
   Used by RestaurantBackOffice for every piece of app state that goes
   through the generic /api/collections store (members, promotions, stock,
   finance, sales history/reports, HR extras, misc settings, logs — see
   GENERIC_COLLECTIONS inside RestaurantBackOffice). Same skip-first-change
   pattern as the bespoke sync effects for menu/categories/staff/etc.: do
   nothing until the bootstrap load has finished, then skip exactly the one
   change that load itself caused, then push every real edit after that.
   Called a fixed number of times in the same order on every render (never
   conditionally), so this doesn't violate the rules of hooks despite being
   "generated" rather than hand-written per key.
   ========================================================================= */
function useGenericCollectionSync(key, value, dataLoaded, skipFirstSyncRef) {
  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current[key]) { skipFirstSyncRef.current[key] = false; return; }
    api.saveCollection(key, value).catch(err => console.error(`ซิงก์ ${key} ไม่สำเร็จ:`, err));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value, dataLoaded]);
}

/* =========================================================================
   APP SHELL
   ========================================================================= */

export default function RestaurantBackOffice() {
  const [active, setActive] = useState("dashboard");
  // Set by OpenTablesPage's "ตรวจสอบสลิป & ชำระเงิน" button so staff can jump
  // straight into POS Order's payment view for a specific table (the one
  // place that already has the slip-verification banner and the full
  // confirm/close-table flow) instead of hunting for that table manually
  // inside the POS Order table grid. PosOrderPage consumes this once (via a
  // useEffect keyed on it) then we clear it back to null so navigating to
  // "pos" normally afterwards doesn't keep re-jumping to the same table.
  const [jumpToTablePayment, setJumpToTablePayment] = useState(null); // tableId | null
  const [currentUser, setCurrentUser] = useState(null); // { type: "owner" } | { type: "staff", staffId, name, positionId }
  // Customer self-service (เช็คคะแนนของฉัน) at thenuar.com/points — detect the
  // URL path so this works as its own standalone link (e.g. as a LIFF
  // endpoint URL), not just a button inside the app.
  const [customerMode, setCustomerMode] = useState(() => typeof window !== "undefined" && window.location.pathname.replace(/\/$/, "") === "/points");
  // Staff check-in/check-out at thenuar.com/checkin — same pattern as /points,
  // /job and /register: detect the URL path so this works as its own
  // standalone link (e.g. pinned in a LINE OA, or sent in a staff group chat),
  // not just a button reachable from inside the login page.
  const [attendanceMode, setAttendanceMode] = useState(() => typeof window !== "undefined" && window.location.pathname.replace(/\/$/, "") === "/checkin");
  // Public job listing at thenuar.com/job — detect the URL path so this works
  // as a real standalone link once deployed, not just a button inside the app.
  const [jobsMode, setJobsMode] = useState(() => typeof window !== "undefined" && window.location.pathname.replace(/\/$/, "") === "/job");
  // Mobile ordering at thenuar.com/order?table=T3&token=... (scanned from the
  // table's QR code) — detect the path + query params once on load.
  const [mobileOrderParams] = useState(() => {
    if (typeof window === "undefined" || window.location.pathname.replace(/\/$/, "") !== "/order") return null;
    const params = new URLSearchParams(window.location.search);
    const table = params.get("table");
    const token = params.get("token");
    return table && token ? { table, token } : null;
  });
  // Public member self-registration at thenuar.com/register — same pattern as
  // /job and /points, detected via URL path so it works as a standalone link.
  const [registerMode, setRegisterMode] = useState(() => typeof window !== "undefined" && window.location.pathname.replace(/\/$/, "") === "/register");
  const [loginLog, setLoginLog] = useState([]);
  const [activityLog, setActivityLog] = useState([]);
  // Records one entry in the "All Activity" log and prunes anything older
  // than 3 months so the log doesn't grow unbounded.
  function logActivity({ action, category, detail = "", branchId = currentBranchId }) {
    const now = new Date();
    const cutoff = new Date(now); cutoff.setMonth(cutoff.getMonth() - 3);
    const cutoffStr = cutoff.toISOString().slice(0, 10);
    const who = currentUser?.type === "staff"
      ? (staff.find(s => s.id === currentUser.staffId)?.displayName || currentUser.name)
      : currentUser?.type === "owner" ? (ownerProfile?.name || "เจ้าของร้าน") : "-";
    setActivityLog(prev => [
      {
        id: "act" + Date.now() + Math.random().toString(36).slice(2, 6),
        date: now.toISOString().slice(0, 10),
        time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
        userType: currentUser?.type || "-", userName: who,
        branchId: branchId || null, isCentral: !!currentUser?.isCentral,
        category, action, detail,
      },
      ...prev,
    ].filter(e => e.date >= cutoffStr));
  }
  const [tables, setTables] = useState(TABLE_SEED);
  const [zones, setZones] = useState(ZONE_SEED);
  const [categories, setCategories] = useState(CATEGORY_SEED);
  const [menu, setMenu] = useState(MENU_SEED);
  const [members, setMembers] = useState(MEMBER_SEED);
  const [tiers, setTiers] = useState(TIER_SEED);
  const [rewards, setRewards] = useState(REWARD_SEED);
  const [history, setHistory] = useState(HISTORY_SEED);
  const [orderHistory, setOrderHistory] = useState(ORDER_HISTORY_SEED);
  const [promotions, setPromotions] = useState(PROMO_SEED);
  const [kitchenFood, setKitchenFood] = useState(KITCHEN_FOOD_SEED);
  const [kitchenDrinks, setKitchenDrinks] = useState(KITCHEN_DRINK_SEED);
  const [storeInfo, setStoreInfo] = useState(STORE_INFO_SEED);
  const [ownerProfile, setOwnerProfile] = useState(OWNER_PROFILE_SEED);
  const [themeSettings, setThemeSettings] = useState({ darkMode: false, accentColor: "#d97706" });
  const [lineOaSettings, setLineOaSettings] = useState({ liffId: "", oaBasicId: "", channelId: "", channelSecret: "", channelAccessToken: "", backendDomain: "" });
  const [slipSettings, setSlipSettings] = useState(SLIP_SETTINGS_SEED);
  const [channels, setChannels] = useState(CHANNEL_SEED);
  const [branches, setBranches] = useState(BRANCH_SEED);
  const [currentBranchId, setCurrentBranchId] = useState(BRANCH_SEED.find(b => b.active)?.id || "");
  const [paymentSettings, setPaymentSettings] = useState(PAYMENT_SETTINGS_SEED);
  const [printers, setPrinters] = useState(PRINTER_SEED);
  const [printAgentSettings, setPrintAgentSettings] = useState({ default: { host: "localhost", port: "9200" } }); // keyed by branchId, plus "default" fallback
  const [emailReceiptSettings, setEmailReceiptSettings] = useState({
    subject: "ใบเสร็จจาก {ชื่อร้าน}",
    body: "เรียนคุณ {ชื่อลูกค้า}\n\nขอบคุณที่ใช้บริการ {ชื่อร้าน} ครับ/ค่ะ\nเลขที่ใบเสร็จ: {เลขที่ใบเสร็จ}\nยอดรวมทั้งสิ้น: {ยอดรวม} บาท\n\nขอบคุณที่ใช้บริการ",
  });
  useEffect(() => {
    const effective = printAgentSettings[currentBranchId] || printAgentSettings.default;
    setPrintAgentConnection(effective?.host, effective?.port);
  }, [printAgentSettings, currentBranchId]);
  const [soundSettings, setSoundSettings] = useState(SOUND_SETTINGS_SEED);
  const [positions, setPositions] = useState(POSITION_SEED);
  const [staff, setStaff] = useState(STAFF_SEED);
  const [attendance, setAttendance] = useState(ATTENDANCE_SEED);
  const [attendanceSettings, setAttendanceSettings] = useState(ATTENDANCE_SETTINGS_SEED);
  const [workSchedules, setWorkSchedules] = useState(WORK_SCHEDULE_SEED);
  const [lateAbsentPolicy, setLateAbsentPolicy] = useState(LATE_ABSENT_POLICY_SEED);
  const [daysOff, setDaysOff] = useState(DAYS_OFF_SEED);
  const [leaveTypes, setLeaveTypes] = useState(LEAVE_TYPE_SEED);
  const [payrollSalesInputs, setPayrollSalesInputs] = useState({});
  const [jobs, setJobs] = useState(JOB_SEED);
  const [applicants, setApplicants] = useState(APPLICANT_SEED);
  const [stockItems, setStockItems] = useState(STOCK_ITEM_SEED);
  const [wasteLog, setWasteLog] = useState(WASTE_LOG_SEED);
  const [stockCategories, setStockCategories] = useState(STOCK_CATEGORY_SEED);
  const [stockUnits, setStockUnits] = useState(STOCK_UNIT_SEED);
  const [vendors, setVendors] = useState(VENDOR_SEED);
  const [purchaseOrders, setPurchaseOrders] = useState(PURCHASE_ORDER_SEED);
  const [goodsReceipts, setGoodsReceipts] = useState(GOODS_RECEIPT_SEED);
  const [vatFilings, setVatFilings] = useState([]);
  const [financeAccounts, setFinanceAccounts] = useState(FINANCE_ACCOUNT_SEED);
  const [salesShifts, setSalesShifts] = useState(SALES_SHIFT_SEED);
  const [expenses, setExpenses] = useState(EXPENSE_SEED);
  const [posSessions, setPosSessions] = useState({});
  const [cancelHistory, setCancelHistory] = useState(CANCEL_HISTORY_SEED);
  // Bridges the customer self-service LIFF page to POS: when a customer redeems
  // a reward themselves, it creates a code here; staff enters that code at
  // checkout to actually apply the discount/free item to the bill.
  const [pendingRedemptions, setPendingRedemptions] = useState([]);
  const [pointRateSettings, setPointRateSettings] = useState({ baht: 10 });
  const [expandedNav, setExpandedNav] = useState({ slipDesign: true });
  const [selectedGroup, setSelectedGroup] = useState(NAV[0].group);
  const [panelOpen, setPanelOpen] = useState(true);
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  const [isTouchDevice, setIsTouchDevice] = useState(false);
  const mainRef = useRef(null);

  /* =======================================================================
     BACKEND WIRING — menu, categories, staff, positions, tables, owner
     profile, attendance (settings + records), POS order sessions (cart,
     sent items, bill total, promotions, payment...), and kitchen tickets
     all now live in the real MariaDB database via thenuar-backend, instead
     of only the in-memory SEED constants above. Those SEED constants still
     act as the initial state, so the app keeps working (in local/offline
     demo mode) even if the API is unreachable — this effect just overwrites
     them with the real saved data once it loads, and the sync effects
     further below push any local edits back to the database.

     For posSessions / kitchenFood / kitchenDrinks specifically: all of
     PosOrderPage's and KitchenBoard's existing logic (adding to cart,
     applying promotions, sending to kitchen, changing a ticket's status,
     clearing done tickets, taking payment) is UNCHANGED — it still just
     calls setSessions / setKitchenFood / setKitchenDrinks exactly as
     before. The sync effects below simply mirror whatever those functions
     produce to the database, the same whole-collection pattern used for
     menu/categories/staff/tables above.
     ========================================================================= */
  const [dataLoaded, setDataLoaded] = useState(false);
  const [apiOffline, setApiOffline] = useState(false);

  // The ~40 other pieces of app state (members/loyalty, promotions, stock,
  // finance, sales history/reports, HR extras, misc settings, logs) that
  // don't have their own dedicated table — all stored generically via
  // routes/collections.js (see api.getAllCollections/saveCollection).
  // "arr: true" means treat an empty/missing value from the server as "not
  // saved yet" and keep the local SEED data instead of wiping it out.
  // Declared before skipFirstSyncRef below so its keys can be included in
  // that ref's initial value (see the comment there for why that matters).
  const GENERIC_COLLECTIONS = [
    { key: "zones", set: setZones, arr: true },
    { key: "members", set: setMembers, arr: true },
    { key: "tiers", set: setTiers, arr: true },
    { key: "rewards", set: setRewards, arr: true },
    { key: "history", set: setHistory, arr: true },
    { key: "orderHistory", set: setOrderHistory, arr: true },
    { key: "promotions", set: setPromotions, arr: true },
    { key: "storeInfo", set: setStoreInfo, arr: false },
    { key: "themeSettings", set: setThemeSettings, arr: false },
    { key: "lineOaSettings", set: setLineOaSettings, arr: false },
    { key: "slipSettings", set: setSlipSettings, arr: false },
    { key: "paymentSettings", set: setPaymentSettings, arr: false },
    { key: "printers", set: setPrinters, arr: true },
    { key: "printAgentSettings", set: setPrintAgentSettings, arr: false },
    { key: "emailReceiptSettings", set: setEmailReceiptSettings, arr: false },
    { key: "soundSettings", set: setSoundSettings, arr: false, merge: (v) => ({
        newOrder: { ...SOUND_SETTINGS_SEED.newOrder, ...(v && typeof v.newOrder === "object" ? v.newOrder : {}) },
        callStaff: { ...SOUND_SETTINGS_SEED.callStaff, ...(v && typeof v.callStaff === "object" ? v.callStaff : {}) },
      }) },
    { key: "workSchedules", set: setWorkSchedules, arr: true },
    { key: "lateAbsentPolicy", set: setLateAbsentPolicy, arr: false },
    { key: "daysOff", set: setDaysOff, arr: true },
    { key: "leaveTypes", set: setLeaveTypes, arr: true },
    { key: "payrollSalesInputs", set: setPayrollSalesInputs, arr: false },
    { key: "jobs", set: setJobs, arr: true },
    { key: "applicants", set: setApplicants, arr: true },
    { key: "stockItems", set: setStockItems, arr: true },
    { key: "wasteLog", set: setWasteLog, arr: true },
    { key: "stockCategories", set: setStockCategories, arr: true },
    { key: "stockUnits", set: setStockUnits, arr: true },
    { key: "vendors", set: setVendors, arr: true },
    { key: "purchaseOrders", set: setPurchaseOrders, arr: true },
    { key: "goodsReceipts", set: setGoodsReceipts, arr: true },
    { key: "vatFilings", set: setVatFilings, arr: true },
    { key: "financeAccounts", set: setFinanceAccounts, arr: true },
    { key: "salesShifts", set: setSalesShifts, arr: true },
    { key: "expenses", set: setExpenses, arr: true },
    { key: "cancelHistory", set: setCancelHistory, arr: true },
    { key: "pendingRedemptions", set: setPendingRedemptions, arr: true },
    { key: "pointRateSettings", set: setPointRateSettings, arr: false },
    { key: "loginLog", set: setLoginLog, arr: true },
    { key: "activityLog", set: setActivityLog, arr: true },
  ];

  // Guards against the initial load (setCategories(fetched), etc.) itself
  // triggering an immediate, pointless sync-it-right-back-to-the-server call.
  //
  // FIX (previously a real data-loss bug): every key here MUST start at
  // `true`. branches/channels/tables used to start at `false` on the theory
  // that they'd only ever flip to `true` once the bootstrap fetch below
  // actually set them — but the bootstrap fetch is a single `Promise.all`
  // covering ~15 API calls at once; if ANY one of them fails (a slow
  // request, the backend mid-restart right after a deploy, a brief network
  // hiccup), the whole thing rejects and NONE of the setters ever run. Local
  // state then stays at its hardcoded SEED value, `dataLoaded` still flips
  // to `true` in the `finally` block below, and every sync effect fires —
  // for any key whose flag was `false`/unset, that immediately PUSHES the
  // untouched SEED value to the server, e.g. silently re-inserting the
  // default seed branch even though the real branch had already been edited
  // or deleted. The exact same gap existed for every one of the ~40
  // GENERIC_COLLECTIONS keys below (their flags start `undefined`, which is
  // just as falsy as `false`) — so a single failed bootstrap call risked
  // overwriting members/promotions/stock/finance/settings/logs too, not
  // just branches. Starting every key at `true` means a failed/partial
  // bootstrap load can never auto-push anything; the tradeoff is that the
  // very first genuine edit made right after such a failure is skipped once
  // (the flag was never legitimately consumed by a successful load) — a
  // one-time missed sync is far safer than silently resurrecting deleted
  // data on every deploy/restart.
  const skipFirstSyncRef = useRef({
    categories: true, menu: true, staff: true, positions: true,
    ownerProfile: true, attendanceSettings: true,
    posSessions: true, kitchenFood: true, kitchenDrinks: true,
    branches: true, channels: true, tables: true,
    ...Object.fromEntries(GENERIC_COLLECTIONS.map(c => [c.key, true])),
  });

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const [
          branchesData, channelsData, categoriesData, menuData, positionsData, staffData,
          ownerProfileData, tablesData, attendanceSettingsData, attendanceData,
          posSessionsData, kitchenFoodData, kitchenDrinksData, allCollections,
        ] = await Promise.all([
          api.getBranches(), api.getChannels(), api.getCategories(), api.getMenu(),
          api.getPositions(), api.getStaff(), api.getOwnerProfile(), api.getTables(),
          api.getAttendanceSettings(), api.getAttendance(),
          api.getPosSessions(), api.getKitchenTickets("food"), api.getKitchenTickets("drink"),
          api.getAllCollections(),
        ]);
        if (cancelled) return;
        // NOTE: this used to check `?.length` (truthy only for a NON-EMPTY
        // array), meaning "the user deleted every row" and "this was never
        // saved yet" both looked like "nothing from the server" and fell back
        // to the hardcoded SEED data — which then got synced right back to
        // the database, silently undoing real deletions on the very next
        // reload/login. Checking Array.isArray(...) instead only falls back
        // to SEED when the server call truly returned nothing (API offline/
        // failed), and correctly accepts a real, intentionally-empty array.
        if (Array.isArray(branchesData)) { setBranches(branchesData); skipFirstSyncRef.current.branches = true; }
        if (Array.isArray(channelsData)) { setChannels(channelsData); skipFirstSyncRef.current.channels = true; }
        setCategories(categoriesData || []);
        setMenu(menuData || []);
        setPositions(positionsData || []);
        setStaff(staffData || []);
        if (ownerProfileData) setOwnerProfile(ownerProfileData);
        if (Array.isArray(tablesData)) { setTables(tablesData); skipFirstSyncRef.current.tables = true; }
        if (attendanceSettingsData) setAttendanceSettings(attendanceSettingsData);
        setAttendance(attendanceData || []);
        setPosSessions(posSessionsData || {});
        setKitchenFood(kitchenFoodData || []);
        setKitchenDrinks(kitchenDrinksData || []);

        for (const { key, set, arr, merge } of GENERIC_COLLECTIONS) {
          const value = allCollections ? allCollections[key] : undefined;
          // Same fix as above: arr collections accept a real (possibly
          // empty) array from the server; they only fall back to SEED data
          // when the server genuinely returned nothing for that key.
          const hasValue = arr ? Array.isArray(value) : value != null && typeof value === "object";
          if (hasValue) {
            // BUG FIX: an "arr: false" collection is a single settings
            // object with known sub-keys (e.g. soundSettings.newOrder /
            // .callStaff). Loading a value saved BEFORE a new sub-key was
            // introduced (e.g. "callStaff" added after "newOrder" already
            // existed) would previously call set(value) and wipe out that
            // missing sub-key entirely, leaving it undefined — any page
            // that renders it (SoundEventEditor) then crashes the whole
            // React tree with a blank white screen. `merge`, when provided,
            // fills in defaults for any sub-key missing from the saved
            // value instead of replacing the object outright.
            set(merge ? merge(value) : value);
            skipFirstSyncRef.current[key] = true;
          }
        }
      } catch (err) {
        // API unreachable (offline dev preview, backend not deployed yet,
        // network hiccup) — keep running on the local SEED data untouched.
        console.error("โหลดข้อมูลจากเซิร์ฟเวอร์ไม่สำเร็จ ใช้ข้อมูลตัวอย่างในเครื่องแทน:", err);
        if (!cancelled) setApiOffline(true);
      } finally {
        if (!cancelled) setDataLoaded(true);
      }
    })();
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Whole-collection sync effects — fire the API's /sync (or, for the
  // single-object owner profile and attendance settings, a plain PUT)
  // whenever the corresponding local state changes, skipping the one-time
  // change caused by the initial load itself. If the API call fails (e.g.
  // connection dropped), the edit still stays applied locally; it just
  // won't have persisted to the database until the next successful sync.
  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.categories) { skipFirstSyncRef.current.categories = false; return; }
    api.syncCategories(categories).catch(err => console.error("ซิงก์หมวดหมู่ไม่สำเร็จ:", err));
  }, [categories, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.menu) { skipFirstSyncRef.current.menu = false; return; }
    api.syncMenu(menu).catch(err => console.error("ซิงก์เมนูไม่สำเร็จ:", err));
  }, [menu, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.staff) { skipFirstSyncRef.current.staff = false; return; }
    api.syncStaff(staff).catch(err => console.error("ซิงก์พนักงานไม่สำเร็จ:", err));
  }, [staff, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.positions) { skipFirstSyncRef.current.positions = false; return; }
    api.syncPositions(positions).catch(err => console.error("ซิงก์ตำแหน่งไม่สำเร็จ:", err));
  }, [positions, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.tables) { skipFirstSyncRef.current.tables = false; return; }
    api.syncTables(tables).catch(err => console.error("ซิงก์โต๊ะไม่สำเร็จ:", err));
  }, [tables, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.ownerProfile) { skipFirstSyncRef.current.ownerProfile = false; return; }
    api.saveOwnerProfile(ownerProfile).catch(err => console.error("บันทึกโปรไฟล์เจ้าของร้านไม่สำเร็จ:", err));
  }, [ownerProfile, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.attendanceSettings) { skipFirstSyncRef.current.attendanceSettings = false; return; }
    api.saveAttendanceSettings(attendanceSettings).catch(err => console.error("บันทึกการตั้งค่าลงเวลาไม่สำเร็จ:", err));
  }, [attendanceSettings, dataLoaded]);

  // posSessions covers everything happening on the POS order screen — cart
  // edits, promotions/redemptions, sending to kitchen, editing sent items,
  // linking a member, taking payment and closing the table out. One sync
  // effect on the whole object covers all of it without touching any of
  // PosOrderPage's/ReservationsPage's/MobileOrderPage's own logic.
  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.posSessions) { skipFirstSyncRef.current.posSessions = false; return; }
    api.syncPosSessions(posSessions).catch(err => console.error("ซิงก์ออเดอร์ไม่สำเร็จ:", err));
  }, [posSessions, dataLoaded]);

  // kitchenFood / kitchenDrinks: covers new tickets from "ส่งครัว", status
  // changes (queued → cooking → done) from KitchenBoard's own buttons, and
  // the PIN-gated "เคลียร์รายการ" clear-done action — synced separately per
  // board so a change on one board can never touch the other's tickets.
  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.kitchenFood) { skipFirstSyncRef.current.kitchenFood = false; return; }
    api.syncKitchenTickets("food", kitchenFood).catch(err => console.error("ซิงก์ตั๋วครัวอาหารไม่สำเร็จ:", err));
  }, [kitchenFood, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.kitchenDrinks) { skipFirstSyncRef.current.kitchenDrinks = false; return; }
    api.syncKitchenTickets("drink", kitchenDrinks).catch(err => console.error("ซิงก์ตั๋วครัวเครื่องดื่มไม่สำเร็จ:", err));
  }, [kitchenDrinks, dataLoaded]);

  // Live pickup for customer self-orders (thenuar.com/order?table=...): a
  // customer's phone now saves straight through atomic single-table/single-
  // ticket endpoints (see MobileOrderPage), but a staff terminal that's
  // already open only ever fetched posSessions/kitchenFood/kitchenDrinks
  // ONCE, at page load — it would otherwise never show a new self-order
  // until someone manually refreshes the whole page. This polls the server
  // periodically and folds in only what's genuinely new (a longer sentItems
  // list, a call-staff flag, a new ticket id) via mergeSessionFromServer /
  // id-based dedup — it never removes or reverts anything this tab already
  // has locally, so it can't clobber an in-progress local edit. Skipped
  // entirely on the customer's own MobileOrderPage — it doesn't need this.
  useEffect(() => {
    if (!dataLoaded || mobileOrderParams) return;
    const id = setInterval(async () => {
      try {
        const [remoteSessions, remoteFood, remoteDrinks] = await Promise.all([
          api.getPosSessions(), api.getKitchenTickets("food"), api.getKitchenTickets("drink"),
        ]);
        setPosSessions(prev => {
          let changed = false;
          const next = { ...prev };
          for (const tableId of Object.keys(remoteSessions || {})) {
            const merged = mergeSessionFromServer(prev[tableId], remoteSessions[tableId]);
            if (merged !== prev[tableId]) { next[tableId] = merged; changed = true; }
          }
          if (!changed) return prev;
          skipFirstSyncRef.current.posSessions = true; // just mirroring the server — nothing new to push back
          return next;
        });
        setKitchenFood(prev => {
          const localIds = new Set(prev.map(t => t.id));
          const fresh = (remoteFood || []).filter(t => !localIds.has(t.id));
          if (!fresh.length) return prev;
          skipFirstSyncRef.current.kitchenFood = true;
          return [...prev, ...fresh];
        });
        setKitchenDrinks(prev => {
          const localIds = new Set(prev.map(t => t.id));
          const fresh = (remoteDrinks || []).filter(t => !localIds.has(t.id));
          if (!fresh.length) return prev;
          skipFirstSyncRef.current.kitchenDrinks = true;
          return [...prev, ...fresh];
        });
      } catch (err) {
        console.error("ตรวจสอบออเดอร์ใหม่จากลูกค้าไม่สำเร็จ:", err);
      }
    }, 7000);
    return () => clearInterval(id);
  }, [dataLoaded, mobileOrderParams]);

  // Sound alert when a customer calls staff from their own phone (the poll
  // above is what actually brings a new callStaffRequested flag into this
  // tab's posSessions — this effect just watches for that specific flag
  // flipping false→true per table and plays the configured sound). Runs at
  // the persistent app-shell level (not inside OpenTablesPage/PosOrderPage),
  // so it fires no matter which page staff currently have open — same
  // reasoning as the "call-staff-notify-yt-frame" iframe rendered in the
  // main return below. `prevCallStaffRef` starts as null so the very first
  // snapshot (right after bootstrap load) never itself triggers a sound —
  // only genuinely NEW call-staff requests seen after that do.
  const prevCallStaffRef = useRef(null);
  useEffect(() => {
    if (!dataLoaded || mobileOrderParams) return;
    const snapshot = {};
    for (const tableId of Object.keys(posSessions || {})) {
      snapshot[tableId] = !!posSessions[tableId]?.callStaffRequested;
    }
    if (prevCallStaffRef.current) {
      const hasNewCall = Object.keys(snapshot).some(tableId => snapshot[tableId] && !prevCallStaffRef.current[tableId]);
      if (hasNewCall && shouldHearAlert(soundSettings?.callStaff, currentUser)) {
        playAlertSound(soundSettings?.callStaff, "ลูกค้าเรียกพนักงาน", "call-staff-notify-yt-frame");
      }
    }
    prevCallStaffRef.current = snapshot;
  }, [posSessions, dataLoaded, mobileOrderParams, soundSettings, currentUser]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.branches) { skipFirstSyncRef.current.branches = false; return; }
    api.syncBranches(branches).catch(err => console.error("ซิงก์สาขาไม่สำเร็จ:", err));
  }, [branches, dataLoaded]);

  useEffect(() => {
    if (!dataLoaded) return;
    if (skipFirstSyncRef.current.channels) { skipFirstSyncRef.current.channels = false; return; }
    api.syncChannels(channels).catch(err => console.error("ซิงก์ช่องทางขายไม่สำเร็จ:", err));
  }, [channels, dataLoaded]);

  // Every other piece of app state (members/loyalty, promotions, stock,
  // finance, sales history/reports, HR extras, misc settings, logs) syncs
  // through the same generic collections store, one call per key — see
  // GENERIC_COLLECTIONS above for the full list. Each of these is a single
  // useEffect exactly like the ones above, just generated instead of
  // hand-written 39 times over, since they're all mechanically identical:
  // wait for dataLoaded, skip the bootstrap-load's own change once, then
  // PUT the current value to routes/collections.js on every real edit.
  useGenericCollectionSync("zones", zones, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("members", members, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("tiers", tiers, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("rewards", rewards, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("history", history, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("orderHistory", orderHistory, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("promotions", promotions, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("storeInfo", storeInfo, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("themeSettings", themeSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("lineOaSettings", lineOaSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("slipSettings", slipSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("paymentSettings", paymentSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("printers", printers, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("printAgentSettings", printAgentSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("emailReceiptSettings", emailReceiptSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("soundSettings", soundSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("workSchedules", workSchedules, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("lateAbsentPolicy", lateAbsentPolicy, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("daysOff", daysOff, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("leaveTypes", leaveTypes, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("payrollSalesInputs", payrollSalesInputs, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("jobs", jobs, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("applicants", applicants, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("stockItems", stockItems, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("wasteLog", wasteLog, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("stockCategories", stockCategories, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("stockUnits", stockUnits, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("vendors", vendors, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("purchaseOrders", purchaseOrders, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("goodsReceipts", goodsReceipts, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("vatFilings", vatFilings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("financeAccounts", financeAccounts, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("salesShifts", salesShifts, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("expenses", expenses, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("cancelHistory", cancelHistory, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("pendingRedemptions", pendingRedemptions, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("pointRateSettings", pointRateSettings, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("loginLog", loginLog, dataLoaded, skipFirstSyncRef);
  useGenericCollectionSync("activityLog", activityLog, dataLoaded, skipFirstSyncRef);

  useEffect(() => {
    // A coarse pointer (finger) means a real phone/tablet — a mouse/trackpad
    // (fine pointer) means a desktop browser, even if its window is narrow.
    const mq = window.matchMedia("(pointer: coarse)");
    setIsTouchDevice(mq.matches);
    const handler = e => setIsTouchDevice(e.matches);
    mq.addEventListener ? mq.addEventListener("change", handler) : mq.addListener(handler);
    return () => {
      mq.removeEventListener ? mq.removeEventListener("change", handler) : mq.removeListener(handler);
    };
  }, []);

  function hasPermission(key) {
    if (!currentUser) return false;
    if (currentUser.type === "owner") return true;
    const position = positions.find(p => p.id === currentUser.positionId);
    return !!position?.permissions?.includes(key);
  }
  function firstAllowedPageFor(user) {
    if (!user) return null;
    if (user.type === "owner") return "dashboard";
    const position = positions.find(p => p.id === user.positionId);
    const allowed = PERMISSION_OPTIONS.find(opt => position?.permissions?.includes(opt.key));
    return allowed?.key || null;
  }
  function handleLogin(user) {
    setCurrentUser(user);
    setCurrentBranchId(user.branchId ?? null);
    const position = user.type === "staff" ? positions.find(p => p.id === user.positionId) : null;
    const currentlyAllowed = user.type === "owner" || position?.permissions?.includes(active);
    if (!currentlyAllowed) {
      setActive(firstAllowedPageFor(user) || "dashboard");
    }
    const now = new Date();
    setLoginLog(prev => [{
      id: "ll" + Date.now(),
      date: now.toISOString().slice(0, 10),
      time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
      userType: user.type, userName: user.name,
      positionName: position?.name || (user.type === "owner" ? "เจ้าของร้าน" : "-"),
      branchId: user.branchId || null, isCentral: !!user.isCentral,
    }, ...prev]);
    setActivityLog(prev => [{
      id: "act" + Date.now(), date: now.toISOString().slice(0, 10),
      time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
      userType: user.type, userName: user.name, branchId: user.branchId || null, isCentral: !!user.isCentral,
      category: "เข้าสู่ระบบ", action: "เข้าสู่ระบบ", detail: "",
    }, ...prev]);
  }
  function handleLogout() {
    const now = new Date();
    if (currentUser) {
      setActivityLog(prev => [{
        id: "act" + Date.now(), date: now.toISOString().slice(0, 10),
        time: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
        userType: currentUser.type, userName: currentUser.type === "staff" ? (staff.find(s => s.id === currentUser.staffId)?.displayName || currentUser.name) : (ownerProfile?.name || "เจ้าของร้าน"),
        branchId: currentBranchId || null, isCentral: !!currentUser.isCentral,
        category: "เข้าสู่ระบบ", action: "ออกจากระบบ", detail: "",
      }, ...prev]);
    }
    setCurrentUser(null);
  }
  function handleSwitchBranch(branchId, isCentral) {
    setCurrentBranchId(branchId);
    setCurrentUser(prev => ({ ...prev, isCentral: !!isCentral }));
    if (isCentral && active === "pos") setActive("dashboard");
    setSwitchingBranch(false);
  }

  // Tables belong to a specific branch. Once a branch is selected (at login,
  // or via the Branches settings page), only that branch's tables are shown —
  // tables with no branchId (older data) are treated as always-visible.
  const branchTables = tables.filter(t => !currentBranchId || !t.branchId || t.branchId === currentBranchId);

  // Staff belong to a specific branch. Staff with no branchId (older data) are
  // treated as always-visible, same convention as tables above.
  const branchStaff = staff.filter(s => !currentBranchId || !s.branchIds?.length || s.branchIds.includes(currentBranchId));
  // Kitchen tickets belong to whichever branch sent them, so two branches
  // running at once never see each other's orders in the queue.
  const branchKitchenFood = kitchenFood.filter(t => !currentBranchId || !t.branchId || t.branchId === currentBranchId);
  const branchKitchenDrinks = kitchenDrinks.filter(t => !currentBranchId || !t.branchId || t.branchId === currentBranchId);

  const visibleNav = NAV.map(group => {
    const items = group.items.map(item => {
      if (item.key === "pos" && currentUser?.isCentral) return null; // taking live orders only makes sense inside one physical branch
      if (item.children) {
        const children = item.children.filter(child => hasPermission(child.key));
        if (children.length === 0) return null;
        return { ...item, children };
      }
      return hasPermission(item.key) ? item : null;
    }).filter(Boolean);
    return items.length > 0 ? { ...group, items } : null;
  }).filter(Boolean);

  const [breadGroup, pageTitle, pageSub] = PAGE_TITLE[active];

  // Jump the content area back to the top every time the page changes, so
  // clicking a menu item further down the sidebar doesn't leave you scrolled
  // past the top of the new page.
  useEffect(() => {
    mainRef.current?.scrollTo(0, 0);
  }, [active]);

  // Keep the rail's selected group synced to whichever group the current
  // page lives in (e.g. after navigating). Clicking a rail icon overrides
  // this until the next page change.
  useEffect(() => {
    setSelectedGroup(breadGroup);
  }, [breadGroup]);

  const [showNotifications, setShowNotifications] = useState(false);
  const [showUserMenu, setShowUserMenu] = useState(false);
  const [switchingBranch, setSwitchingBranch] = useState(false);
  const FOOD_COST_ALERT_THRESHOLD = 35; // %

  const notifications = useMemo(() => {
    const list = [];
    const todayStr = new Date().toISOString().slice(0, 10);

    const lowStockItems = stockItems.filter(s => stockQtyFor(s, currentBranchId) <= stockMinFor(s, currentBranchId));
    if (lowStockItems.length > 0) {
      list.push({
        id: "n-lowstock", severity: "warn", title: `สินค้าใกล้หมด ${lowStockItems.length} รายการ`,
        detail: lowStockItems.slice(0, 3).map(s => s.name).join(", ") + (lowStockItems.length > 3 ? " และอื่นๆ" : ""),
        page: "stockItems",
      });
    }

    const overCostItems = menu.filter(m => {
      if (!(m.recipe || []).length || !m.price) return false;
      const cost = menuItemCost(m, stockItems);
      return (cost / m.price) * 100 > FOOD_COST_ALERT_THRESHOLD;
    });
    if (overCostItems.length > 0) {
      list.push({
        id: "n-foodcost", severity: "warn", title: `เมนูต้นทุนเกิน ${FOOD_COST_ALERT_THRESHOLD}% จำนวน ${overCostItems.length} รายการ`,
        detail: overCostItems.slice(0, 3).map(m => m.name).join(", ") + (overCostItems.length > 3 ? " และอื่นๆ" : ""),
        page: "foodCost",
      });
    }

    const openShifts = salesShifts.filter(s => s.status === "open");
    openShifts.forEach(s => {
      list.push({
        id: `n-shift-${s.id}`, severity: "info", title: `กะการขายยังไม่ได้ปิด — เปิดโดย ${s.openedBy}`,
        detail: `เปิดเมื่อ ${fmtDate(s.openedAt.slice(0, 10))} ${s.openedAt.slice(11, 16)} น.`,
        page: "salesShifts",
      });
    });

    const overduePOs = purchaseOrders.filter(po => (po.paymentStatus || "pending") === "pending" && poDueDate(po) < todayStr);
    if (overduePOs.length > 0) {
      list.push({
        id: "n-po-overdue", severity: "danger", title: `ใบสั่งซื้อเกินกำหนดชำระ ${overduePOs.length} ฉบับ`,
        detail: overduePOs.slice(0, 3).map(po => po.poNumber).join(", ") + (overduePOs.length > 3 ? " และอื่นๆ" : ""),
        page: "purchaseOrders",
      });
    }

    const overdueExpenses = expenses.filter(e => (e.paymentStatus || "pending") === "pending" && poDueDate(e) < todayStr);
    if (overdueExpenses.length > 0) {
      list.push({
        id: "n-expense-overdue", severity: "danger", title: `ค่าใช้จ่ายเกินกำหนดชำระ ${overdueExpenses.length} รายการ`,
        detail: overdueExpenses.slice(0, 3).map(e => e.expenseNumber).join(", ") + (overdueExpenses.length > 3 ? " และอื่นๆ" : ""),
        page: "expenses",
      });
    }

    return list;
  }, [stockItems, menu, salesShifts, purchaseOrders, expenses, currentBranchId]);

  function renderPage() {
    switch (active) {
      case "dashboard": return <DashboardPage history={history} orderHistory={orderHistory} expenses={expenses} stockItems={stockItems} members={members} setActive={setActive} branches={branches} currentBranchId={currentBranchId} />;
      case "profitLoss": return <ProfitLossPage history={history} orderHistory={orderHistory} expenses={expenses} menu={menu} stockItems={stockItems} branches={branches} currentBranchId={currentBranchId} />;
      case "staffSales": return <StaffSalesReportPage history={history} staff={staff} positions={positions} currentBranchId={currentBranchId} branches={branches} />;
      case "vatReport": return <VatReportPage history={history} setHistory={setHistory} goodsReceipts={goodsReceipts} setGoodsReceipts={setGoodsReceipts} expenses={expenses} setExpenses={setExpenses} paymentSettings={paymentSettings} vatFilings={vatFilings} setVatFilings={setVatFilings} storeInfo={storeInfo} purchaseOrders={purchaseOrders} vendors={vendors} />;
      case "foodCost": return <FoodCostPage menu={menu} categories={categories} stockItems={stockItems} orderHistory={orderHistory} currentBranchId={currentBranchId} branches={branches} />;
      case "pos": return <PosOrderPage tables={branchTables} setTables={setTables} categories={categories} menu={menu} channels={channels} sessions={posSessions} setSessions={setPosSessions} paymentSettings={paymentSettings} slipSettings={slipSettings} storeInfo={storeInfo} cancelHistory={cancelHistory} setCancelHistory={setCancelHistory} staff={staff} positions={positions} ownerProfile={ownerProfile} members={members} setMembers={setMembers} tiers={tiers} pointRateSettings={pointRateSettings} history={history} setHistory={setHistory} orderHistory={orderHistory} setOrderHistory={setOrderHistory} promotions={promotions} rewards={rewards} setRewards={setRewards} stockItems={stockItems} setStockItems={setStockItems} financeAccounts={financeAccounts} setFinanceAccounts={setFinanceAccounts} setKitchenFood={setKitchenFood} setKitchenDrinks={setKitchenDrinks} currentBranchId={currentBranchId} currentUser={currentUser} branches={branches} pendingRedemptions={pendingRedemptions} setPendingRedemptions={setPendingRedemptions} printers={printers} logActivity={logActivity} emailReceiptSettings={emailReceiptSettings} jumpToTableId={jumpToTablePayment} onJumpToTableConsumed={() => setJumpToTablePayment(null)} />;
      case "openTables": return <OpenTablesPage tables={tables} setTables={setTables} currentBranchId={currentBranchId} branches={branches} sessions={posSessions} setSessions={setPosSessions} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} onReviewSlip={tableId => { setJumpToTablePayment(tableId); setActive("pos"); }} />;
      case "reservations": return <ReservationsPage tables={tables} setTables={setTables} channels={channels} sessions={posSessions} setSessions={setPosSessions} setActive={setActive} setCancelHistory={setCancelHistory} currentBranchId={currentBranchId} branches={branches} />;
      case "tableSettings": return <TableSettingsPage tables={tables} setTables={setTables} zones={zones} setZones={setZones} currentBranchId={currentBranchId} branches={branches} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "kitchenFood": return <KitchenBoard title="ครัวอาหาร" subtitle="คิวออเดอร์อาหารที่ต้องปรุง" icon={ChefHat} tickets={branchKitchenFood} setTickets={setKitchenFood} soundSettings={soundSettings} currentBranchId={currentBranchId} branches={branches} printers={printers} boardType="food" staff={staff} positions={positions} ownerProfile={ownerProfile} currentUser={currentUser} />;
      case "kitchenDrinks": return <KitchenBoard title="ครัวเครื่องดื่ม" subtitle="คิวออเดอร์เครื่องดื่มที่ต้องเตรียม" icon={Coffee} tickets={branchKitchenDrinks} setTickets={setKitchenDrinks} soundSettings={soundSettings} currentBranchId={currentBranchId} branches={branches} printers={printers} boardType="drink" staff={staff} positions={positions} ownerProfile={ownerProfile} currentUser={currentUser} />;
      case "kitchenDisplaySettings": return <KitchenDisplaySettingsPage categories={categories} setCategories={setCategories} />;
      case "members": return <MembersPage members={members} setMembers={setMembers} tiers={tiers} history={history} orderHistory={orderHistory} logActivity={logActivity} />;
      case "tiers": return <TiersPage tiers={tiers} setTiers={setTiers} categories={categories} />;
      case "pointRate": return <PointRatePage settings={pointRateSettings} setSettings={setPointRateSettings} />;
      case "rewards": return <RewardsPage rewards={rewards} setRewards={setRewards} members={members} setMembers={setMembers} setHistory={setHistory} menu={menu} categories={categories} />;
      case "history": return <HistoryPage history={history} />;
      case "lineOaSettings": return <LineOaSettingsPage settings={lineOaSettings} setSettings={setLineOaSettings} />;
      case "addMenu": return <AddMenuPage menu={menu} setMenu={setMenu} categories={categories} channels={channels} stockItems={stockItems} staff={staff} positions={positions} ownerProfile={ownerProfile} currentBranchId={currentBranchId} branches={branches} />;
      case "categories": return <CategoriesPage categories={categories} setCategories={setCategories} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "promotions": return <PromotionsPage promotions={promotions} setPromotions={setPromotions} categories={categories} menu={menu} />;
      case "storeInfo": return <StoreInfoPage storeInfo={storeInfo} setStoreInfo={setStoreInfo} />;
      case "ownerProfile": return <OwnerProfilePage ownerProfile={ownerProfile} setOwnerProfile={setOwnerProfile} />;
      case "themeSettings": return <ThemeSettingsPage themeSettings={themeSettings} setThemeSettings={setThemeSettings} />;
      case "slipReceipt": return <SlipReceiptPage settings={slipSettings} setSettings={setSlipSettings} storeInfo={storeInfo} paymentSettings={paymentSettings} />;
      case "slipOrderQr": return <SlipOrderQrPage settings={slipSettings} setSettings={setSlipSettings} storeInfo={storeInfo} />;
      case "slipKitchenOrder": return <SlipKitchenOrderPage settings={slipSettings} setSettings={setSlipSettings} />;
      case "slipPrecheckBill": return <SlipPrecheckBillPage settings={slipSettings} setSettings={setSlipSettings} storeInfo={storeInfo} paymentSettings={paymentSettings} />;
      case "salesChannels": return <SalesChannelsPage channels={channels} setChannels={setChannels} menu={menu} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "emailReceiptSettings": return <EmailReceiptSettingsPage settings={emailReceiptSettings} setSettings={setEmailReceiptSettings} />;
      case "financeAccounts": return <FinanceAccountsPage financeAccounts={financeAccounts} setFinanceAccounts={setFinanceAccounts} staff={staff} currentBranchId={currentBranchId} branches={branches} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "salesShifts": return <SalesShiftsPage salesShifts={salesShifts} setSalesShifts={setSalesShifts} financeAccounts={financeAccounts} setFinanceAccounts={setFinanceAccounts} staff={staff} history={history} currentBranchId={currentBranchId} branches={branches} />;
      case "receiptHistory": return <ReceiptHistoryPage history={history} financeAccounts={financeAccounts} storeInfo={storeInfo} paymentSettings={paymentSettings} branches={branches} currentBranchId={currentBranchId} printers={printers} />;
      case "cancelHistoryPage": return <CancelHistoryPage cancelHistory={cancelHistory} tables={tables} currentBranchId={currentBranchId} branches={branches} />;
      case "expenses": return <ExpensesPage expenses={expenses} setExpenses={setExpenses} vendors={vendors} financeAccounts={financeAccounts} setFinanceAccounts={setFinanceAccounts} currentBranchId={currentBranchId} branches={branches} storeInfo={storeInfo} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "branches": return <BranchesPage branches={branches} setBranches={setBranches} menu={menu} currentBranchId={currentBranchId} setCurrentBranchId={setCurrentBranchId} storeInfo={storeInfo} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "paymentSettings": return <PaymentSettingsPage settings={paymentSettings} setSettings={setPaymentSettings} financeAccounts={financeAccounts} currentBranchId={currentBranchId} branches={branches} />;
      case "printerSettings": return <PrinterSettingsPage printers={printers} setPrinters={setPrinters} categories={categories} currentBranchId={currentBranchId} branches={branches} />;
      case "printAgentPort": return <PrintAgentPortSettingsPage printAgentSettings={printAgentSettings} setPrintAgentSettings={setPrintAgentSettings} currentBranchId={currentBranchId} branches={branches} />;
      case "soundSettings": return <SoundSettingsPage settings={soundSettings} setSettings={setSoundSettings} positions={positions} />;
      case "staffList": return <StaffListPage staff={staff} setStaff={setStaff} positions={positions} categories={categories} currentBranchId={currentBranchId} branches={branches} />;
      case "attendance": return <AttendancePage attendance={attendance} setAttendance={setAttendance} staff={staff} attendanceSettings={attendanceSettings} branches={branches} />;
      case "attendanceSettings": return <AttendanceSettingsPage attendanceSettings={attendanceSettings} setAttendanceSettings={setAttendanceSettings} />;
      case "attendanceReport": return <AttendanceReportPage attendance={attendance} setAttendance={setAttendance} staff={staff} workSchedules={workSchedules} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "workSchedule": return <WorkSchedulePage workSchedules={workSchedules} setWorkSchedules={setWorkSchedules} staff={staff} setStaff={setStaff} lateAbsentPolicy={lateAbsentPolicy} setLateAbsentPolicy={setLateAbsentPolicy} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "staffDaysOff": return <StaffDaysOffPage staff={staff} setStaff={setStaff} daysOff={daysOff} setDaysOff={setDaysOff} ownerProfile={ownerProfile} positions={positions} leaveTypes={leaveTypes} currentBranchId={currentBranchId} branches={branches} />;
      case "leaveEntitlements": return <LeaveEntitlementsPage leaveTypes={leaveTypes} setLeaveTypes={setLeaveTypes} staff={staff} setStaff={setStaff} daysOff={daysOff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "payroll": return <PayrollPage staff={staff} positions={positions} attendance={attendance} daysOff={daysOff} workSchedules={workSchedules} salesInputs={payrollSalesInputs} setSalesInputs={setPayrollSalesInputs} storeInfo={storeInfo} expenses={expenses} setExpenses={setExpenses} ownerProfile={ownerProfile} currentBranchId={currentBranchId} branches={branches} />;
      case "staffPositions": return <StaffPositionsPage positions={positions} setPositions={setPositions} />;
      case "staffApplicants": return <StaffApplicantsPage applicants={applicants} setApplicants={setApplicants} positions={positions} staff={staff} setStaff={setStaff} ownerProfile={ownerProfile} />;
      case "staffRecruitment": return <StaffRecruitmentPage jobs={jobs} setJobs={setJobs} storeInfo={storeInfo} setApplicants={setApplicants} currentBranchId={currentBranchId} branches={branches} />;
      case "stockItems": return <StockItemsPage stockItems={stockItems} setStockItems={setStockItems} stockCategories={stockCategories} stockUnits={stockUnits} currentBranchId={currentBranchId} branches={branches} vendors={vendors} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "stockCategories": return <StockCategoriesPage stockCategories={stockCategories} setStockCategories={setStockCategories} stockUnits={stockUnits} setStockUnits={setStockUnits} stockItems={stockItems} setStockItems={setStockItems} />;
      case "vendors": return <VendorsPage vendors={vendors} setVendors={setVendors} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "purchaseOrders": return <PurchaseOrdersPage purchaseOrders={purchaseOrders} setPurchaseOrders={setPurchaseOrders} vendors={vendors} stockItems={stockItems} financeAccounts={financeAccounts} setFinanceAccounts={setFinanceAccounts} currentBranchId={currentBranchId} branches={branches} storeInfo={storeInfo} />;
      case "goodsReceipts": return <GoodsReceiptsPage purchaseOrders={purchaseOrders} setPurchaseOrders={setPurchaseOrders} vendors={vendors} stockItems={stockItems} setStockItems={setStockItems} goodsReceipts={goodsReceipts} setGoodsReceipts={setGoodsReceipts} currentBranchId={currentBranchId} branches={branches} />;
      case "wasteLog": return <WastePage wasteLog={wasteLog} setWasteLog={setWasteLog} stockItems={stockItems} setStockItems={setStockItems} currentBranchId={currentBranchId} branches={branches} staff={staff} ownerProfile={ownerProfile} logActivity={logActivity} />;
      case "activityLog": return <ActivityLogPage activityLog={activityLog} currentBranchId={currentBranchId} branches={branches} />;
      case "loginLog": return <LoginLogPage loginLog={loginLog} currentBranchId={currentBranchId} branches={branches} />;
      default: return null;
    }
  }

  if (mobileOrderParams) {
    return <MobileOrderPage tableId={mobileOrderParams.table} token={mobileOrderParams.token} sessions={posSessions} setSessions={setPosSessions} tables={tables} menu={menu} categories={categories} storeInfo={storeInfo} paymentSettings={paymentSettings} branches={branches} currentBranchId={currentBranchId} printers={printers} skipSyncRef={skipFirstSyncRef} financeAccounts={financeAccounts} members={members} />;
  }

  if (jobsMode) {
    return <PublicJobsPage jobs={jobs} storeInfo={storeInfo} setApplicants={setApplicants} />;
  }

  if (customerMode) {
    return <CustomerSelfServicePage members={members} setMembers={setMembers} tiers={tiers} promotions={promotions} rewards={rewards} setRewards={setRewards} history={history} storeInfo={storeInfo} onBack={() => setCustomerMode(false)} pendingRedemptions={pendingRedemptions} setPendingRedemptions={setPendingRedemptions} menu={menu} logActivity={logActivity} />;
  }

  if (attendanceMode) {
    return (
      <div className="liff-font min-h-screen bg-stone-50 p-4 py-10">
        <BrandFontStyle />
        <div className="w-full max-w-md mx-auto">
          <div className="text-center mb-6">
            <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-14 h-14 rounded-xl object-cover mx-auto mb-3" />
            <div className="font-serif text-xl text-stone-800">{storeInfo?.name}</div>
            <div className="text-xs text-amber-600 tracking-wide">Check In - Check Out</div>
          </div>
          <AttendancePage attendance={attendance} setAttendance={setAttendance} staff={staff} attendanceSettings={attendanceSettings} branches={branches} />
          <button onClick={() => setAttendanceMode(false)} className="text-xs text-stone-400 hover:text-stone-600 mt-6 block mx-auto">
            ← กลับสู่หน้าพนักงาน
          </button>
        </div>
      </div>
    );
  }

  if (!currentUser) {
    return <LoginPage staff={staff} ownerProfile={ownerProfile} storeInfo={storeInfo} onLogin={handleLogin} branches={branches} onAttendanceMode={() => setAttendanceMode(true)} />;
  }

  if (!hasPermission(active)) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-stone-50 p-4">
        <div className="text-center">
          <ShieldCheck size={40} className="text-stone-300 mx-auto mb-3" />
          <div className="text-lg font-semibold text-stone-700 mb-1">ไม่มีสิทธิ์เข้าถึงหน้านี้</div>
          <div className="text-sm text-stone-400 mb-4">ตำแหน่งของคุณไม่ได้รับสิทธิ์เข้าถึงเมนูนี้ ติดต่อผู้จัดการหากต้องการสิทธิ์เพิ่มเติม</div>
          <Btn onClick={() => setActive(firstAllowedPageFor(currentUser) || "dashboard")}>กลับหน้าแรก</Btn>
        </div>
      </div>
    );
  }

  return (
    <div className={`rbo-app flex min-h-screen bg-stone-50 text-stone-800${themeSettings.darkMode ? " dark-mode" : ""}`}>
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Prompt:wght@300;400;500;600;700&family=Sarabun:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
        .rbo-app { font-family: 'Prompt','Sarabun',sans-serif; --accent: ${themeSettings.accentColor}; }
        .rbo-app .font-serif { font-family: 'Prompt','Sarabun',sans-serif; font-weight: 600; letter-spacing: 0.01em; }
        .rbo-app .font-mono { font-family: 'JetBrains Mono', 'Sarabun', monospace; }
        .print-receipt { display: none; }
        .print-po { display: none; }
        @media print {
          body * { visibility: hidden; }
          .print-receipt, .print-receipt * { visibility: visible; }
          .print-receipt { display: block; position: absolute; top: 0; left: 0; width: 80mm; padding: 4mm; }
          .print-po, .print-po * { visibility: visible; }
          .print-po { display: block; position: absolute; top: 0; left: 0; width: 210mm; padding: 15mm; }
        }

        /* Custom accent color — remaps the app's amber accent to whatever the user picks. */
        .rbo-app .text-amber-600, .rbo-app .text-amber-700, .rbo-app .text-amber-800 { color: var(--accent) !important; }
        .rbo-app .bg-amber-600 { background-color: var(--accent) !important; }
        .rbo-app .bg-amber-400 { background-color: color-mix(in srgb, var(--accent) 75%, white) !important; }
        .rbo-app .text-amber-400 { color: color-mix(in srgb, var(--accent) 75%, white) !important; }
        .rbo-app .bg-amber-50, .rbo-app .bg-amber-100 { background-color: color-mix(in srgb, var(--accent) 12%, white) !important; }
        .rbo-app .border-amber-200, .rbo-app .border-amber-300, .rbo-app .border-amber-400 { border-color: color-mix(in srgb, var(--accent) 45%, white) !important; }
        .rbo-app .hover\\:bg-amber-700:hover, .rbo-app button:hover.bg-stone-900 { background-color: var(--accent) !important; }
        .rbo-app .hover\\:text-amber-700:hover { color: var(--accent) !important; }
        .rbo-app .focus\\:ring-amber-400:focus { --tw-ring-color: var(--accent) !important; }
        .rbo-app .focus\\:border-amber-400:focus { border-color: var(--accent) !important; }
        .rbo-app .border-amber-600 { border-color: var(--accent) !important; }

        /* Dark mode — best-effort recoloring of the app's core chrome (backgrounds, text, borders, inputs). */
        .rbo-app.dark-mode { background-color: #18181b !important; color: #e4e4e7; }
        .rbo-app.dark-mode .bg-white { background-color: #27272a !important; }
        .rbo-app.dark-mode .bg-stone-50 { background-color: #18181b !important; }
        .rbo-app.dark-mode .bg-stone-100 { background-color: #3f3f46 !important; }
        .rbo-app.dark-mode .bg-stone-900\\/40, .rbo-app.dark-mode .bg-stone-900\\/50 { background-color: rgba(0,0,0,0.6) !important; }
        .rbo-app.dark-mode .text-stone-800, .rbo-app.dark-mode .text-stone-900 { color: #f4f4f5 !important; }
        .rbo-app.dark-mode .text-stone-700, .rbo-app.dark-mode .text-stone-600 { color: #d4d4d8 !important; }
        .rbo-app.dark-mode .text-stone-500, .rbo-app.dark-mode .text-stone-400 { color: #a1a1aa !important; }
        .rbo-app.dark-mode .text-stone-300 { color: #71717a !important; }
        .rbo-app.dark-mode .border-stone-200, .rbo-app.dark-mode .border-stone-100, .rbo-app.dark-mode .border-stone-300 { border-color: #3f3f46 !important; }
        .rbo-app.dark-mode input, .rbo-app.dark-mode select, .rbo-app.dark-mode textarea { background-color: #27272a !important; color: #e4e4e7 !important; border-color: #52525b !important; }
        .rbo-app.dark-mode option { background-color: #27272a; color: #e4e4e7; }
        .rbo-app.dark-mode ::placeholder { color: #71717a !important; }
        .rbo-app.dark-mode .shadow-sm, .rbo-app.dark-mode .shadow-lg { box-shadow: 0 1px 3px rgba(0,0,0,0.5) !important; }
      `}</style>

      {/* Hidden target for the "เรียกพนักงาน" sound alert's YouTube option (see
          the callStaffRequested watcher effect) — rendered once here at the
          persistent app shell level (not inside any one page) so the alert
          can fire no matter which page staff currently have open, unlike
          KitchenBoard's own notify iframe which only exists while a kitchen
          board is the active page. */}
      <iframe id="call-staff-notify-yt-frame" title="เสียงแจ้งเตือนลูกค้าเรียกพนักงาน" width="0" height="0" style={{ border: 0, position: "absolute" }} allow="autoplay" />

      {/* Mobile/tablet backdrop for the nav drawer (touch devices only) */}
      {isTouchDevice && mobileNavOpen && (
        <div className="fixed inset-0 bg-stone-900/50 z-40" onClick={() => setMobileNavOpen(false)} />
      )}

      {/* Sidebar: icon rail (picks a group) + panel (that group's items) */}
      <aside className={isTouchDevice
        ? `fixed inset-y-0 left-0 z-50 flex transition-transform duration-200 ease-in-out ${mobileNavOpen ? "translate-x-0" : "-translate-x-full"}`
        : "flex flex-shrink-0"}>
        {/* Icon rail */}
        <div className="w-14 flex-shrink-0 flex flex-col items-center py-4 gap-1" style={{ backgroundColor: "#0a1a30" }}>
          <img src={storeInfo.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-8 h-8 rounded-md object-cover flex-shrink-0 mb-3" />
          {visibleNav.map(group => {
            const isSelected = selectedGroup === group.group;
            return (
              <button key={group.group} onClick={() => { setSelectedGroup(group.group); setPanelOpen(true); }} title={group.group}
                className={`w-10 h-10 rounded-lg flex items-center justify-center transition-colors flex-shrink-0
                ${isSelected ? "bg-blue-900 text-amber-400" : "text-blue-400 hover:text-white hover:bg-blue-900/60"}`}>
                <group.groupIcon size={19} />
              </button>
            );
          })}
        </div>

        {/* Panel: items for the selected group (collapses to just the rail after picking a page) */}
        {panelOpen && (
        <div className="w-52 bg-blue-950 text-blue-200 flex-shrink-0 flex flex-col">
          <div className="px-4 py-5 border-b border-blue-900 flex items-center justify-between gap-2">
            <div className="min-w-0">
              <div className="font-serif text-base text-white leading-tight truncate">{storeInfo.name}</div>
              <div className="text-[10px] text-amber-400 tracking-wide truncate">{storeInfo.tagline}</div>
            </div>
            {isTouchDevice && (
              <button onClick={() => setMobileNavOpen(false)} className="text-blue-300 hover:text-white flex-shrink-0"><X size={18} /></button>
            )}
          </div>
          <div className="px-4 py-3 text-xs font-semibold tracking-widest text-blue-500 uppercase border-b border-blue-900/60">{selectedGroup}</div>
          <nav className="flex-1 overflow-y-auto py-2">
            {(visibleNav.find(g => g.group === selectedGroup)?.items || []).map(item => {
              const isActive = active === item.key;
              if (item.children) {
                const isExpanded = !!expandedNav[item.key];
                const childActive = item.children.some(ch => ch.key === active);
                return (
                  <div key={item.key}>
                    <button onClick={() => setExpandedNav(prev => ({ ...prev, [item.key]: !prev[item.key] }))}
                      className={`w-full flex items-center gap-2.5 px-4 py-2 text-sm transition-colors border-l-2
                      ${childActive ? "text-amber-400 border-amber-500" : "border-transparent text-blue-300 hover:text-white hover:bg-blue-900/60"}`}>
                      <item.icon size={16} />
                      <span className="flex-1 text-left">{item.label}</span>
                      <ChevronDown size={12} className={`transition-transform ${isExpanded ? "rotate-180" : ""}`} />
                    </button>
                    {isExpanded && (
                      <div>
                        {item.children.map(child => (
                          <button key={child.key} onClick={() => { setActive(child.key); setMobileNavOpen(false); setPanelOpen(false); }}
                            className={`w-full flex items-center gap-2 pl-9 pr-4 py-1.5 text-xs transition-colors border-l-2
                            ${active === child.key ? "bg-blue-900 text-amber-400 border-amber-500" : "border-transparent text-blue-400 hover:text-white hover:bg-blue-900/60"}`}>
                            {child.label}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                );
              }
              return (
                <button key={item.key} onClick={() => { setActive(item.key); setMobileNavOpen(false); setPanelOpen(false); }}
                  className={`w-full flex items-center gap-2.5 px-4 py-2 text-sm transition-colors border-l-2
                  ${isActive ? "bg-blue-900 text-amber-400 border-amber-500" : "border-transparent text-blue-300 hover:text-white hover:bg-blue-900/60"}`}>
                  <item.icon size={16} />
                  {item.label}
                </button>
              );
            })}
          </nav>
        </div>
        )}
      </aside>

      {/* Main */}
      <div className="flex-1 flex flex-col min-w-0">
        <header className="h-14 border-b border-stone-200 bg-white flex items-center justify-between px-3 sm:px-6 flex-shrink-0">
          <div className="flex items-center gap-3 min-w-0">
            {isTouchDevice && (
              <button onClick={() => setMobileNavOpen(true)} className="text-stone-500 hover:text-stone-800 flex-shrink-0">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="3" y1="6" x2="21" y2="6" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="18" x2="21" y2="18" /></svg>
              </button>
            )}
            <div className="text-xs text-stone-400 truncate">{breadGroup} / <span className="text-stone-600">{pageTitle}</span></div>
          </div>
          <div className="flex items-center gap-2 sm:gap-4 text-xs text-stone-500 flex-shrink-0">
            <span className={`px-2.5 py-1 rounded-full text-[11px] font-medium border ${currentUser?.isCentral ? "bg-stone-900 text-white border-stone-900" : "bg-amber-50 text-amber-700 border-amber-200"}`}>
              {currentUser?.isCentral ? "ระบบส่วนกลาง" : (branches.find(b => b.id === currentBranchId)?.name || "-")}
            </span>
            <span className="hidden md:inline">{(() => {
              // Was hardcoded to a fixed placeholder date before — now reads
              // the real current date/time on every render.
              const THAI_FULL_WEEKDAYS = ["วันอาทิตย์", "วันจันทร์", "วันอังคาร", "วันพุธ", "วันพฤหัสบดี", "วันศุกร์", "วันเสาร์"];
              const THAI_MONTH_ABBR = ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."];
              const now = new Date();
              return `${THAI_FULL_WEEKDAYS[now.getDay()]} ${now.getDate()} ${THAI_MONTH_ABBR[now.getMonth()]} ${now.getFullYear() + 543}`;
            })()}</span>
            <div className="relative">
              <button onClick={() => setShowNotifications(v => !v)} className="relative text-stone-400 hover:text-stone-700">
                <Bell size={19} />
                {notifications.length > 0 && (
                  <span className="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-rose-500 text-white text-[9px] font-semibold flex items-center justify-center">
                    {notifications.length > 9 ? "9+" : notifications.length}
                  </span>
                )}
              </button>
              {showNotifications && (
                <div className="absolute right-0 top-full mt-2 w-80 bg-white border border-stone-200 rounded-lg shadow-lg z-50 overflow-hidden">
                  <div className="px-4 py-3 border-b border-stone-100 font-semibold text-stone-700 text-sm">การแจ้งเตือน</div>
                  <div className="max-h-96 overflow-y-auto">
                    {notifications.length === 0 && (
                      <div className="px-4 py-8 text-center text-stone-400 text-sm">ไม่มีการแจ้งเตือนตอนนี้</div>
                    )}
                    {notifications.map(n => (
                      <button key={n.id} onClick={() => { setActive(n.page); setShowNotifications(false); }}
                        className="w-full text-left px-4 py-3 border-b border-stone-50 last:border-0 hover:bg-stone-50 flex items-start gap-2.5">
                        <span className={`w-2 h-2 rounded-full mt-1.5 flex-shrink-0 ${n.severity === "danger" ? "bg-rose-500" : n.severity === "warn" ? "bg-amber-500" : "bg-sky-500"}`} />
                        <div className="min-w-0">
                          <div className="text-sm font-medium text-stone-800">{n.title}</div>
                          <div className="text-xs text-stone-400 truncate">{n.detail}</div>
                        </div>
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </div>
            <div className="relative">
              <button onClick={() => setShowUserMenu(v => !v)} className="flex items-center gap-1.5">
                <div className="w-7 h-7 rounded-full bg-amber-100 text-amber-800 flex items-center justify-center text-xs font-semibold flex-shrink-0">
                  {currentUser.name?.slice(0, 2) || "?"}
                </div>
              </button>
              {showUserMenu && (
                <div className="absolute right-0 top-full mt-2 w-48 bg-white border border-stone-200 rounded-lg shadow-lg z-50 overflow-hidden">
                  <div className="px-3 py-2.5 border-b border-stone-100">
                    <div className="text-sm font-medium text-stone-800 truncate">{currentUser.name}</div>
                    <div className="text-xs text-stone-400">{currentUser.type === "owner" ? "เจ้าของร้าน" : (positions.find(p => p.id === currentUser.positionId)?.name || "พนักงาน")}</div>
                    <div className="text-xs mt-1 font-medium">
                      {currentUser.isCentral ? (
                        <span className="text-amber-700">ระบบส่วนกลาง</span>
                      ) : (
                        <span className="text-stone-500">{branches.find(b => b.id === currentBranchId)?.name || "-"}</span>
                      )}
                    </div>
                  </div>
                  {currentUser.type === "owner" && branches.filter(b => b.active).length > 1 && (
                    <button onClick={() => { setShowUserMenu(false); setSwitchingBranch(true); }} className="w-full text-left px-3 py-2.5 text-sm text-stone-700 hover:bg-stone-50 flex items-center gap-2">
                      <RefreshCw size={14} /> เปลี่ยนสาขา
                    </button>
                  )}
                  <button onClick={handleLogout} className="w-full text-left px-3 py-2.5 text-sm text-rose-600 hover:bg-rose-50">ออกจากระบบ</button>
                </div>
              )}
            </div>
          </div>
        </header>
        <main ref={mainRef} className="flex-1 overflow-y-auto p-4 sm:p-5 lg:p-7">
          {renderPage()}
        </main>
      </div>

      {switchingBranch && (() => {
        const BRANCH_EMOJIS = ["🏢", "🏯", "🏰", "🏛️", "🏬", "🏪"];
        return (
        <div className="fixed inset-0 bg-stone-900/50 flex items-center justify-center z-[100] p-4" onClick={() => setSwitchingBranch(false)}>
          <div className="w-full max-w-3xl" onClick={e => e.stopPropagation()}>
            <div className="text-center mb-8">
              <img src={storeInfo?.logoDataUrl || LOGO_DATA_URI} alt="โลโก้ร้าน" className="w-16 h-16 rounded-full object-cover mx-auto mb-3" />
              <div className="font-serif text-xl text-stone-800">เปลี่ยนสาขา / ระบบ</div>
              <p className="text-sm text-stone-400 mt-1">ระบบส่วนกลางจัดการได้ทุกสาขา ส่วนเลือกสาขาจะจัดการได้เฉพาะสาขานั้น</p>
            </div>
            <div className="flex flex-wrap items-stretch justify-center gap-4">
              <button onClick={() => handleSwitchBranch(null, true)}
                className={`relative w-44 bg-white rounded-2xl shadow-sm hover:shadow-md p-6 text-center transition-shadow border-2 ${currentUser.isCentral ? "border-amber-400" : "border-transparent"}`}>
                {currentUser.isCentral && <CheckCircle2 size={18} className="text-amber-500 absolute top-3 right-3" />}
                <div className="text-4xl mb-3">🔑</div>
                <div className="font-semibold text-stone-800 text-sm">ระบบกลาง</div>
                <div className="text-xs text-stone-400 mt-1">เข้าถึงได้ทุกสาขา</div>
              </button>
              {branches.filter(b => b.active).map((b, i) => (
                <button key={b.id} onClick={() => handleSwitchBranch(b.id, false)}
                  className={`relative w-44 bg-white rounded-2xl shadow-sm hover:shadow-md p-6 text-center transition-shadow border-2 ${!currentUser.isCentral && currentBranchId === b.id ? "border-amber-400" : "border-transparent"}`}>
                  {!currentUser.isCentral && currentBranchId === b.id && <CheckCircle2 size={18} className="text-amber-500 absolute top-3 right-3" />}
                  <div className="text-4xl mb-3">{BRANCH_EMOJIS[i % BRANCH_EMOJIS.length]}</div>
                  <div className="font-semibold text-stone-800 text-sm">{b.name}</div>
                  <div className="text-xs text-stone-400 mt-1 leading-snug">{b.address}</div>
                </button>
              ))}
            </div>
            <button onClick={() => setSwitchingBranch(false)} className="text-xs text-stone-400 hover:text-stone-600 mt-8 block mx-auto">ยกเลิก</button>
          </div>
        </div>
        );
      })()}
    </div>
  );
}

/* =========================================================================
   MOUNT — no-build deployment entry point (Babel Standalone + import map)
   ========================================================================= */
createRoot(document.getElementById("root")).render(<RestaurantBackOffice />);
