// TTG Petty Cash — Mock Data & Helpers
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ---------- Currency / Date Helpers ----------
const fmtMoney = (n, opts={}) => {
  if (n == null || isNaN(n)) return '—';
  const v = Number(n);
  return v.toLocaleString('th-TH', { minimumFractionDigits: 2, maximumFractionDigits: 2, ...opts });
};
const fmtDate = (iso) => {
  if (!iso) return '—';
  const d = new Date(iso);
  const months = ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.','ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'];
  return `${d.getDate()} ${months[d.getMonth()]} ${(d.getFullYear()+543).toString().slice(-2)}`;
};
const fmtDateTime = (iso) => {
  if (!iso) return '—';
  const d = new Date(iso);
  return `${fmtDate(iso)} ${d.getHours().toString().padStart(2,'0')}:${d.getMinutes().toString().padStart(2,'0')}`;
};
const todayISO = () => new Date().toISOString().slice(0,10);
const addDays = (iso, days) => {
  const d = new Date(iso);
  d.setDate(d.getDate() + days);
  return d.toISOString().slice(0,10);
};
const sumItems = (items) => items.reduce((a,b)=> a + (Number(b.amount)||0), 0);
const sumActual = (items) => items.reduce((a,b)=> a + (Number(b.actual)||0), 0);

// ---------- Departments ----------
const DEPARTMENTS = [
  { code: 'MKT-01', name: 'การตลาดและสื่อสารองค์กร' },
  { code: 'OPS-02', name: 'ปฏิบัติการ' },
  { code: 'HR-03', name: 'ทรัพยากรบุคคล' },
  { code: 'IT-04', name: 'เทคโนโลยีสารสนเทศ' },
  { code: 'FIN-05', name: 'บัญชีและการเงิน' },
  { code: 'SAL-06', name: 'ฝ่ายขาย' },
  { code: 'PRD-07', name: 'พัฒนาผลิตภัณฑ์' },
];

// ---------- Users ----------
const USERS = {
  staff: { id: 'u1', name: 'สุชาดา วิจิตรกุล', initials: 'SV', position: 'Senior Marketing Officer', role: 'staff', dept: 'MKT-01' },
  manager: { id: 'u2', name: 'ธนากร เจริญวงศ์', initials: 'TC', position: 'Marketing Manager', role: 'manager', dept: 'MKT-01' },
  director: { id: 'u3', name: 'พิมพ์ลภัส ศรีสวัสดิ์', initials: 'PS', position: 'Director, Brand & Comms', role: 'director', dept: 'MKT-01' },
  finance: { id: 'u4', name: 'อรวรรณ ดำรงพันธุ์', initials: 'OD', position: 'Finance Officer', role: 'finance', dept: 'FIN-05' },
};

const ROLE_META = {
  staff: { label: 'พนักงาน', en: 'Employee' },
  manager: { label: 'ผู้จัดการฝ่าย', en: 'Manager' },
  director: { label: 'ผู้อำนวยการ', en: 'Director' },
  finance: { label: 'เจ้าหน้าที่การเงิน', en: 'Finance' },
};

// ---------- Status ----------
const STATUS_META = {
  draft:       { label: 'ฉบับร่าง',          en: 'Draft',        cls: 'badge--draft'    },
  pending_mgr: { label: 'รออนุมัติฝ่าย',     en: 'Manager',      cls: 'badge--pending'  },
  pending_dir: { label: 'รออนุมัติ ผอ.',     en: 'Director',     cls: 'badge--pending'  },
  pending_fin: { label: 'รอตรวจ การเงิน',    en: 'Finance',      cls: 'badge--pending'  },
  approved:    { label: 'อนุมัติแล้ว',       en: 'Approved',     cls: 'badge--approved' },
  paid:        { label: 'จ่ายเงินแล้ว',      en: 'Paid out',     cls: 'badge--paid'     },
  clearing:    { label: 'รอเคลียร์',         en: 'Awaiting clear', cls: 'badge--clearing' },
  cleared:     { label: 'เคลียร์สำเร็จ',     en: 'Cleared',      cls: 'badge--closed'   },
  rejected:    { label: 'ถูกปฏิเสธ',         en: 'Rejected',     cls: 'badge--rejected' },
};
const statusBadge = (s) => {
  const m = STATUS_META[s] || STATUS_META.draft;
  return <span className={`badge ${m.cls}`}><span className="dot"></span>{m.label}</span>;
};

// ---------- Sample Data ----------
const SEED_REQUESTS = [
  {
    id: 'PCR-2026-0428',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'ค่าใช้จ่ายในการจัดกิจกรรมเปิดตัวสินค้าใหม่ ไตรมาส 2 สำหรับลูกค้าโครงการคอนโดมิเนียม รวมค่าเช่าสถานที่ ค่าอาหารและของชำร่วย',
    startDate: '2026-05-22',
    dueDate: '2026-06-05',
    submittedAt: '2026-05-15T09:24:00',
    items: [
      { desc: 'ค่าเช่าสถานที่จัดงาน 1 วัน', amount: 25000 },
      { desc: 'ค่าอาหารกลางวันและของว่าง (50 ท่าน)', amount: 18500 },
      { desc: 'ของชำร่วยสำหรับลูกค้า VIP', amount: 12800 },
      { desc: 'ค่าเดินทางทีมงาน 4 คน', amount: 4200 },
    ],
    status: 'pending_dir',
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-05-15T09:24:00', note: '' },
      { type: 'approve', who: USERS.manager, role: 'manager', at: '2026-05-15T14:02:00', note: 'อนุมัติ ขอให้เก็บใบเสร็จครบถ้วน' },
    ],
  },
  {
    id: 'PCR-2026-0431',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'ค่าใช้จ่ายในการเดินทางไปออกบูธงาน Property Expo 2026 ที่ศูนย์การประชุมแห่งชาติสิริกิติ์',
    startDate: '2026-05-18',
    dueDate: '2026-05-25',
    submittedAt: '2026-05-14T11:15:00',
    items: [
      { desc: 'ค่าตกแต่งบูธและพิมพ์โบรชัวร์', amount: 35000 },
      { desc: 'ค่าเดินทางและที่พักทีม 3 วัน', amount: 22000 },
      { desc: 'ค่าอาหารและเครื่องดื่ม', amount: 8000 },
    ],
    status: 'paid',
    paidAt: '2026-05-16T10:30:00',
    paidAmount: 65000,
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-05-14T11:15:00' },
      { type: 'approve', who: USERS.manager, role: 'manager', at: '2026-05-14T15:20:00' },
      { type: 'approve', who: USERS.director, role: 'director', at: '2026-05-15T09:45:00', note: 'รบกวนเร่งดำเนินการ' },
      { type: 'approve', who: USERS.finance, role: 'finance', at: '2026-05-16T08:40:00' },
      { type: 'paid', who: USERS.finance, at: '2026-05-16T10:30:00', note: 'โอนเข้าบัญชีธนาคารกรุงเทพ ของผู้ขอเบิก' },
    ],
  },
  {
    id: 'PCR-2026-0425',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'จัดถ่ายทำคอนเทนต์โซเชียลมีเดียประจำเดือนพฤษภาคม รวมค่าโลเคชั่นและทีมโปรดักชั่น',
    startDate: '2026-05-08',
    dueDate: '2026-05-20',
    submittedAt: '2026-05-05T08:00:00',
    items: [
      { desc: 'ค่าจ้างทีมถ่ายทำ Freelance 2 วัน', amount: 28000 },
      { desc: 'ค่าโลเคชั่นและพร็อพ', amount: 12000 },
      { desc: 'ค่าเดินทาง', amount: 3500 },
    ],
    status: 'clearing',
    paidAt: '2026-05-07T11:00:00',
    paidAmount: 43500,
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-05-05T08:00:00' },
      { type: 'approve', who: USERS.manager, role: 'manager', at: '2026-05-05T10:00:00' },
      { type: 'approve', who: USERS.director, role: 'director', at: '2026-05-06T09:00:00' },
      { type: 'approve', who: USERS.finance, role: 'finance', at: '2026-05-07T08:30:00' },
      { type: 'paid', who: USERS.finance, at: '2026-05-07T11:00:00' },
    ],
  },
  {
    id: 'PCR-2026-0419',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'ประชุมสัมมนาทีมการตลาดประจำไตรมาส',
    startDate: '2026-04-22',
    dueDate: '2026-05-01',
    submittedAt: '2026-04-15T10:00:00',
    items: [
      { desc: 'ค่าห้องสัมมนาและอาหาร', amount: 15000 },
    ],
    status: 'cleared',
    paidAt: '2026-04-21T09:00:00',
    paidAmount: 15000,
    actualTotal: 13750,
    clearedAt: '2026-04-30T16:00:00',
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-04-15T10:00:00' },
      { type: 'approve', who: USERS.manager, role: 'manager', at: '2026-04-15T14:00:00' },
      { type: 'approve', who: USERS.director, role: 'director', at: '2026-04-16T09:00:00' },
      { type: 'approve', who: USERS.finance, role: 'finance', at: '2026-04-20T08:00:00' },
      { type: 'paid', who: USERS.finance, at: '2026-04-21T09:00:00' },
      { type: 'clear', who: USERS.staff, at: '2026-04-30T14:00:00', note: 'ส่งใบเสร็จและคืนเงิน 1,250 บาท' },
      { type: 'close', who: USERS.finance, at: '2026-04-30T16:00:00' },
    ],
  },
  {
    id: 'PCR-2026-0411',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'ของรางวัลแคมเปญลูกค้าใหม่ ไตรมาส 1',
    startDate: '2026-04-01',
    dueDate: '2026-04-15',
    submittedAt: '2026-03-28T13:00:00',
    items: [
      { desc: 'บัตรกำนัล Central 50 ใบ', amount: 50000 },
    ],
    status: 'rejected',
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-03-28T13:00:00' },
      { type: 'reject', who: USERS.manager, role: 'manager', at: '2026-03-29T09:00:00', note: 'ขอให้แบ่งของรางวัลเป็นมูลค่าย่อยกว่านี้ และระบุเงื่อนไขแคมเปญให้ชัดเจน' },
    ],
  },
  {
    id: 'PCR-2026-0435',
    type: 'request',
    requester: USERS.staff,
    dept: 'MKT-01',
    purpose: 'ค่าใช้จ่ายเตรียมงานแถลงข่าวประจำไตรมาส 2',
    startDate: '2026-05-25',
    dueDate: '2026-06-10',
    submittedAt: '2026-05-17T08:30:00',
    items: [
      { desc: 'ค่าห้องประชุมและอุปกรณ์', amount: 18000 },
      { desc: 'ค่าอาหารสื่อมวลชน', amount: 9500 },
    ],
    status: 'pending_mgr',
    timeline: [
      { type: 'submit', who: USERS.staff, at: '2026-05-17T08:30:00' },
    ],
  },
];

// ---------- ICONS (Lucide-like inline) ----------
const Icon = ({ name, size=18, stroke=1.8, className='' }) => {
  const paths = {
    home: <><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V20a1 1 0 0 0 1 1h4v-6h4v6h4a1 1 0 0 0 1-1V9.5"/></>,
    inbox: <><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z"/></>,
    file: <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></>,
    fileText: <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" x2="15" y1="13" y2="13"/><line x1="9" x2="15" y1="17" y2="17"/></>,
    fileCheck: <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><path d="m9 15 2 2 4-4"/></>,
    plus: <><line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/></>,
    search: <><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></>,
    bell: <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></>,
    chevDown: <polyline points="6 9 12 15 18 9"/>,
    chevRight: <polyline points="9 18 15 12 9 6"/>,
    chevLeft: <polyline points="15 18 9 12 15 6"/>,
    arrowUp: <><line x1="12" x2="12" y1="19" y2="5"/><polyline points="5 12 12 5 19 12"/></>,
    arrowDown: <><line x1="12" x2="12" y1="5" y2="19"/><polyline points="19 12 12 19 5 12"/></>,
    arrowLeft: <><line x1="19" x2="5" y1="12" y2="12"/><polyline points="12 19 5 12 12 5"/></>,
    arrowRight: <><line x1="5" x2="19" y1="12" y2="12"/><polyline points="12 5 19 12 12 19"/></>,
    check: <polyline points="20 6 9 17 4 12"/>,
    x: <><line x1="18" x2="6" y1="6" y2="18"/><line x1="6" x2="18" y1="6" y2="18"/></>,
    close: <><line x1="18" x2="6" y1="6" y2="18"/><line x1="6" x2="18" y1="6" y2="18"/></>,
    trash: <><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></>,
    download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></>,
    upload: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></>,
    paperclip: <path d="M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/>,
    image: <><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></>,
    user: <><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
    users: <><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z"/></>,
    money: <><line x1="12" x2="12" y1="2" y2="22"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></>,
    wallet: <><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12a2 2 0 0 0 0 4h4v-4Z"/></>,
    clock: <><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></>,
    calendar: <><rect width="18" height="18" x="3" y="4" rx="2" ry="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/></>,
    edit: <><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z"/></>,
    eye: <><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></>,
    filter: <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>,
    sortDesc: <><path d="M3 5h13"/><path d="M3 12h9"/><path d="M3 19h5"/><path d="M19 5v14"/><path d="m16 16 3 3 3-3"/></>,
    refresh: <><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></>,
    info: <><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="16" y2="12"/><line x1="12" x2="12.01" y1="8" y2="8"/></>,
    alert: <><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" x2="12" y1="9" y2="13"/><line x1="12" x2="12.01" y1="17" y2="17"/></>,
    checkCircle: <><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></>,
    send: <><line x1="22" x2="11" y1="2" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></>,
    swap: <><path d="M16 3h5v5"/><path d="M4 20 21 3"/><path d="M21 16v5h-5"/><path d="M15 15l6 6"/><path d="m4 4 5 5"/></>,
    chart: <><line x1="18" x2="18" y1="20" y2="10"/><line x1="12" x2="12" y1="20" y2="4"/><line x1="6" x2="6" y1="20" y2="14"/></>,
    list: <><line x1="8" x2="21" y1="6" y2="6"/><line x1="8" x2="21" y1="12" y2="12"/><line x1="8" x2="21" y1="18" y2="18"/><line x1="3" x2="3.01" y1="6" y2="6"/><line x1="3" x2="3.01" y1="12" y2="12"/><line x1="3" x2="3.01" y1="18" y2="18"/></>,
    receipt: <><path d="M4 2v20l2-2 2 2 2-2 2 2 2-2 2 2 2-2 2 2V2l-2 2-2-2-2 2-2-2-2 2-2-2-2 2Z"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 17.5v-11"/></>,
    history: <><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M12 7v5l4 2"/></>,
    save: <><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></>,
    logout: <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></>,
    more: <><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></>,
    moreV: <><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></>,
    copy: <><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></>,
    printer: <><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect width="12" height="8" x="6" y="14"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" className={className}>
      {paths[name] || null}
    </svg>
  );
};

Object.assign(window, {
  React, useState, useEffect, useMemo, useRef, useCallback,
  fmtMoney, fmtDate, fmtDateTime, todayISO, addDays, sumItems, sumActual,
  DEPARTMENTS, USERS, ROLE_META, STATUS_META, statusBadge, SEED_REQUESTS,
  Icon,
});
