# -*- coding: utf-8 -*-
"""
Cloud POS Sync Server & Web Management Portal 24/24 (Python Backend)
Hỗ trợ đầy đủ 9 phân hệ đồng bộ 2 chiều với Desktop App OfflinePOS (.exe):
1. Tổng quan (Dashboard)
2. Bán hàng POS trực tiếp trên Web (Web POS)
3. Đơn bán hàng (Invoices)
4. Nhập hàng từ NCC (Purchases)
5. Kho & Danh mục hàng hóa (Inventory)
6. Khách hàng & Nhà cung cấp (Partners)
7. Sổ quỹ Thu - Chi (Finance)
8. Báo cáo thống kê (Reports)
9. Quản lý Nhân sự & Chấm công (HR: Hồ sơ NV, Chấm công, Tạm ứng, Bảng lương)
10. Cài đặt & Đồng bộ 2 chiều (Sync & Pending Events)
"""

import os
import sys
import json
import gzip
import sqlite3
import argparse
import time
from datetime import datetime, date, timedelta
from pathlib import Path
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs

# Thiết lập thư mục gốc
BASE_DIR = Path(__file__).resolve().parent
DB_FILE = BASE_DIR / "cloud_pos.db"
ATT_DB_FILE = BASE_DIR / "cloud_attendance.db"
META_FILE = BASE_DIR / "sync_meta.json"
EVENTS_FILE = BASE_DIR / "cloud_pending_events.json"

DEFAULT_SECRET = "cuahang123"

def get_server_secret() -> str:
    if "SYNC_SECRET_KEY" in os.environ:
        return os.environ["SYNC_SECRET_KEY"].strip()
    if META_FILE.exists():
        try:
            with open(META_FILE, "r", encoding="utf-8") as f:
                data = json.load(f)
                return data.get("sync_secret", DEFAULT_SECRET).strip()
        except Exception:
            pass
    return DEFAULT_SECRET

def set_server_secret(new_secret: str):
    meta = get_meta()
    meta["sync_secret"] = new_secret.strip()
    save_meta(meta)

def get_meta() -> dict:
    if META_FILE.exists():
        try:
            with open(META_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except Exception:
            pass
    return {
        "last_sync_time": "Chưa có dữ liệu",
        "sync_count": 0,
        "store_name": "CỬA HÀNG ĐA NGÀNH",
        "sync_secret": DEFAULT_SECRET,
        "store_wifi_ips": ""
    }

def save_meta(data: dict):
    try:
        with open(META_FILE, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
    except Exception as e:
        print(f"Error saving meta: {e}")

# -----------------------------------------------------------------------------
# CLOUD PENDING EVENTS (DONG BO 2 CHIEU VE APP .EXE)
# -----------------------------------------------------------------------------
def get_pending_events() -> list:
    if EVENTS_FILE.exists():
        try:
            with open(EVENTS_FILE, "r", encoding="utf-8") as f:
                return json.load(f)
        except Exception:
            pass
    return []

def save_pending_events(events: list):
    try:
        with open(EVENTS_FILE, "w", encoding="utf-8") as f:
            json.dump(events, f, ensure_ascii=False, indent=2)
    except Exception as e:
        print(f"Error saving events: {e}")

def record_cloud_event(entity_type: str, action: str, entity_id: str, payload: dict) -> int:
    event_id = int(time.time() * 1000)
    ev = {
        "id": event_id,
        "entity_type": entity_type,
        "action": action,
        "entity_id": str(entity_id or ""),
        "payload": payload,
        "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    events = get_pending_events()
    events.append(ev)
    save_pending_events(events)

    if DB_FILE.exists():
        try:
            conn = get_sqlite_conn(DB_FILE)
            cur = conn.cursor()
            cur.execute("""
                CREATE TABLE IF NOT EXISTS cloud_sync_events (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    entity_type TEXT NOT NULL,
                    action TEXT NOT NULL,
                    entity_id TEXT,
                    payload TEXT NOT NULL,
                    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                    is_synced_to_desktop INTEGER DEFAULT 0
                )
            """)
            cur.execute("""
                INSERT INTO cloud_sync_events (id, entity_type, action, entity_id, payload, created_at, is_synced_to_desktop)
                VALUES (?, ?, ?, ?, ?, ?, 0)
            """, (event_id, entity_type, action, str(entity_id or ""), json.dumps(payload, ensure_ascii=False), ev["created_at"]))
            conn.commit()
            conn.close()
        except Exception:
            pass
    return event_id

def get_sqlite_conn(path: Path) -> sqlite3.Connection:
    conn = sqlite3.connect(str(path), timeout=30.0)
    conn.execute("PRAGMA journal_mode = WAL;")
    conn.execute("PRAGMA busy_timeout = 30000;")
    conn.execute("PRAGMA synchronous = NORMAL;")
    return conn

def get_db_connection() -> sqlite3.Connection:
    if not DB_FILE.exists():
        return None
    try:
        return get_sqlite_conn(DB_FILE)
    except Exception as e:
        print(f"Database connection error: {e}")
        return None

def ensure_hr_tables(conn: sqlite3.Connection):
    try:
        cur = conn.cursor()
        cur.executescript("""
            CREATE TABLE IF NOT EXISTS employees (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                code TEXT NOT NULL UNIQUE,
                full_name TEXT NOT NULL,
                phone TEXT,
                position TEXT DEFAULT 'Nhân viên',
                username TEXT NOT NULL UNIQUE,
                password_hash TEXT NOT NULL,
                password_plain TEXT,
                base_salary REAL DEFAULT 0.0,
                hourly_rate REAL DEFAULT 0.0,
                commission_rate REAL DEFAULT 0.0,
                insurance_amount REAL DEFAULT 0.0,
                allowance_amount REAL DEFAULT 0.0,
                allowance_details TEXT,
                ot_multiplier REAL DEFAULT 1.5,
                is_active INTEGER DEFAULT 1,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
            );
            CREATE TABLE IF NOT EXISTS hr_salary_advances (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                month_year TEXT NOT NULL,
                employee_code TEXT NOT NULL,
                advance_date TEXT NOT NULL,
                amount REAL NOT NULL DEFAULT 0,
                reason TEXT,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP
            );
            CREATE TABLE IF NOT EXISTS hr_payrolls (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                month_year TEXT NOT NULL,
                employee_code TEXT NOT NULL,
                standard_work_days REAL DEFAULT 24.0,
                actual_work_days REAL DEFAULT 0.0,
                actual_hours REAL DEFAULT 0.0,
                base_salary REAL DEFAULT 0.0,
                hourly_rate REAL DEFAULT 0.0,
                salary_amount REAL DEFAULT 0.0,
                allowance_amount REAL DEFAULT 0.0,
                ot_amount REAL DEFAULT 0.0,
                insurance_deduction REAL DEFAULT 0.0,
                advance_deduction REAL DEFAULT 0.0,
                net_salary REAL DEFAULT 0.0,
                payment_status TEXT DEFAULT 'Chưa chi',
                note TEXT,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
            );
            CREATE TABLE IF NOT EXISTS attendance_logs (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                remote_id INTEGER,
                employee_id INTEGER,
                employee_code TEXT NOT NULL,
                employee_name TEXT NOT NULL,
                work_date TEXT NOT NULL,
                check_in_time TEXT,
                check_out_time TEXT,
                total_hours REAL DEFAULT 0.0,
                ip_address TEXT,
                status TEXT DEFAULT 'Hợp lệ',
                note TEXT,
                synced INTEGER DEFAULT 0,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
            );
            CREATE TABLE IF NOT EXISTS cloud_sync_events (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                entity_type TEXT NOT NULL,
                action TEXT NOT NULL,
                entity_id TEXT,
                payload TEXT NOT NULL,
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                is_synced_to_desktop INTEGER DEFAULT 0
            );
            CREATE INDEX IF NOT EXISTS idx_att_date ON attendance_logs (work_date);
            CREATE INDEX IF NOT EXISTS idx_att_emp ON attendance_logs (employee_code);
        """)
        conn.commit()
    except Exception as e:
        print(f"ensure_hr_tables error: {e}")

def query_dashboard_data(conn: sqlite3.Connection) -> dict:
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()
    ensure_hr_tables(conn)
    today_str = datetime.now().strftime("%Y-%m-%d")

    # 1. Doanh thu & Lợi nhuận hôm nay
    cursor.execute("""
        SELECT 
            COALESCE(SUM(total_amount), 0) as today_revenue,
            COALESCE(SUM(total_cost), 0) as today_cogs,
            COALESCE(SUM(paid_amount), 0) as today_paid,
            COALESCE(SUM(remaining_debt), 0) as today_debt,
            COUNT(id) as today_invoices
        FROM sales_invoices
        WHERE status = 'COMPLETED' AND date(invoice_date) = date(?)
    """, (today_str,))
    today_inv = dict(cursor.fetchone() or {})
    today_rev = float(today_inv.get("today_revenue", 0))
    today_cogs = float(today_inv.get("today_cogs", 0))
    today_profit = today_rev - today_cogs

    # 2. Toàn bộ doanh số
    cursor.execute("""
        SELECT 
            COALESCE(SUM(total_amount), 0) as total_revenue,
            COUNT(id) as total_invoices
        FROM sales_invoices
        WHERE status = 'COMPLETED'
    """)
    all_inv = dict(cursor.fetchone() or {})

    # 3. Tiền mặt & Ngân hàng
    cursor.execute("SELECT id, name, account_type, current_balance FROM cash_accounts WHERE is_active = 1")
    accounts = [dict(r) for r in cursor.fetchall()]
    total_cash = sum(float(a["current_balance"]) for a in accounts if a["account_type"] == "CASH")
    total_bank = sum(float(a["current_balance"]) for a in accounts if a["account_type"] == "BANK")

    # 4. Công nợ
    cursor.execute("SELECT COALESCE(SUM(current_debt), 0) FROM customers WHERE is_active = 1")
    customer_debt = float(cursor.fetchone()[0])
    cursor.execute("SELECT COALESCE(SUM(current_debt), 0) FROM suppliers WHERE is_active = 1")
    supplier_debt = float(cursor.fetchone()[0])

    # 5. Tồn kho & Cảnh báo
    cursor.execute("SELECT COALESCE(SUM(quantity * cost_price), 0) FROM stock_balances")
    inventory_value = float(cursor.fetchone()[0])
    cursor.execute("""
        SELECT COUNT(p.id) 
        FROM products p
        LEFT JOIN stock_balances sb ON p.id = sb.product_id
        WHERE p.is_active = 1 AND ((p.min_stock > 0 AND COALESCE(sb.quantity, 0) <= p.min_stock) OR (COALESCE(sb.quantity, 0) <= 0))
    """)
    low_stock_count = int(cursor.fetchone()[0])

    # 6. Đơn bán hàng gần nhất
    cursor.execute("""
        SELECT 
            i.id, i.code, i.invoice_date, i.total_amount, i.paid_amount, 
            i.remaining_debt, i.payment_method, i.status,
            c.name as customer_name, c.phone as customer_phone,
            COALESCE(u.full_name, u.username, 'Admin') as cashier_name
        FROM sales_invoices i
        LEFT JOIN customers c ON i.customer_id = c.id
        LEFT JOIN users u ON i.user_id = u.id
        ORDER BY i.id DESC
        LIMIT 50
    """)
    recent_invoices = [dict(r) for r in cursor.fetchall()]

    # 7. Nhập hàng gần nhất
    cursor.execute("""
        SELECT 
            p.id, p.code, p.receipt_date, p.total_amount, p.paid_amount, 
            p.remaining_debt, p.payment_method, p.status,
            s.name as supplier_name
        FROM purchase_receipts p
        LEFT JOIN suppliers s ON p.supplier_id = s.id
        ORDER BY p.id DESC
        LIMIT 30
    """)
    recent_purchases = [dict(r) for r in cursor.fetchall()]

    # 8. Danh mục hàng hóa
    cursor.execute("""
        SELECT 
            p.id, p.code, p.barcode, p.name, 
            COALESCE(c.name, 'Chưa phân loại') as category_name,
            COALESCE(u.name, 'Cái') as unit_name,
            p.cost_price, p.retail_price, p.wholesale_price,
            COALESCE(sb.quantity, 0) as stock_qty,
            p.min_stock
        FROM products p
        LEFT JOIN product_categories c ON p.category_id = c.id
        LEFT JOIN units u ON p.base_unit_id = u.id
        LEFT JOIN stock_balances sb ON p.id = sb.product_id
        WHERE p.is_active = 1
        ORDER BY p.name ASC
        LIMIT 500
    """)
    products = [dict(r) for r in cursor.fetchall()]

    # 9. Khách hàng
    cursor.execute("SELECT id, code, name, phone, address, current_debt FROM customers WHERE is_active = 1 AND current_debt > 0 ORDER BY current_debt DESC LIMIT 100")
    debt_customers = [dict(r) for r in cursor.fetchall()]
    cursor.execute("SELECT id, code, name, phone, address, current_debt FROM customers WHERE is_active = 1 ORDER BY name ASC LIMIT 300")
    all_customers = [dict(r) for r in cursor.fetchall()]

    # 10. Nhà cung cấp
    cursor.execute("SELECT id, code, name, phone, current_debt FROM suppliers WHERE is_active = 1 AND current_debt > 0 ORDER BY current_debt DESC LIMIT 100")
    debt_suppliers = [dict(r) for r in cursor.fetchall()]
    cursor.execute("SELECT id, code, name, phone, current_debt FROM suppliers WHERE is_active = 1 ORDER BY name ASC LIMIT 300")
    all_suppliers = [dict(r) for r in cursor.fetchall()]

    # 11. Sổ quỹ
    cursor.execute("""
        SELECT 
            t.id, t.code, t.trans_type, t.created_at, t.category, 
            t.amount, t.partner_name, t.note,
            a.name as account_name
        FROM cash_transactions t
        LEFT JOIN cash_accounts a ON t.account_id = a.id
        ORDER BY t.id DESC
        LIMIT 50
    """)
    recent_transactions = [dict(r) for r in cursor.fetchall()]

    # 12. Danh mục & Đơn vị & Nhân sự
    cursor.execute("SELECT id, name FROM product_categories ORDER BY name ASC")
    categories = [dict(r) for r in cursor.fetchall()]
    cursor.execute("SELECT id, name FROM units ORDER BY name ASC")
    units = [dict(r) for r in cursor.fetchall()]

    cursor.execute("""
        SELECT id, code, full_name, phone, position, username, password_plain,
               base_salary, hourly_rate, insurance_amount, allowance_amount,
               allowance_details, ot_multiplier, is_active
        FROM employees WHERE is_active = 1 ORDER BY full_name ASC
    """)
    employees = [dict(r) for r in cursor.fetchall()]

    cursor.execute("""
        SELECT a.id, a.month_year, a.employee_code, a.advance_date, a.amount, a.reason,
               e.full_name as employee_name
        FROM hr_salary_advances a
        LEFT JOIN employees e ON UPPER(a.employee_code) = UPPER(e.code)
        ORDER BY a.id DESC LIMIT 100
    """)
    salary_advances = [dict(r) for r in cursor.fetchall()]

    cursor.execute("""
        SELECT p.*, e.full_name as employee_name
        FROM hr_payrolls p
        LEFT JOIN employees e ON UPPER(p.employee_code) = UPPER(e.code)
        ORDER BY p.month_year DESC, p.id DESC LIMIT 100
    """)
    payrolls = [dict(r) for r in cursor.fetchall()]

    # 13. Tên cửa hàng
    cursor.execute("SELECT key, value FROM app_settings WHERE key IN ('store_name', 'store_phone', 'store_address')")
    settings_map = {r[0]: r[1] for r in cursor.fetchall()}
    store_name = settings_map.get("store_name", "CỬA HÀNG ĐA NGÀNH")

    # 14. 7 days financial chart data
    c_today = date.today()
    c_dates = [(c_today - timedelta(days=i)).strftime('%Y-%m-%d') for i in reversed(range(7))]
    c_cats = [(c_today - timedelta(days=i)).strftime('%d/%m') for i in reversed(range(7))]
    c_start = c_dates[0]

    cursor.execute("""
        SELECT substr(invoice_date, 1, 10) as dt,
               COALESCE(SUM(total_amount), 0) as rev,
               COALESCE(SUM(total_cost), 0) as cogs
        FROM sales_invoices
        WHERE status = 'COMPLETED' AND substr(invoice_date, 1, 10) >= ?
        GROUP BY substr(invoice_date, 1, 10)
    """, (c_start,))
    c_rev_map = {r[0]: (float(r[1]), float(r[2])) for r in cursor.fetchall()}

    cursor.execute("""
        SELECT substr(created_at, 1, 10) as dt,
               COALESCE(SUM(CASE WHEN trans_type = 'THU' THEN amount ELSE 0 END), 0) as cash_in,
               COALESCE(SUM(CASE WHEN trans_type = 'CHI' THEN amount ELSE 0 END), 0) as cash_out
        FROM cash_transactions
        WHERE substr(created_at, 1, 10) >= ?
        GROUP BY substr(created_at, 1, 10)
    """, (c_start,))
    c_cash_map = {r[0]: (float(r[1]), float(r[2])) for r in cursor.fetchall()}

    c_revs, c_cogs, c_profits, c_ins, c_outs = [], [], [], [], []
    for dt in c_dates:
        rv, cg = c_rev_map.get(dt, (0.0, 0.0))
        cin, cout = c_cash_map.get(dt, (0.0, 0.0))
        c_revs.append(round(rv, 2))
        c_cogs.append(round(cg, 2))
        c_profits.append(round(rv - cg, 2))
        c_ins.append(round(cin, 2))
        c_outs.append(round(cout, 2))

    chart_data = {
        "categories": c_cats,
        "dates": c_dates,
        "revenues": c_revs,
        "cogs": c_cogs,
        "profits": c_profits,
        "cash_ins": c_ins,
        "cash_outs": c_outs,
        "total_revenue": sum(c_revs),
        "total_profit": sum(c_profits),
        "total_cash_in": sum(c_ins),
        "total_cash_out": sum(c_outs)
    }

    res = {
        "store_name": store_name,
        "store_phone": settings_map.get("store_phone", ""),
        "store_address": settings_map.get("store_address", ""),
        "today": {
            "date": today_str,
            "revenue": today_rev,
            "cogs": today_cogs,
            "profit": today_profit,
            "invoices": today_inv.get("today_invoices", 0),
            "paid": float(today_inv.get("today_paid", 0)),
            "debt": float(today_inv.get("today_debt", 0))
        },
        "all_time": {
            "revenue": float(all_inv.get("total_revenue", 0)),
            "invoices": int(all_inv.get("total_invoices", 0))
        },
        "finance": {
            "cash": total_cash,
            "bank": total_bank,
            "customer_debt": customer_debt,
            "supplier_debt": supplier_debt,
            "accounts": accounts
        },
        "chart_data": chart_data,
        "inventory": {
            "total_value": inventory_value,
            "low_stock_count": low_stock_count
        },
        "recent_invoices": recent_invoices,
        "recent_purchases": recent_purchases,
        "products": products,
        "debt_customers": debt_customers,
        "all_customers": all_customers,
        "debt_suppliers": debt_suppliers,
        "all_suppliers": all_suppliers,
        "recent_transactions": recent_transactions,
        "attendance_logs": [],
        "categories": categories,
        "units": units,
        "employees": employees,
        "salary_advances": salary_advances,
        "payrolls": payrolls
    }

    if ATT_DB_FILE.exists():
        try:
            c_att = get_sqlite_conn(ATT_DB_FILE)
            c_att.row_factory = sqlite3.Row
            c_att_cur = c_att.cursor()
            c_att_cur.execute("SELECT * FROM attendance_logs ORDER BY work_date DESC, id DESC LIMIT 200")
            res["attendance_logs"] = [dict(r) for r in c_att_cur.fetchall()]
            c_att.close()
        except Exception:
            pass
    if not res["attendance_logs"]:
        try:
            cursor.execute("SELECT * FROM attendance_logs ORDER BY work_date DESC, id DESC LIMIT 200")
            res["attendance_logs"] = [dict(r) for r in cursor.fetchall()]
        except Exception:
            pass

    return res

def get_invoice_items(conn: sqlite3.Connection, invoice_id: int) -> list:
    cursor = conn.cursor()
    cursor.execute("""
        SELECT 
            item.id, item.product_id, item.unit_name, item.quantity, 
            item.unit_price, item.discount_amount, item.line_total, item.note,
            p.name as product_name, p.code as product_code
        FROM sales_invoice_items item
        LEFT JOIN products p ON item.product_id = p.id
        WHERE item.invoice_id = ?
        ORDER BY item.id ASC
    """, (invoice_id,))
    return [dict(r) for r in cursor.fetchall()]

def get_purchase_items(conn: sqlite3.Connection, receipt_id: int) -> list:
    cursor = conn.cursor()
    cursor.execute("""
        SELECT 
            item.id, item.product_id, item.unit_name, item.quantity, 
            item.unit_cost as unit_price, item.line_total,
            p.name as product_name, p.code as product_code
        FROM purchase_receipt_items item
        LEFT JOIN products p ON item.product_id = p.id
        WHERE item.receipt_id = ?
        ORDER BY item.id ASC
    """, (receipt_id,))
    return [dict(r) for r in cursor.fetchall()]

HTML_PORTAL = r"""<!DOCTYPE html>
<html lang="vi" class="light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no, viewport-fit=cover">
    <title>Tạp Hóa Số - Quản Lý Bán Hàng Trực Tuyến 24/24</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
    <style>
        :root {
            --background: #fcfdfe;
            --foreground: #09131a;
            --card: #ffffff;
            --card-foreground: #09131a;
            --popover: #ffffff;
            --popover-foreground: #09131a;
            --primary: #e1773b;
            --primary-hover: #cf6528;
            --primary-light: rgba(225, 119, 59, 0.12);
            --primary-foreground: #ffffff;
            --secondary: #eff2f6;
            --secondary-foreground: #121c23;
            --muted: #f1f4f8;
            --muted-foreground: #5a6672;
            --accent: #e2f1fc;
            --accent-foreground: #142f4b;
            --destructive: #df2225;
            --destructive-light: #fef2f2;
            --destructive-foreground: #ffffff;
            --success: #16a34a;
            --success-light: #ecfdf5;
            --border: #d8dfe4;
            --border-light: #edf2f6;
            --input: #d8dfe4;
            --ring: #e1773b;
            --radius: 0.65rem;
            --sidebar: #f9fafc;
            --sidebar-foreground: #09131a;
            --sidebar-border: #d8dfe4;
            --sidebar-accent: #f0f3f6;
            --sidebar-accent-foreground: #09131a;
            --sidebar-width: 256px;
        }

        * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
        html, body {
            width: 100%;
            max-width: 100%;
            overflow-x: hidden;
            touch-action: manipulation;
            -webkit-text-size-adjust: 100%;
            -ms-text-size-adjust: 100%;
            -webkit-tap-highlight-color: transparent;
            position: relative;
        }
        body { background: var(--background); color: var(--foreground); min-height: 100vh; display: flex; text-rendering: optimizeLegibility; }
        input, select, textarea, button {
            touch-action: manipulation;
            font-size: 16px;
        }
        @media (min-width: 769px) {
            input, select, textarea, button {
                font-size: 13.5px;
            }
        }

        /* Left Sidebar (MOSMind Layout) */
        aside.sidebar {
            width: var(--sidebar-width);
            min-width: var(--sidebar-width);
            background: var(--sidebar);
            border-right: 1px solid var(--sidebar-border);
            display: flex;
            flex-direction: column;
            position: fixed;
            top: 0; bottom: 0; left: 0;
            z-index: 100;
            transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .sidebar-brand {
            height: 64px;
            padding: 0 18px;
            display: flex;
            align-items: center;
            gap: 12px;
            border-bottom: 1px solid var(--sidebar-border);
            background: var(--sidebar);
        }
        .brand-logo-badge {
            width: 38px;
            height: 38px;
            min-width: 38px;
            background: linear-gradient(135deg, #e1773b 0%, #ff9557 100%);
            color: #ffffff;
            font-weight: 800;
            font-size: 15px;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 4px 12px rgba(225, 119, 59, 0.3);
            letter-spacing: -0.5px;
        }
        .brand-meta {
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        .brand-name {
            font-size: 15px;
            font-weight: 800;
            color: var(--foreground);
            letter-spacing: -0.3px;
            line-height: 1.2;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        .brand-badge-pill {
            font-size: 9px;
            font-weight: 800;
            background: var(--primary-light);
            color: var(--primary);
            padding: 2px 6px;
            border-radius: 4px;
            text-transform: uppercase;
        }
        .brand-sub {
            font-size: 11px;
            font-weight: 600;
            color: var(--muted-foreground);
            margin-top: 1px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .sidebar-nav {
            flex: 1;
            overflow-y: auto;
            padding: 12px 10px;
        }
        .nav-section-title {
            padding: 14px 12px 6px 12px;
            font-size: 10.5px;
            font-weight: 700;
            color: var(--muted-foreground);
            letter-spacing: 0.8px;
            text-transform: uppercase;
        }
        .nav-item {
            display: flex;
            align-items: center;
            gap: 11px;
            padding: 9.5px 12px;
            margin: 2px 0;
            border-radius: 8px;
            color: var(--muted-foreground);
            font-size: 13.5px;
            font-weight: 600;
            text-decoration: none;
            cursor: pointer;
            transition: all 0.15s ease;
            background: transparent;
            border: none;
            width: 100%;
            text-align: left;
        }
        .nav-item:hover {
            background: var(--sidebar-accent);
            color: var(--foreground);
        }
        .nav-item.active {
            background: var(--primary-light);
            color: var(--primary);
            font-weight: 700;
        }
        .nav-item svg {
            width: 18px;
            height: 18px;
            stroke: currentColor;
            flex-shrink: 0;
            transition: stroke 0.15s;
        }
        .nav-item.active svg {
            stroke: var(--primary);
        }
        .title-svg {
            width: 19px;
            height: 19px;
            stroke: var(--primary);
            flex-shrink: 0;
        }
        .btn-icon {
            width: 14px;
            height: 14px;
            stroke: currentColor;
            flex-shrink: 0;
            display: inline-block;
            vertical-align: middle;
        }
        .kpi-icon-badge {
            width: 32px;
            height: 32px;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        .kpi-icon-badge svg {
            width: 17px;
            height: 17px;
            stroke: currentColor;
            stroke-width: 2.2;
        }
        .kpi-badge-rev { background: #fff7ed; color: #e1773b; }
        .kpi-badge-profit { background: #ecfdf5; color: #16a34a; }
        .kpi-badge-cash { background: #f0f9ff; color: #0284c7; }
        .kpi-badge-debt { background: #fef2f2; color: #dc2626; }
        .kpi-badge-stock { background: #f5f3ff; color: #8b5cf6; }
        .subtab-btn svg {
            width: 15px;
            height: 15px;
            stroke: currentColor;
            flex-shrink: 0;
        }
        .nav-item.active svg {
            stroke: var(--primary);
        }

        .sidebar-user {
            padding: 14px 16px;
            border-top: 1px solid var(--sidebar-border);
            display: flex;
            align-items: center;
            gap: 12px;
            background: #ffffff;
        }
        .user-avatar-box {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background: linear-gradient(135deg, #e1773b, #f97316);
            color: #fff;
            font-weight: 800;
            font-size: 13px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
            box-shadow: 0 2px 8px rgba(225, 119, 59, 0.25);
        }
        .user-name-txt { font-size: 13px; font-weight: 700; color: var(--foreground); line-height: 1.2; }
        .user-role-txt { font-size: 11px; color: var(--muted-foreground); font-weight: 500; }

        /* Workspace & Top Header (Tạp Hóa Số Design) */
        .workspace {
            margin-left: var(--sidebar-width);
            flex: 1;
            display: flex;
            flex-direction: column;
            min-width: 0;
            width: calc(100% - var(--sidebar-width));
            max-width: calc(100% - var(--sidebar-width));
            overflow-x: hidden;
            box-sizing: border-box;
            background: var(--background);
        }

        header.top-header {
            height: 60px;
            min-height: 60px;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(12px);
            border-bottom: 1px solid var(--border);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 18px;
            position: sticky;
            top: 0;
            z-index: 50;
            width: 100%;
            max-width: 100%;
            box-sizing: border-box;
            overflow: hidden;
        }
        .top-left {
            display: flex;
            align-items: center;
            gap: 10px;
            min-width: 0;
            flex: 1 1 auto;
            overflow: hidden;
        }
        .menu-toggle {
            display: none;
            background: #ffffff;
            border: 1px solid var(--border);
            border-radius: 8px;
            padding: 7px;
            cursor: pointer;
            color: var(--muted-foreground);
            flex-shrink: 0;
            width: 36px;
            height: 36px;
            align-items: center;
            justify-content: center;
        }
        .breadcrumb-box {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 13px;
            color: var(--muted-foreground);
            min-width: 0;
            overflow: hidden;
            white-space: nowrap;
        }
        .view-title-main {
            font-size: 14.5px;
            font-weight: 800;
            color: var(--foreground);
            letter-spacing: -0.2px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            display: block;
            min-width: 0;
        }

        .top-right {
            display: flex;
            align-items: center;
            gap: 8px;
            flex-shrink: 0;
        }
        .sync-time-short { display: none; }
        .bar-pill {
            height: 34px;
            padding: 0 12px;
            border-radius: 8px;
            font-size: 12.5px;
            font-weight: 600;
            display: inline-flex;
            align-items: center;
            gap: 7px;
            border: 1px solid var(--border);
            background: #ffffff;
            color: var(--foreground);
            white-space: nowrap;
        }
        .sync-pill-live {
            background: var(--success-light);
            border-color: #86efac;
            color: #15803d;
            font-weight: 700;
        }
        .pulse-dot-live {
            width: 8px;
            height: 8px;
            background: #16a34a;
            border-radius: 50%;
            display: inline-block;
            box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.7);
            animation: pulse-green 1.8s infinite;
        }
        @keyframes pulse-green {
            0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.7); }
            70% { transform: scale(1); box-shadow: 0 0 0 6px rgba(22, 163, 74, 0); }
            100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
        }
        @keyframes stockBlink {
            0%, 100% { background-color: #dc2626; color: #ffffff; border-color: #b91c1c; }
            50% { background-color: #ea580c; color: #ffffff; border-color: #c2410c; }
        }
        .badge-stock-blink {
            animation: stockBlink 1.2s infinite ease-in-out;
        }

        .btn-header {
            height: 34px;
            padding: 0 14px;
            border-radius: 8px;
            font-size: 12.5px;
            font-weight: 700;
            cursor: pointer;
            border: 1px solid transparent;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            text-decoration: none;
            transition: all 0.15s ease;
        }
        .btn-outline {
            background: #ffffff;
            border-color: var(--border);
            color: var(--foreground);
        }
        .btn-outline:hover { background: var(--muted); border-color: #cbd5e1; }
        .btn-primary {
            background: var(--primary);
            color: #ffffff;
            box-shadow: 0 2px 6px rgba(225, 119, 59, 0.25);
        }
        .btn-primary:hover { background: var(--primary-hover); transform: translateY(-1px); }
        .btn-success { background: var(--success); color: #fff; }
        .btn-success:hover { background: #15803d; }
        .btn-danger { background: var(--destructive); color: #fff; }
        .btn-danger:hover { background: #b91c1c; }
        .btn-logout {
            background: var(--destructive-light);
            color: #b91c1c;
            border-color: #fca5a5;
        }
        .btn-logout:hover { background: #fee2e2; }

        .clock-display-txt {
            font-size: 13.5px;
            font-weight: 700;
            color: var(--muted-foreground);
            font-family: 'JetBrains Mono', monospace;
            padding-left: 4px;
        }

        /* Content Area */
        main.content-area {
            padding: 20px 24px;
            flex: 1;
            width: 100%;
            max-width: 100%;
            overflow-x: hidden;
            box-sizing: border-box;
        }
        .tab-pane {
            display: none;
            width: 100%;
            max-width: 100%;
            box-sizing: border-box;
        }
        .tab-pane.active { display: block; }

        /* KPI Cards Grid (MOSMind Card Style) */
        .kpi-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 16px;
            margin-bottom: 24px;
        }
        .kpi-card {
            background: var(--card);
            border-radius: var(--radius);
            padding: 20px 22px;
            border: 1px solid var(--border);
            box-shadow: 0 1px 3px rgba(0,0,0,0.03);
            transition: all 0.2s ease;
            position: relative;
            overflow: hidden;
        }
        .kpi-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 16px rgba(0,0,0,0.06);
            border-color: #cbd5e1;
        }
        .kpi-card::before {
            content: '';
            position: absolute;
            top: 0; left: 0; right: 0;
            height: 3px;
            background: var(--primary);
            opacity: 0.85;
        }
        .kpi-card.kpi-rev::before { background: #e1773b; }
        .kpi-card.kpi-profit::before { background: #16a34a; }
        .kpi-card.kpi-cash::before { background: #0284c7; }
        .kpi-card.kpi-debt::before { background: #dc2626; }
        .kpi-card.kpi-stock::before { background: #8b5cf6; }

        .kpi-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }
        .kpi-title {
            font-size: 11.5px;
            font-weight: 700;
            color: var(--muted-foreground);
            text-transform: uppercase;
            letter-spacing: 0.6px;
        }
        .kpi-icon-badge {
            width: 28px;
            height: 28px;
            border-radius: 6px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 13px;
            background: var(--muted);
        }
        .kpi-value {
            font-size: 25px;
            font-weight: 800;
            color: var(--foreground);
            letter-spacing: -0.5px;
            line-height: 1.2;
        }
        .kpi-sub {
            font-size: 12.5px;
            margin-top: 6px;
            color: var(--muted-foreground);
            font-weight: 500;
        }

        /* Modern Excel & Data Cards */
        .card {
            background: var(--card);
            border-radius: var(--radius);
            border: 1px solid var(--border);
            box-shadow: 0 1px 3px rgba(0,0,0,0.03);
            margin-bottom: 24px;
            overflow: hidden;
        }
        .card-header {
            padding: 16px 22px;
            border-bottom: 1px solid var(--border);
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: #ffffff;
            gap: 14px;
            flex-wrap: wrap;
        }
        .card-title {
            font-size: 15px;
            font-weight: 800;
            color: var(--foreground);
            display: flex;
            align-items: center;
            gap: 8px;
            letter-spacing: -0.2px;
        }
        .search-input {
            height: 36px;
            padding: 0 14px 0 34px;
            border: 1px solid var(--border);
            border-radius: 8px;
            font-size: 13px;
            outline: none;
            width: 280px;
            background: #ffffff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cpath d='m21 21-4.3-4.3'%3E%3C/path%3E%3C/svg%3E") no-repeat 11px center;
            transition: all 0.15s ease;
        }
        .search-input:focus {
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(225, 119, 59, 0.15);
        }

        .table-responsive { width: 100%; overflow-x: auto; }
        table.excel-table {
            width: 100%;
            border-collapse: collapse;
            font-size: 13px;
            text-align: left;
        }
        table.excel-table th {
            background-color: #f8fafc;
            color: var(--muted-foreground);
            font-weight: 700;
            padding: 12px 16px;
            border-bottom: 1px solid var(--border);
            white-space: nowrap;
            font-size: 11.5px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        table.excel-table td {
            padding: 12px 16px;
            border-bottom: 1px solid var(--border-light);
            color: #334155;
            vertical-align: middle;
        }
        table.excel-table tr:hover td {
            background-color: #fbfcfe;
        }
        .text-right { text-align: right; }
        .text-center { text-align: center; }
        .font-mono { font-family: 'JetBrains Mono', monospace; font-size: 12.5px; font-weight: 700; }
        .font-bold { font-weight: 700; }

        .badge-pill {
            display: inline-flex;
            align-items: center;
            padding: 3px 10px;
            border-radius: 9999px;
            font-size: 11.5px;
            font-weight: 700;
            white-space: nowrap;
        }
        .badge-paid { background: #ecfdf5; color: #15803d; border: 1px solid #a7f3d0; }
        .badge-debt { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; }
        .badge-method { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; }
        .badge-bank { background: #e0f2fe; color: #0369a1; border: 1px solid #bae6fd; }

        .btn-act {
            padding: 5px 10px;
            border-radius: 6px;
            font-size: 12px;
            font-weight: 700;
            cursor: pointer;
            border: 1px solid transparent;
            display: inline-flex;
            align-items: center;
            gap: 4px;
            transition: all 0.15s;
        }
        .btn-act-edit { background: #e0f2fe; color: #0369a1; border-color: #bae6fd; }
        .btn-act-edit:hover { background: #bae6fd; }
        .btn-act-pay { background: #ecfdf5; color: #15803d; border-color: #86efac; }
        .btn-act-pay:hover { background: #bbf7d0; }
        .btn-act-del { background: #fef2f2; color: #b91c1c; border-color: #fca5a5; }
        .btn-act-del:hover { background: #fecaca; }
        .btn-act-view { background: #f1f5f9; color: #334155; border-color: #cbd5e1; }
        .btn-act-view:hover { background: #e2e8f0; }

        .subtab-bar { display: flex; gap: 8px; margin-bottom: 18px; border-bottom: 1px solid var(--border); padding-bottom: 10px; }
        .subtab-btn {
            padding: 8px 18px;
            background: #ffffff;
            border: 1px solid var(--border);
            border-radius: 8px;
            font-size: 13px;
            font-weight: 600;
            color: var(--muted-foreground);
            cursor: pointer;
            transition: all 0.15s;
        }
        .subtab-btn:hover { background: var(--muted); color: var(--foreground); }
        .subtab-btn.active {
            background: var(--primary);
            border-color: var(--primary);
            color: #ffffff;
            font-weight: 700;
            box-shadow: 0 2px 6px rgba(225, 119, 59, 0.25);
        }

        /* Modal dialogs (MOSMind Sheet/Modal Style) */
        .modal-overlay {
            position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(9, 19, 26, 0.55);
            backdrop-filter: blur(4px);
            display: none; align-items: center; justify-content: center; z-index: 1000; padding: 16px;
        }
        .modal-overlay.active { display: flex; }
        .modal-box {
            background: #ffffff;
            border-radius: 14px;
            width: 100%;
            max-width: 580px;
            max-height: 90vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            box-shadow: 0 20px 40px rgba(0,0,0,0.18);
            border: 1px solid var(--border);
            animation: modal-pop 0.2s cubic-bezier(0.16, 1, 0.3, 1);
        }
        @keyframes modal-pop {
            0% { opacity: 0; transform: scale(0.96) translateY(8px); }
            100% { opacity: 1; transform: scale(1) translateY(0); }
        }
        .modal-header {
            padding: 16px 22px;
            border-bottom: 1px solid var(--border);
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: #fbfcfd;
        }
        .modal-title { font-size: 15px; font-weight: 800; color: var(--foreground); }
        .modal-close {
            background: none; border: none; font-size: 20px; cursor: pointer; color: var(--muted-foreground);
            width: 32px; height: 32px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
        }
        .modal-close:hover { background: var(--muted); color: var(--foreground); }
        .modal-body { padding: 20px 22px; overflow-y: auto; }
        .modal-footer {
            padding: 14px 22px;
            border-top: 1px solid var(--border);
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            background: #fbfcfd;
        }

        .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
        .form-group { margin-bottom: 14px; }
        .form-label { display: block; font-size: 12.5px; font-weight: 700; color: #334155; margin-bottom: 6px; }
        .form-control {
            width: 100%;
            height: 38px;
            padding: 0 13px;
            border: 1px solid var(--input);
            border-radius: 8px;
            font-size: 13.5px;
            outline: none;
            background: #ffffff;
            transition: all 0.15s ease;
        }
        .form-control:focus {
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(225, 119, 59, 0.15);
        }

        /* Login Screen (Exact MOSMind Login Style) */
        #login-screen {
            position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: #f8fafc;
            display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 16px;
        }
        .login-card {
            background: #ffffff;
            border-radius: 16px;
            padding: 38px 40px;
            width: 100%;
            max-width: 440px;
            text-align: center;
            box-shadow: 0 10px 30px rgba(0,0,0,0.08);
            border: 1px solid var(--border);
            position: relative;
            overflow: hidden;
        }
        .login-card::before {
            content: '';
            position: absolute;
            top: -60px; right: -60px;
            width: 180px; height: 180px;
            border-radius: 50%;
            background: rgba(225, 119, 59, 0.12);
            filter: blur(40px);
        }
        .login-card-icon {
            width: 56px;
            height: 56px;
            background: linear-gradient(135deg, #e1773b 0%, #ff9557 100%);
            color: #fff;
            border-radius: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 22px;
            font-weight: 800;
            margin: 0 auto 18px auto;
            box-shadow: 0 6px 16px rgba(225, 119, 59, 0.3);
        }
        .login-card h2 { font-size: 20px; font-weight: 800; color: var(--foreground); margin-bottom: 8px; letter-spacing: -0.3px; }
        .login-card p { font-size: 13px; color: var(--muted-foreground); margin-bottom: 24px; line-height: 1.5; }
        .login-input {
            width: 100%;
            height: 44px;
            padding: 0 16px;
            border: 1.5px solid var(--border);
            border-radius: 10px;
            font-size: 14.5px;
            margin-bottom: 18px;
            outline: none;
            transition: all 0.15s;
        }
        .login-input:focus {
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(225, 119, 59, 0.15);
        }
        .btn-login-submit {
            width: 100%;
            height: 44px;
            background: var(--primary);
            color: #ffffff;
            border: none;
            border-radius: 10px;
            font-size: 14.5px;
            font-weight: 700;
            cursor: pointer;
            box-shadow: 0 4px 12px rgba(225, 119, 59, 0.28);
            transition: all 0.15s;
        }
        .btn-login-submit:hover { background: var(--primary-hover); transform: translateY(-1px); }

        /* Responsive Breakpoints */
        @media (max-width: 960px) {
            aside.sidebar { transform: translateX(-100%); box-shadow: 4px 0 20px rgba(0,0,0,0.15); width: 260px; max-width: 80vw; }
            aside.sidebar.mobile-open { transform: translateX(0); }
            .sidebar-backdrop { display: none; position: fixed; inset: 0; background: rgba(9, 19, 26, 0.5); backdrop-filter: blur(2px); z-index: 90; }
            .sidebar-backdrop.active { display: block; }
            .workspace { margin-left: 0 !important; width: 100% !important; max-width: 100vw !important; overflow-x: hidden !important; }
            main.content-area { padding: 12px 10px !important; width: 100% !important; max-width: 100vw !important; overflow-x: hidden !important; }
            .menu-toggle { display: inline-flex; }
            .bar-pill.pill-hide-mobile { display: none !important; }
            .clock-display-txt { display: none !important; }
            .kpi-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 10px; }
            .form-row { grid-template-columns: 1fr; }
        }

        @media (max-width: 768px) {
            header.top-header {
                height: 52px !important;
                min-height: 52px !important;
                padding: 0 8px !important;
            }
            .top-left {
                gap: 6px;
                flex: 1 1 auto;
                min-width: 0;
                overflow: hidden;
            }
            .menu-toggle {
                width: 32px;
                height: 32px;
                padding: 5px;
                border-radius: 6px;
            }
            .breadcrumb-box {
                flex: 1;
                min-width: 0;
            }
            .bc-crumb, .bc-sep {
                display: none !important;
            }
            .view-title-main {
                font-size: 13px !important;
                font-weight: 800;
                white-space: nowrap !important;
                overflow: hidden !important;
                text-overflow: ellipsis !important;
                display: block !important;
                max-width: 100% !important;
                line-height: 1.2;
            }
            .top-right {
                gap: 5px;
                flex-shrink: 0;
            }
            .sync-pill-live {
                height: 30px;
                padding: 0 6px;
                font-size: 11px;
                gap: 4px;
            }
            .sync-time-full {
                display: none !important;
            }
            .sync-time-short {
                display: inline !important;
            }
            .top-header .btn-header-txt {
                display: none !important;
            }
            .top-header .btn-header {
                height: 30px;
                min-width: 30px;
                padding: 0 6px;
                justify-content: center;
            }
            .top-header .btn-header .btn-icon {
                margin: 0;
                width: 15px;
                height: 15px;
            }
            .card {
                margin-bottom: 12px;
                border-radius: 10px;
            }
            .card-header {
                padding: 12px 10px;
                flex-direction: column;
                align-items: stretch;
                gap: 10px;
            }
            .card-title {
                font-size: 13.5px;
                width: 100%;
            }
            .card-header > div:last-child {
                display: flex;
                flex-wrap: wrap;
                gap: 6px;
                width: 100%;
            }
            .card-header .btn-header {
                flex: 1 1 calc(50% - 6px);
                height: 36px;
                padding: 0 8px;
                font-size: 12.5px;
                justify-content: center;
            }
            .search-input {
                width: 100% !important;
                max-width: 100%;
                height: 38px;
                font-size: 14px;
            }
            .kpi-grid {
                grid-template-columns: repeat(2, 1fr) !important;
                gap: 8px;
                margin-bottom: 12px;
            }
            .kpi-card {
                padding: 10px 12px;
            }
            .kpi-value {
                font-size: 15px;
            }
            .kpi-title {
                font-size: 11.5px;
            }
            .modal-box {
                width: 95% !important;
                max-width: 95% !important;
                padding: 14px !important;
                margin: 10px auto;
            }
            .table-responsive {
                width: 100%;
                max-width: 100%;
                overflow-x: auto;
                -webkit-overflow-scrolling: touch;
            }
            table.excel-table {
                min-width: 580px;
            }
        }

        @media (max-width: 480px) {
            .kpi-grid {
                grid-template-columns: 1fr 1fr !important;
                gap: 6px;
            }
            .kpi-card {
                padding: 8px 10px;
            }
            .kpi-value {
                font-size: 14px;
            }
            .kpi-title {
                font-size: 10.5px;
            }
        }
    </style>
</head>
<body>
    <!-- LOGIN SCREEN -->
    <div id="login-screen">
        <div class="login-card">
            <div class="login-card-icon">THS</div>
            <h2>Tạp Hóa Số</h2>
            <p>Hệ Thống Quản Lý <b>Tạp Hóa Số</b> 24/24<br>Nhập <b>Mã Bảo Mật</b> bạn đã đặt trong App .exe<br>(mục <i>Cài đặt &rarr; Đồng bộ Online</i>)</p>
            <input type="password" id="secret-input" class="login-input" placeholder="Nhập mã bảo mật (VD: cuahang123)..." onkeydown="if(event.key==='Enter') verifyLogin()">
            <button class="btn-login-submit" onclick="verifyLogin()">Đăng Nhập Quản Lý 24/24</button>
            <div id="login-error" style="color:#dc2626; font-size:12.5px; margin-top:14px; display:none; background:#fee2e2; padding:10px; border-radius:8px; font-weight:600;"></div>
        </div>
    </div>

    <!-- Mobile Backdrop -->
    <div class="sidebar-backdrop" id="sidebar-backdrop" onclick="toggleMobileSidebar()"></div>

    <!-- ASIDE SIDEBAR (MOSMind Style) -->
    <aside class="sidebar" id="app-sidebar">
        <div class="sidebar-brand">
            <div class="brand-logo-badge">THS</div>
            <div class="brand-meta">
                <div class="brand-name">
                    Tạp Hóa Số
                    <span class="brand-badge-pill">POS</span>
                </div>
                <div class="brand-sub">Quản Lý Bán Hàng 24/24</div>
            </div>
        </div>

        <nav class="sidebar-nav">
            <div class="nav-section-title">TỔNG QUAN</div>
            <button class="nav-item active" data-tab="dashboard" onclick="switchTab('dashboard')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></svg>
                <span>Tổng quan</span>
                <span id="nav-low-stock-badge" class="badge-stock-blink" style="display:none; margin-left:auto; font-size:10.5px; font-weight:800; padding:2px 7px; border-radius:10px; border:1px solid #b91c1c;"></span>
            </button>

            <div class="nav-section-title">QUẢN LÝ BÁN HÀNG</div>
            <button class="nav-item" data-tab="invoices" onclick="switchTab('invoices')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="21" r="1"/><circle cx="19" cy="21" r="1"/><path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12"/></svg>
                <span>Đơn bán hàng (24/24)</span>
            </button>
            <button class="nav-item" data-tab="purchases" onclick="switchTab('purchases')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2"/><path d="M15 18H9"/><path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14v10Z"/><circle cx="17" cy="18.5" r="2.5"/><circle cx="7" cy="18.5" r="2.5"/></svg>
                <span>Nhập hàng</span>
            </button>
            <button class="nav-item" data-tab="inventory" onclick="switchTab('inventory')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"/><path d="M12 22V12"/><polyline points="3.29 7 12 12 20.71 7"/><path d="m7.5 4.27 9 5.15"/></svg>
                <span>Kho & Hàng hóa</span>
            </button>

            <div class="nav-section-title">TÀI CHÍNH & ĐỐI TÁC</div>
            <button class="nav-item" data-tab="partners" onclick="switchTab('partners')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/></svg>
                <span>Khách hàng & NCC</span>
            </button>
            <button class="nav-item" data-tab="finance" onclick="switchTab('finance')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"/><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"/></svg>
                <span>Sổ quỹ Thu - Chi</span>
            </button>

            <div class="nav-section-title">NHÂN SỰ & CHẤM CÔNG</div>
            <button class="nav-item" data-tab="attendance" onclick="switchTab('attendance')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/><path d="m9 16 2 2 4-4"/></svg>
                <span>Bảng Chấm Công (24/24)</span>
            </button>
            <a href="?page=cham-cong" target="_blank" class="nav-item" style="color: #16a34a; font-weight: 700;">
                <svg viewBox="0 0 24 24" fill="none" stroke="#16a34a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><polyline points="16 11 18 13 22 9"/></svg>
                <span>Cổng Chấm Công NV</span>
                <svg class="opacity-60" style="width:13px; height:13px; margin-left:auto;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
            </a>

            <div class="nav-section-title">HỆ THỐNG</div>
            <button class="nav-item" data-tab="sync" onclick="switchTab('sync')">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
                <span>Thông tin & Đồng bộ</span>
            </button>
        </nav>

        <div class="sidebar-user">
            <div class="user-avatar-box"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg></div>
            <div style="overflow:hidden;">
                <div class="user-name-txt">Chủ Cửa Hàng</div>
                <div class="user-role-txt">Giám sát Online 24/24</div>
            </div>
        </div>
    </aside>

    <!-- MAIN WORKSPACE -->
    <div class="workspace">
        <header class="top-header">
            <div class="top-left">
                <button class="menu-toggle" onclick="toggleMobileSidebar()" aria-label="Toggle Menu">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
                </button>
                <div class="breadcrumb-box">
                    <span class="bc-crumb">Dashboard</span>
                    <span class="bc-sep">/</span>
                    <span class="view-title-main" id="main-view-title">TỔNG QUAN HỆ THỐNG (24/24)</span>
                </div>
            </div>

            <div class="top-right">
                <div class="bar-pill sync-pill-live">
                    <span class="pulse-dot-live"></span>
                    <span id="hdr-last-sync" class="sync-time-full">Cập nhật: --:--:--</span>
                    <span id="hdr-last-sync-short" class="sync-time-short">--:--:--</span>
                </div>
                <div class="bar-pill pill-hide-mobile" id="hdr-store-name">CỬA HÀNG ĐA NGÀNH</div>

                <button class="btn-header btn-outline" onclick="loadData(true)" title="Làm mới">
                    <svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg>
                    <span class="btn-header-txt">Làm mới</span>
                </button>
                <a href="?api=download-db" class="btn-header btn-primary pill-hide-mobile" id="btn-dl-db" download title="Tải SQLite">
                    <svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/><path d="M3 12c0 1.66 4 3 9 3s9-1.34 9-3"/><path d="M12 12v5m2.5-2.5L12 17l-2.5-2.5"/></svg>
                    <span class="btn-header-txt">Tải SQLite</span>
                </a>
                <button class="btn-header btn-logout" onclick="logout()" title="Đăng xuất">
                    <svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/></svg>
                    <span class="btn-header-txt">Đăng xuất</span>
                </button>
                <div class="clock-display-txt" id="header-clock">--:--:--</div>
            </div>
        </header>

        <main class="content-area">
            
            <!-- TAB: POS (BAN HANG TRUC TIEP TREN WEB) -->
            <div id="tab-pos" class="tab-pane">
                <div class="pos-wrapper">
                    <!-- Left: Products Catalog & Search -->
                    <div>
                        <div class="card" style="margin-bottom:12px; padding:12px;">
                            <div style="display:flex; gap:10px; align-items:center; flex-wrap:wrap;">
                                <div style="flex:1; min-width:240px; position:relative;">
                                    <input type="text" id="pos-search-input" class="search-input" placeholder="🔍 Quét mã vạch hoặc gõ tên / mã sản phẩm... (F2)" style="width:100%;" oninput="filterPosProducts()" onkeydown="handlePosSearchKey(event)">
                                </div>
                                <div style="display:flex; gap:6px;">
                                    <button class="btn-header btn-outline" onclick="loadData(true)" title="Làm mới kho"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></svg></button>
                                </div>
                            </div>
                            <div class="pos-cat-bar" id="pos-category-bar" style="margin-top:10px; margin-bottom:0;">
                                <button class="pos-cat-btn active" onclick="selectPosCategory('ALL')">Tất cả</button>
                            </div>
                        </div>

                        <div class="pos-prod-grid" id="pos-product-grid">
                            <!-- Rendered by JS -->
                        </div>
                    </div>

                    <!-- Right: Cart & Checkout Panel -->
                    <div>
                        <div class="pos-cart-panel">
                            <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; border-bottom:1px solid var(--border-light); padding-bottom:8px;">
                                <div style="font-weight:800; font-size:15px; display:flex; align-items:center; gap:6px;">
                                    <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="var(--primary)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="21" r="1"/><circle cx="19" cy="21" r="1"/><path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12"/></svg>
                                    <span>Giỏ Hàng (<span id="pos-cart-count">0</span> món)</span>
                                </div>
                                <button class="btn-act btn-act-del" onclick="clearPosCart()" style="font-size:11px; padding:3px 8px;">Xóa hết</button>
                            </div>

                            <!-- Customer select -->
                            <div style="display:flex; gap:6px; margin-bottom:10px;">
                                <select id="pos-customer-select" class="login-input" style="height:36px; padding:4px 8px; font-size:12.5px; flex:1;">
                                    <option value="">Khách lẻ (Không lưu công nợ)</option>
                                </select>
                                <button class="btn-header btn-outline" style="height:36px; width:36px; padding:0; justify-content:center;" onclick="openAddCustomerModal()" title="Thêm khách mới">+</button>
                            </div>

                            <!-- Cart Items Table -->
                            <div style="max-height:240px; overflow-y:auto; margin-bottom:10px; border:1px solid var(--border-light); border-radius:8px;">
                                <table class="pos-cart-table" id="tbl-pos-cart">
                                    <thead>
                                        <tr>
                                            <th>Sản phẩm</th>
                                            <th style="width:75px; text-align:center;">SL</th>
                                            <th style="text-align:right;">Thành tiền</th>
                                            <th style="width:24px;"></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr><td colspan="4" style="text-align:center; padding:24px; color:var(--muted-foreground);">Giỏ hàng đang trống.<br>Nhấn vào sản phẩm để chọn.</td></tr>
                                    </tbody>
                                </table>
                            </div>

                            <!-- Calculations -->
                            <div style="font-size:13px; line-height:1.7;">
                                <div style="display:flex; justify-content:space-between;">
                                    <span style="color:var(--muted-foreground);">Tổng tiền hàng:</span>
                                    <span class="font-bold" id="pos-subtotal">0 đ</span>
                                </div>
                                <div style="display:flex; justify-content:space-between; align-items:center; margin:4px 0;">
                                    <span style="color:var(--muted-foreground);">Giảm giá:</span>
                                    <input type="number" id="pos-discount" class="cart-qty-input" style="width:90px; height:26px; text-align:right; padding-right:4px;" value="0" oninput="calcPosTotals()">
                                </div>
                                <div style="display:flex; justify-content:space-between; font-size:15px; border-top:1px dashed var(--border); padding-top:6px; margin-top:4px;">
                                    <span style="font-weight:800;">Khách cần trả:</span>
                                    <span style="font-weight:800; color:var(--primary); font-size:17px;" id="pos-total-amount">0 đ</span>
                                </div>
                            </div>

                            <!-- Payment Method -->
                            <div style="margin:10px 0;">
                                <div style="font-size:11.5px; font-weight:700; color:var(--muted-foreground); margin-bottom:4px;">HÌNH THỨC THANH TOÁN</div>
                                <div style="display:grid; grid-template-columns:repeat(3, 1fr); gap:6px;">
                                    <label style="border:1px solid var(--border); border-radius:6px; padding:6px 2px; text-align:center; cursor:pointer; font-size:12px; font-weight:700; background:var(--card);">
                                        <input type="radio" name="pos-payment-method" value="TIEN_MAT" checked onchange="calcPosTotals()"> Tiền mặt
                                    </label>
                                    <label style="border:1px solid var(--border); border-radius:6px; padding:6px 2px; text-align:center; cursor:pointer; font-size:12px; font-weight:700; background:var(--card);">
                                        <input type="radio" name="pos-payment-method" value="CHUYEN_KHOAN" onchange="calcPosTotals()"> C.Khoản
                                    </label>
                                    <label style="border:1px solid var(--border); border-radius:6px; padding:6px 2px; text-align:center; cursor:pointer; font-size:12px; font-weight:700; background:var(--card);">
                                        <input type="radio" name="pos-payment-method" value="GHI_NO" onchange="calcPosTotals()"> Ghi nợ
                                    </label>
                                </div>
                            </div>

                            <!-- Cash Given -->
                            <div id="pos-cash-panel" style="margin-bottom:8px;">
                                <div style="display:flex; justify-content:space-between; align-items:center;">
                                    <span style="font-size:12px; color:var(--muted-foreground);">Tiền khách đưa:</span>
                                    <input type="number" id="pos-cash-given" class="search-input" style="width:130px; height:30px; text-align:right; font-weight:800;" value="0" oninput="calcPosTotals()">
                                </div>
                                <div class="quick-cash-grid">
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash('EXACT')">Đủ tiền</button>
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash(50000)">50.000</button>
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash(100000)">100.000</button>
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash(200000)">200.000</button>
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash(500000)">500.000</button>
                                    <button type="button" class="quick-cash-btn" onclick="setPosQuickCash(1000000)">1.000.000</button>
                                </div>
                                <div style="display:flex; justify-content:space-between; font-size:13px; margin-top:4px;">
                                    <span id="pos-change-label" style="color:var(--muted-foreground);">Tiền thừa trả khách:</span>
                                    <span id="pos-change-val" style="font-weight:800; color:#16a34a;">0 đ</span>
                                </div>
                            </div>

                            <input type="text" id="pos-order-note" class="login-input" placeholder="Ghi chú đơn hàng (nếu có)..." style="height:32px; font-size:12px; margin-bottom:10px;">

                            <button class="btn-checkout" onclick="posCheckout()">
                                <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                                <span>THANH TOÁN (F9)</span>
                            </button>
                        </div>
                    </div>
                </div>
            </div>

            <!-- TAB 1: DASHBOARD -->
            <div id="tab-dashboard" class="tab-pane active">
                <div class="kpi-grid">
                    <div class="kpi-card kpi-rev">
                        <div class="kpi-header">
                            <span class="kpi-title">Doanh Thu Hôm Nay</span>
                            <span class="kpi-icon-badge kpi-badge-rev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6"/><path d="M18.09 10.37A6 6 0 1 1 10.34 18"/><path d="m7 6 5 5"/><path d="m12 17 5 5"/></svg></span>
                        </div>
                        <div class="kpi-value" style="color:#e1773b;" id="kpi-today-rev">0 đ</div>
                        <div class="kpi-sub" id="kpi-today-inv">0 đơn hàng hôm nay</div>
                    </div>
                    <div class="kpi-card kpi-profit">
                        <div class="kpi-header">
                            <span class="kpi-title">Lợi Nhuận Hôm Nay</span>
                            <span class="kpi-icon-badge kpi-badge-profit"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg></span>
                        </div>
                        <div class="kpi-value" style="color:#16a34a;" id="kpi-today-profit">0 đ</div>
                        <div class="kpi-sub" id="kpi-today-cogs">Giá vốn: 0 đ</div>
                    </div>
                    <div class="kpi-card kpi-cash">
                        <div class="kpi-header">
                            <span class="kpi-title">Tiền Mặt Tại Quầy</span>
                            <span class="kpi-icon-badge kpi-badge-cash"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/><path d="M6 12h.01M18 12h.01"/></svg></span>
                        </div>
                        <div class="kpi-value" style="color:#0284c7;" id="kpi-cash">0 đ</div>
                        <div class="kpi-sub" id="kpi-bank">Ngân hàng: 0 đ</div>
                    </div>
                    <div class="kpi-card kpi-debt">
                        <div class="kpi-header">
                            <span class="kpi-title">Khách Hàng Đang Nợ</span>
                            <span class="kpi-icon-badge kpi-badge-debt"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></span>
                        </div>
                        <div class="kpi-value" style="color:#dc2626;" id="kpi-cust-debt">0 đ</div>
                        <div class="kpi-sub" id="kpi-supp-debt">Nợ NCC: 0 đ</div>
                    </div>
                    <div class="kpi-card kpi-stock">
                        <div class="kpi-header">
                            <span class="kpi-title">Giá Trị Tồn Kho</span>
                            <span class="kpi-icon-badge kpi-badge-stock"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"/><path d="M12 22V12"/><polyline points="3.29 7 12 12 20.71 7"/><path d="m7.5 4.27 9 5.15"/></svg></span>
                        </div>
                        <div class="kpi-value" style="color:#8b5cf6;" id="kpi-stock-val">0 đ</div>
                        <div class="kpi-sub" id="kpi-low-stock">0 mặt hàng sắp hết</div>
                    </div>
                </div>

                <!-- Charts Grid: Revenue & Profit, Cash Flow (7 days) -->
                <div class="dash-charts-grid" style="display:grid; grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); gap: 16px; margin: 16px 0 20px 0;">
                    <div class="card" style="margin-bottom:0;">
                        <div class="card-header" style="padding:12px 16px;">
                            <div class="card-title">
                                <svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>
                                <span>Doanh Thu & Lợi Nhuận Gộp (7 Ngày)</span>
                            </div>
                            <span id="chart-rev-badge" class="badge" style="background:#eff6ff; color:#1d4ed8; border:1px solid #bfdbfe; font-size:11.5px; font-weight:700;">--</span>
                        </div>
                        <div style="padding: 14px 16px; height: 260px; position: relative;">
                            <canvas id="chartRevenueProfit"></canvas>
                        </div>
                    </div>
                    <div class="card" style="margin-bottom:0;">
                        <div class="card-header" style="padding:12px 16px;">
                            <div class="card-title">
                                <svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 6v2m0 8v2"/></svg>
                                <span>Dòng Tiền Thu - Chi (7 Ngày)</span>
                            </div>
                            <span id="chart-cash-badge" class="badge" style="background:#ecfdf5; color:#047857; border:1px solid #a7f3d0; font-size:11.5px; font-weight:700;">--</span>
                        </div>
                        <div style="padding: 14px 16px; height: 260px; position: relative;">
                            <canvas id="chartCashFlow"></canvas>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="21" r="1"/><circle cx="19" cy="21" r="1"/><path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12"/></svg><span>Đơn Bán Hàng Mới Nhất (Tại Quầy POS)</span></div>
                        <div style="display:flex; gap:8px;">
                            <button class="btn-header btn-primary" onclick="openStoreInfoModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg><span>Sửa Cấu Hình Cửa Hàng</span></button>
                            <button class="btn-header btn-outline" onclick="switchTab('invoices')"><span>Xem toàn bộ đơn</span><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-dash-invoices">
                            <thead>
                                <tr>
                                    <th>Mã HĐ</th>
                                    <th>Thời gian</th>
                                    <th>Thu ngân</th>
                                    <th>Khách hàng</th>
                                    <th class="text-right">Tổng tiền</th>
                                    <th class="text-right">Đã thanh toán</th>
                                    <th class="text-right">Còn nợ</th>
                                    <th>Hình thức</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>

                <!-- Low Stock Alert Card -->
                <div class="card" style="margin-top:16px;">
                    <div class="card-header">
                        <div class="card-title" style="color:#dc2626;"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg><span>Cảnh Báo Hàng Hóa Sắp Hết Tồn Kho</span></div>
                        <button id="btn-web-stock-alert" class="btn-header badge-stock-blink" style="display:none; cursor:pointer;" onclick="switchTab('purchases')">
                            <span>⚠️ Có <span id="web-alert-stock-count">0</span> sản phẩm cần nhập thêm (Nhập hàng ngay ➔)</span>
                        </button>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-dash-low-stock">
                            <thead>
                                <tr>
                                    <th>Mã hàng</th>
                                    <th>Tên hàng</th>
                                    <th>ĐVT</th>
                                    <th class="text-right">Tồn hiện tại</th>
                                    <th class="text-right">Tồn tối thiểu</th>
                                    <th class="text-center">Trạng thái</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 2: INVOICES -->
            <div id="tab-invoices" class="tab-pane">
                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="21" r="1"/><circle cx="19" cy="21" r="1"/><path d="M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12"/></svg><span>Toàn Bộ Đơn Bán Hàng (24/24)</span></div>
                        <input type="text" class="search-input" id="search-invoices" placeholder="Tìm theo mã HĐ, tên khách..." oninput="filterInvoices()">
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-all-invoices">
                            <thead>
                                <tr>
                                    <th>Mã HĐ</th>
                                    <th>Thời gian</th>
                                    <th>Thu ngân</th>
                                    <th>Khách hàng</th>
                                    <th class="text-right">Tổng tiền</th>
                                    <th class="text-right">Đã trả</th>
                                    <th class="text-right">Còn nợ</th>
                                    <th>Thanh toán</th>
                                    <th>Trạng thái</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 3: PURCHASES -->
            <div id="tab-purchases" class="tab-pane">
                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2"/><path d="M15 18H9"/><path d="M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14v10Z"/><circle cx="17" cy="18.5" r="2.5"/><circle cx="7" cy="18.5" r="2.5"/></svg><span>Phiếu Nhập Hàng Từ Nhà Cung Cấp</span></div>
                        <div style="display:flex; gap:8px;">
                            <input type="text" class="search-input" id="search-purchases" placeholder="Tìm theo mã phiếu, tên NCC..." oninput="filterPurchases()">
                            <button class="btn-header btn-primary" onclick="openCreatePurchaseModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Tạo Phiếu Nhập Hàng</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-purchases">
                            <thead>
                                <tr>
                                    <th>Mã Phiếu</th>
                                    <th>Thời gian</th>
                                    <th>Nhà cung cấp</th>
                                    <th class="text-right">Tổng tiền nhập</th>
                                    <th class="text-right">Đã thanh toán</th>
                                    <th class="text-right">Còn nợ NCC</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 4: INVENTORY -->
            <div id="tab-inventory" class="tab-pane">
                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"/><path d="M12 22V12"/><polyline points="3.29 7 12 12 20.71 7"/><path d="m7.5 4.27 9 5.15"/></svg><span>Danh Mục Kho & Hàng Hóa</span></div>
                        <div style="display:flex; gap:8px; align-items:center;">
                            <input type="text" class="search-input" id="search-products" placeholder="Tìm tên hàng, mã hàng..." oninput="filterProducts()">
                            <button class="btn-header btn-primary" onclick="openAddProductModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Thêm Hàng Mới</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-products">
                            <thead>
                                <tr>
                                    <th>Mã hàng</th>
                                    <th>Tên hàng hóa</th>
                                    <th>Mã vạch</th>
                                    <th>ĐVT</th>
                                    <th class="text-right">Giá vốn</th>
                                    <th class="text-right">Giá bán</th>
                                    <th class="text-right">Tồn kho hiện tại</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 5: PARTNERS -->
            <div id="tab-partners" class="tab-pane">
                <div class="subtab-bar">
                    <button class="subtab-btn active" id="btn-subtab-cust" onclick="switchPartnerTab('customers')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/></svg><span>Khách Hàng</span></button>
                    <button class="subtab-btn" id="btn-subtab-supp" onclick="switchPartnerTab('suppliers')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/><path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/><path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/></svg><span>Nhà Cung Cấp</span></button>
                </div>

                <div class="card partner-content" id="card-debt-cust">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/></svg><span>Quản Lý Khách Hàng & Công Nợ</span></div>
                        <div style="display:flex; gap:8px;">
                            <input type="text" class="search-input" id="search-customers" placeholder="Tìm khách theo tên, SĐT..." oninput="filterCustomers()">
                            <button class="btn-header btn-primary" onclick="openAddCustomerModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg><span>Thêm Khách Hàng</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-customers">
                            <thead>
                                <tr>
                                    <th>Mã KH</th>
                                    <th>Họ và tên</th>
                                    <th>Số điện thoại</th>
                                    <th>Địa chỉ</th>
                                    <th class="text-right">Nợ hiện tại</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>

                <div class="card partner-content" id="card-debt-supp" style="display: none;">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/><path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/><path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/></svg><span>Quản Lý Nhà Cung Cấp & Nợ Phải Trả</span></div>
                        <div style="display:flex; gap:8px;">
                            <input type="text" class="search-input" id="search-suppliers" placeholder="Tìm NCC theo tên, SĐT..." oninput="filterSuppliers()">
                            <button class="btn-header btn-primary" onclick="openAddSupplierModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Thêm Nhà Cung Cấp</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-suppliers">
                            <thead>
                                <tr>
                                    <th>Mã NCC</th>
                                    <th>Tên nhà cung cấp</th>
                                    <th>Số điện thoại</th>
                                    <th class="text-right">Nợ phải trả</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 6: FINANCE -->
            <div id="tab-finance" class="tab-pane">
                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1"/><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4"/></svg><span>Sổ Quỹ Thu - Chi Thời Gian Thực</span></div>
                        <div style="display:flex; gap:8px;">
                            <button class="btn-header btn-success" onclick="openCreateTransactionModal('THU')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Tạo Phiếu Thu</span></button>
                            <button class="btn-header btn-danger" onclick="openCreateTransactionModal('CHI')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Tạo Phiếu Chi</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-finance">
                            <thead>
                                <tr>
                                    <th>Mã Phiếu</th>
                                    <th>Thời gian</th>
                                    <th>Loại</th>
                                    <th>Hạng mục</th>
                                    <th>Đối tác</th>
                                    <th class="text-right">Số tiền</th>
                                    <th>Tài khoản</th>
                                    <th>Ghi chú</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            
            <!-- TAB: REPORTS (BAO CAO THONG KE) -->
            <div id="tab-reports" class="tab-pane">
                <div class="card" style="margin-bottom:16px;">
                    <div class="card-header" style="flex-wrap:wrap; gap:12px;">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg><span>Báo Cáo Thống Kê Doanh Thu & Lợi Nhuận</span></div>
                        <div style="display:flex; gap:6px;">
                            <button class="subtab-btn active" id="btn-rep-today" onclick="setReportPeriod('today')">Hôm nay</button>
                            <button class="subtab-btn" id="btn-rep-7days" onclick="setReportPeriod('7days')">7 ngày qua</button>
                            <button class="subtab-btn" id="btn-rep-month" onclick="setReportPeriod('month')">Tháng này</button>
                            <button class="subtab-btn" id="btn-rep-all" onclick="setReportPeriod('all')">Toàn bộ</button>
                        </div>
                    </div>
                </div>

                <div class="kpi-grid">
                    <div class="kpi-card kpi-rev">
                        <div class="kpi-title">Doanh Thu Thuần</div>
                        <div class="kpi-value" style="color:#e1773b;" id="rep-rev">0 đ</div>
                        <div class="kpi-sub" id="rep-inv-count">0 đơn bán</div>
                    </div>
                    <div class="kpi-card kpi-profit">
                        <div class="kpi-title">Lợi Nhuận Gộp</div>
                        <div class="kpi-value" style="color:#16a34a;" id="rep-profit">0 đ</div>
                        <div class="kpi-sub" id="rep-cogs">Giá vốn: 0 đ</div>
                    </div>
                    <div class="kpi-card kpi-cash">
                        <div class="kpi-title">Tổng Chi Tiêu Sổ Quỹ</div>
                        <div class="kpi-value" style="color:#dc2626;" id="rep-expense">0 đ</div>
                        <div class="kpi-sub">Phiếu chi từ sổ quỹ</div>
                    </div>
                    <div class="kpi-card kpi-stock">
                        <div class="kpi-title">Lợi Nhuận Ròng Thực Tế</div>
                        <div class="kpi-value" style="color:#8b5cf6;" id="rep-net-profit">0 đ</div>
                        <div class="kpi-sub">(Lợi nhuận gộp - Chi phí)</div>
                    </div>
                </div>

                <div class="card" style="margin-top:16px;">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg><span>Top 10 Hàng Hóa Bán Chạy Nhất</span></div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-report-top-products">
                            <thead>
                                <tr>
                                    <th>STT</th>
                                    <th>Mã hàng</th>
                                    <th>Tên hàng hóa</th>
                                    <th>ĐVT</th>
                                    <th class="text-right">Số lượng bán</th>
                                    <th class="text-right">Doanh số</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB: HR & CHẤM CÔNG (QUAN LY NHAN SU ĐAY ĐU) -->
            <div id="tab-hr" class="tab-pane">
                <div class="subtab-bar" style="margin-bottom:14px;">
                    <button class="subtab-btn active" id="btn-hr-sub-emp" onclick="switchHrSubtab('employees')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg><span>Danh Sách Nhân Viên</span></button>
                    <button class="subtab-btn" id="btn-hr-sub-att" onclick="switchHrSubtab('attendance')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/><path d="m9 16 2 2 4-4"/></svg><span>Nhật Ký Chấm Công</span></button>
                    <button class="subtab-btn" id="btn-hr-sub-adv" onclick="switchHrSubtab('advances')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/></svg><span>Tạm Ứng Lương</span></button>
                    <button class="subtab-btn" id="btn-hr-sub-pay" onclick="switchHrSubtab('payroll')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/></svg><span>Bảng Tính Lương Tháng</span></button>
                </div>

                <!-- SUBTAB 1: EMPLOYEES -->
                <div class="card hr-subcontent" id="hr-sub-employees">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg><span>Hồ Sơ Nhân Viên & Cấu Hình Lương</span></div>
                        <div style="display:flex; gap:8px;">
                            <button class="btn-header btn-primary" onclick="openAddEmployeeModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Thêm Nhân Viên</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-hr-employees">
                            <thead>
                                <tr>
                                    <th>Mã NV</th>
                                    <th>Họ và tên</th>
                                    <th>SĐT</th>
                                    <th>Chức vụ</th>
                                    <th class="text-right">Lương CB (24 công)</th>
                                    <th class="text-right">Lương giờ</th>
                                    <th class="text-right">BHXH (10.5%)</th>
                                    <th class="text-right">Phụ cấp</th>
                                    <th class="text-center">Trạng thái</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>

                <!-- SUBTAB 2: ATTENDANCE -->
                <div class="card hr-subcontent" id="hr-sub-attendance" style="display:none;">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/><path d="m9 16 2 2 4-4"/></svg><span>Bảng Chấm Công Nhân Viên (24/24)</span></div>
                        <div style="display:flex; gap:8px;">
                            <input type="text" class="search-input" id="search-attendance" placeholder="Tìm theo tên, mã NV..." oninput="filterAttendance()">
                            <button class="btn-header btn-primary" onclick="openAddAttendanceModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Bổ Sung Công</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-attendance">
                            <thead>
                                <tr>
                                    <th class="text-center" style="width: 45px;">STT</th>
                                    <th>Ngày làm</th>
                                    <th>Mã NV</th>
                                    <th>Họ và tên</th>
                                    <th class="text-center">Giờ vào</th>
                                    <th class="text-center">Giờ ra</th>
                                    <th class="text-right">Tổng giờ</th>
                                    <th>Địa chỉ IP</th>
                                    <th class="text-center">Trạng thái</th>
                                    <th>Ghi chú</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>

                <!-- SUBTAB 3: ADVANCES -->
                <div class="card hr-subcontent" id="hr-sub-advances" style="display:none;">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/></svg><span>Danh Sách Tạm Ứng Lương (Thực Tế)</span></div>
                        <div style="display:flex; gap:8px;">
                            <button class="btn-header btn-primary" onclick="openAddAdvanceModal()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg><span>Lập Phiếu Tạm Ứng</span></button>
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-hr-advances">
                            <thead>
                                <tr>
                                    <th>Mã NV</th>
                                    <th>Họ và tên</th>
                                    <th>Tháng</th>
                                    <th>Ngày tạm ứng</th>
                                    <th class="text-right">Số tiền tạm ứng</th>
                                    <th>Lý do / Ghi chú</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>

                <!-- SUBTAB 4: PAYROLL -->
                <div class="card hr-subcontent" id="hr-sub-payroll" style="display:none;">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/></svg><span>Bảng Lương Tháng (Chuẩn 24 Công & BHXH 10.5%)</span></div>
                        <div style="display:flex; gap:8px; align-items:center;">
                            <input type="month" id="hr-payroll-month" class="search-input" style="height:34px; padding:0 8px;" onchange="renderPayrollTable()">
                        </div>
                    </div>
                    <div class="table-responsive">
                        <table class="excel-table" id="tbl-hr-payroll">
                            <thead>
                                <tr>
                                    <th>Mã NV</th>
                                    <th>Họ và tên</th>
                                    <th>Chức vụ</th>
                                    <th class="text-right">Công / Giờ</th>
                                    <th class="text-right">Lương chính</th>
                                    <th class="text-right">Phụ cấp</th>
                                    <th class="text-right" style="color:#dc2626;">Trừ BHXH (10.5%)</th>
                                    <th class="text-right" style="color:#d97706;">Trừ Tạm ứng</th>
                                    <th class="text-right font-bold" style="color:#16a34a;">Thực Lĩnh</th>
                                    <th class="text-center">Trạng thái</th>
                                    <th class="text-center">Thao tác</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                </div>
            </div>

            <!-- TAB 8: SYNC INFO -->
            <div id="tab-sync" class="tab-pane">
                <div class="card">
                    <div class="card-header">
                        <div class="card-title"><svg class="title-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></svg><span>Thông Tin Máy Chủ & Kết Nối Đồng Bộ 2 Chiều</span></div>
                    </div>
                    <div style="padding: 22px;">
                        <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 20px;">
                            <div style="background: #f8fafc; border: 1px solid var(--border); border-radius: 10px; padding: 18px;">
                                <div style="font-size: 11.5px; font-weight: 700; color: var(--muted-foreground); text-transform: uppercase;">Cửa Hàng</div>
                                <div style="font-size: 17px; font-weight: 800; color: var(--foreground); margin-top: 5px;" id="sync-info-store">--</div>
                            </div>
                            <div style="background: #f8fafc; border: 1px solid var(--border); border-radius: 10px; padding: 18px;">
                                <div style="font-size: 11.5px; font-weight: 700; color: var(--muted-foreground); text-transform: uppercase;">Lần Đồng Bộ Cuối</div>
                                <div style="font-size: 17px; font-weight: 800; color: #16a34a; margin-top: 5px;" id="sync-info-time">--</div>
                            </div>
                            <div style="background: #f8fafc; border: 1px solid var(--border); border-radius: 10px; padding: 18px;">
                                <div style="font-size: 11.5px; font-weight: 700; color: var(--muted-foreground); text-transform: uppercase;">Tổng Số Lần Đồng Bộ</div>
                                <div style="font-size: 17px; font-weight: 800; color: var(--primary); margin-top: 5px;" id="sync-info-count">0</div>
                            </div>
                        </div>

                        <div style="background: #f0fdf4; border: 1px solid #86efac; border-radius: 10px; padding: 18px; margin-bottom: 16px;">
                            <h4 style="color: #15803d; font-size: 14.5px; margin-bottom: 6px; font-weight: 800; display:flex; align-items:center; gap:6px;"><svg class="btn-icon" style="color:#15803d;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Cơ Chế Đồng Bộ 2 Chiều Tự Động (Offline-First)</span></h4>
                            <p style="font-size: 13.5px; color: #166534; line-height: 1.6;">
                                - Mọi chỉnh sửa của Chủ cửa hàng trên web này (Thêm/Sửa hàng hóa, Sửa nợ khách, Tạo phiếu thu/chi, Sửa công) sẽ được lưu lại và <b>tự động kéo về App .exe</b> ngay khi máy tính cửa hàng kết nối mạng.<br>
                                - Mọi đơn hàng bán ra hoặc nhập hàng tại cửa hàng cũng được <b>tự động đẩy lên web</b> này theo thời gian thực 24/24.
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </div>

    <!-- MODAL: PRODUCT -->
    <div class="modal-overlay" id="modal-product">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title" id="modal-product-title">Thêm Hàng Hóa Mới</span>
                <button class="modal-close" onclick="closeModal('modal-product')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="p-id">
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Mã hàng:</label>
                        <input type="text" class="form-control" id="p-code" placeholder="Tự sinh nếu để trống">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Mã vạch (Barcode):</label>
                        <input type="text" class="form-control" id="p-barcode" placeholder="Mã vạch...">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Tên hàng hóa (*):</label>
                    <input type="text" class="form-control" id="p-name" placeholder="Tên sản phẩm..." required>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Đơn vị tính:</label>
                        <input type="text" class="form-control" id="p-unit" placeholder="Cái, Kg, Mét, Cây...">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Giá bán (* VNĐ):</label>
                        <input type="number" class="form-control" id="p-retail" placeholder="0" required>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Giá vốn (VNĐ):</label>
                        <input type="number" class="form-control" id="p-cost" placeholder="0">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Tồn kho hiện tại:</label>
                        <input type="number" class="form-control" id="p-stock" placeholder="0">
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Tồn tối thiểu:</label>
                        <input type="number" class="form-control" id="p-min-stock" placeholder="0">
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-product')">Hủy</button>
                <button class="btn-header btn-primary" onclick="submitProduct()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Hàng Hóa</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: CUSTOMER -->
    <div class="modal-overlay" id="modal-customer">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title" id="modal-customer-title">Thêm Khách Hàng</span>
                <button class="modal-close" onclick="closeModal('modal-customer')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="c-id">
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Mã khách hàng:</label>
                        <input type="text" class="form-control" id="c-code" placeholder="Tự sinh nếu để trống">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Số điện thoại:</label>
                        <input type="text" class="form-control" id="c-phone" placeholder="09xxxxxxx">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Họ và tên (*):</label>
                    <input type="text" class="form-control" id="c-name" placeholder="Tên khách hàng..." required>
                </div>
                <div class="form-group">
                    <label class="form-label">Địa chỉ:</label>
                    <input type="text" class="form-control" id="c-address" placeholder="Địa chỉ...">
                </div>
                <div class="form-group" id="c-init-debt-group">
                    <label class="form-label">Nợ ban đầu (VNĐ):</label>
                    <input type="number" class="form-control" id="c-init-debt" placeholder="0">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-customer')">Hủy</button>
                <button class="btn-header btn-primary" onclick="submitCustomer()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Khách Hàng</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: PAY CUSTOMER DEBT -->
    <div class="modal-overlay" id="modal-pay-customer">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title">Thu Nợ Khách Hàng</span>
                <button class="modal-close" onclick="closeModal('modal-pay-customer')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="pay-c-id">
                <div class="form-group">
                    <label class="form-label">Khách hàng:</label>
                    <div id="pay-c-name" style="font-size:16px; font-weight:800; color:var(--primary);">--</div>
                </div>
                <div class="form-group">
                    <label class="form-label">Số tiền khách đang nợ:</label>
                    <div id="pay-c-debt" style="font-size:18px; font-weight:800; color:#dc2626;">0 đ</div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Số tiền khách trả (* VNĐ):</label>
                        <input type="number" class="form-control" id="pay-c-amount" placeholder="Nhập số tiền..." required>
                    </div>
                    <div class="form-group">
                        <label class="form-label">Tài khoản nhận:</label>
                        <select class="form-control" id="pay-c-account">
                            <option value="1">Tiền mặt tại quầy</option>
                            <option value="2">Tài khoản Ngân hàng</option>
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Ghi chú phiếu thu:</label>
                    <input type="text" class="form-control" id="pay-c-note" value="Thu nợ khách hàng">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-pay-customer')">Hủy</button>
                <button class="btn-header btn-success" onclick="submitPayCustomerDebt()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Xác Nhận Thu Nợ</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: SUPPLIER -->
    <div class="modal-overlay" id="modal-supplier">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title" id="modal-supplier-title">Thêm Nhà Cung Cấp</span>
                <button class="modal-close" onclick="closeModal('modal-supplier')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="s-id">
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Mã NCC:</label>
                        <input type="text" class="form-control" id="s-code" placeholder="Tự sinh nếu để trống">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Số điện thoại:</label>
                        <input type="text" class="form-control" id="s-phone" placeholder="09xxxxxxx">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Tên nhà cung cấp (*):</label>
                    <input type="text" class="form-control" id="s-name" placeholder="Tên NCC..." required>
                </div>
                <div class="form-group">
                    <label class="form-label">Địa chỉ:</label>
                    <input type="text" class="form-control" id="s-address" placeholder="Địa chỉ...">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-supplier')">Hủy</button>
                <button class="btn-header btn-primary" onclick="submitSupplier()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Nhà Cung Cấp</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: PAY SUPPLIER DEBT -->
    <div class="modal-overlay" id="modal-pay-supplier">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title">Trả Nợ Nhà Cung Cấp</span>
                <button class="modal-close" onclick="closeModal('modal-pay-supplier')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="pay-s-id">
                <div class="form-group">
                    <label class="form-label">Nhà cung cấp:</label>
                    <div id="pay-s-name" style="font-size:16px; font-weight:800; color:var(--primary);">--</div>
                </div>
                <div class="form-group">
                    <label class="form-label">Nợ phải trả hiện tại:</label>
                    <div id="pay-s-debt" style="font-size:18px; font-weight:800; color:#ea580c;">0 đ</div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Số tiền trả (* VNĐ):</label>
                        <input type="number" class="form-control" id="pay-s-amount" placeholder="Nhập số tiền..." required>
                    </div>
                    <div class="form-group">
                        <label class="form-label">Nguồn tiền chi:</label>
                        <select class="form-control" id="pay-s-account">
                            <option value="1">Tiền mặt tại quầy</option>
                            <option value="2">Tài khoản Ngân hàng</option>
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Ghi chú phiếu chi:</label>
                    <input type="text" class="form-control" id="pay-s-note" value="Trả nợ nhà cung cấp">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-pay-supplier')">Hủy</button>
                <button class="btn-header btn-danger" onclick="submitPaySupplierDebt()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Xác Nhận Trả Nợ</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: INVOICE DETAIL -->
    <div class="modal-overlay" id="modal-invoice-detail">
        <div class="modal-box" style="max-width: 720px;">
            <div class="modal-header">
                <span class="modal-title" id="inv-detail-title">Chi Tiết Đơn Hàng</span>
                <button class="modal-close" onclick="closeModal('modal-invoice-detail')">&times;</button>
            </div>
            <div class="modal-body">
                <div style="display:flex; justify-content:space-between; margin-bottom:14px; font-size:13.5px;">
                    <div>Khách: <strong id="inv-detail-cust" style="color:var(--foreground);">--</strong></div>
                    <div>Thời gian: <strong id="inv-detail-time" class="font-mono">--</strong></div>
                </div>
                <div class="table-responsive" style="max-height: 260px; margin-bottom:16px; border:1px solid var(--border); border-radius:8px;">
                    <table class="excel-table">
                        <thead>
                            <tr>
                                <th>Mặt hàng</th>
                                <th>ĐVT</th>
                                <th class="text-right">Số lượng</th>
                                <th class="text-right">Đơn giá</th>
                                <th class="text-right">Thành tiền</th>
                            </tr>
                        </thead>
                        <tbody id="inv-detail-items"></tbody>
                    </table>
                </div>
                <div style="display:flex; justify-content:flex-end; gap:20px; font-size:14.5px; margin-bottom:16px;">
                    <div>Tổng tiền: <strong id="inv-detail-total" style="color:var(--primary);">0 đ</strong></div>
                    <div>Đã trả: <strong id="inv-detail-paid" style="color:#16a34a;">0 đ</strong></div>
                    <div>Còn nợ: <strong id="inv-detail-debt" style="color:#dc2626;">0 đ</strong></div>
                </div>

                <div id="inv-pay-debt-section" style="background:#f8fafc; border:1px solid var(--border); border-radius:10px; padding:14px; display:none;">
                    <div style="font-weight:700; font-size:13.5px; margin-bottom:10px; color:#16a34a; display:flex; align-items:center; gap:6px;"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="12" x="2" y="6" rx="2"/><circle cx="12" cy="12" r="2"/></svg><span>Thu tiền nợ đơn hàng này:</span></div>
                    <div class="form-row" style="margin-bottom:0;">
                        <div class="form-group" style="margin:0;">
                            <input type="number" class="form-control" id="inv-pay-amount" placeholder="Nhập số tiền khách trả...">
                        </div>
                        <div style="display:flex; gap:8px;">
                            <select class="form-control" id="inv-pay-account" style="width:160px;">
                                <option value="1">Tiền mặt</option>
                                <option value="2">Ngân hàng</option>
                            </select>
                            <button class="btn-header btn-success" onclick="submitPayInvoiceDebt()">Thu tiền</button>
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal-footer" style="justify-content:space-between;">
                <button class="btn-header btn-danger" id="btn-cancel-invoice" onclick="confirmCancelInvoice()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg><span>Hủy Đơn Hàng Này</span></button>
                <button class="btn-header btn-outline" onclick="closeModal('modal-invoice-detail')">Đóng</button>
            </div>
        </div>
    </div>

    <!-- MODAL: TRANSACTION -->
    <div class="modal-overlay" id="modal-transaction">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title" id="modal-trans-title">Tạo Phiếu Thu Tiền</span>
                <button class="modal-close" onclick="closeModal('modal-transaction')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="trans-type" value="THU">
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Hạng mục (*):</label>
                        <input type="text" class="form-control" id="trans-cat" placeholder="Thu bán hàng, Chi tiền điện..." required>
                    </div>
                    <div class="form-group">
                        <label class="form-label">Số tiền (* VNĐ):</label>
                        <input type="number" class="form-control" id="trans-amount" placeholder="0" required>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Tài khoản:</label>
                        <select class="form-control" id="trans-account">
                            <option value="1">Tiền mặt tại quầy</option>
                            <option value="2">Tài khoản Ngân hàng</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label class="form-label">Người nộp / nhận:</label>
                        <input type="text" class="form-control" id="trans-partner" placeholder="Tên người nộp/nhận...">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Ghi chú diễn giải:</label>
                    <input type="text" class="form-control" id="trans-note" placeholder="Chi tiết giao dịch...">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-transaction')">Hủy</button>
                <button class="btn-header btn-primary" id="btn-submit-trans" onclick="submitTransaction()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Phiếu</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: ATTENDANCE EDIT & MANUAL ADD -->
    <div class="modal-overlay" id="modal-attendance">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title" id="modal-att-title">Sửa / Duyệt Chấm Công</span>
                <button class="modal-close" onclick="closeModal('modal-attendance')">&times;</button>
            </div>
            <div class="modal-body">
                <input type="hidden" id="att-id">
                <div class="form-group" id="att-emp-select-group" style="display:none;">
                    <label class="form-label">Chọn nhân viên (*):</label>
                    <select class="form-control" id="att-emp-select"></select>
                </div>
                <div class="form-group" id="att-emp-name-group">
                    <label class="form-label">Nhân viên:</label>
                    <div id="att-emp-name" style="font-size:16px; font-weight:800; color:var(--primary);">--</div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Ngày làm việc:</label>
                        <input type="date" class="form-control" id="att-date">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Trạng thái duyệt:</label>
                        <select class="form-control" id="att-status">
                            <option value="Đúng giờ (Đã duyệt)">Đúng giờ (Đã duyệt)</option>
                            <option value="Đi muộn">Đi muộn</option>
                            <option value="Bù công">Bù công</option>
                            <option value="Hợp lệ">Hợp lệ</option>
                        </select>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Giờ vào (HH:mm:ss):</label>
                        <input type="text" class="form-control font-mono" id="att-checkin" placeholder="08:00:00">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Giờ ra (HH:mm:ss):</label>
                        <input type="text" class="form-control font-mono" id="att-checkout" placeholder="17:00:00">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Ghi chú giải trình:</label>
                    <input type="text" class="form-control" id="att-note" placeholder="Lý do duyệt / sửa công...">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-attendance')">Hủy</button>
                <button class="btn-header btn-primary" onclick="submitAttendance()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Chấm Công</span></button>
            </div>
        </div>
    </div>

    <!-- MODAL: STORE INFO & SECRET -->
    <div class="modal-overlay" id="modal-store-info">
        <div class="modal-box">
            <div class="modal-header">
                <span class="modal-title">Cấu Hình Cửa Hàng & Mật Khẩu</span>
                <button class="modal-close" onclick="closeModal('modal-store-info')">&times;</button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label class="form-label">Tên cửa hàng (*):</label>
                    <input type="text" class="form-control" id="cfg-store-name" placeholder="Tên cửa hàng...">
                </div>
                <div class="form-row">
                    <div class="form-group">
                        <label class="form-label">Số điện thoại:</label>
                        <input type="text" class="form-control" id="cfg-store-phone" placeholder="SĐT...">
                    </div>
                    <div class="form-group">
                        <label class="form-label">Mã bảo mật (Sync Secret):</label>
                        <input type="text" class="form-control" id="cfg-sync-secret" placeholder="Mã bảo mật...">
                    </div>
                </div>
                <div class="form-group">
                    <label class="form-label">Địa chỉ cửa hàng:</label>
                    <input type="text" class="form-control" id="cfg-store-address" placeholder="Địa chỉ...">
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-header btn-outline" onclick="closeModal('modal-store-info')">Hủy</button>
                <button class="btn-header btn-primary" onclick="submitStoreInfo()"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg><span>Lưu Cấu Hình</span></button>
            </div>
        </div>
    </div>

    <script>
        let GLOBAL_DATA = null;
        let CURRENT_SECRET = localStorage.getItem("pos_sync_secret") || "";
        let ACTIVE_INVOICE_ID = 0;

        const SCRIPT_NAME = window.location.pathname.split("/").pop() || "";
        function apiUrl(apiName, token = "") {
            const base = SCRIPT_NAME.endsWith(".php") ? SCRIPT_NAME : "";
            let url = (base ? base : "") + "?api=" + encodeURIComponent(apiName);
            const tk = token || CURRENT_SECRET;
            if (tk) url += "&token=" + encodeURIComponent(tk);
            return url;
        }

        const VIEW_TITLES = {
            'dashboard': 'TỔNG QUAN HỆ THỐNG (24/24)',
            'pos': 'BÁN HÀNG (POS) TRỰC TIẾP TRÊN WEB',
            'invoices': 'ĐƠN BÁN HÀNG PHÁT SINH (24/24)',
            'purchases': 'QUẢN LÝ NHẬP HÀNG TỪ NCC',
            'inventory': 'KHO & HÀNG HÓA - TỒN HIỆN TẠI',
            'partners': 'QUẢN LÝ CÔNG NỢ ĐỐI TÁC',
            'finance': 'SỔ QUỸ THU - CHI THỜI GIAN THỰC',
            'reports': 'BÁO CÁO THỐNG KÊ DOANH THU & LỢI NHUẬN',
            'hr': 'QUẢN LÝ NHÂN SỰ & CHẤM CÔNG (24/24)',
            'attendance': 'BẢNG CHẤM CÔNG NHÂN VIÊN (24/24)',
            'sync': 'THÔNG TIN MÁY CHỦ & ĐỒNG BỘ'
        };

        function formatMoney(num) { return new Intl.NumberFormat('vi-VN').format(Math.round(num || 0)) + ' đ'; }
        function formatQty(num) { return parseFloat(num || 0).toLocaleString('vi-VN'); }

        function toggleMobileSidebar() {
            document.getElementById("app-sidebar").classList.toggle("mobile-open");
            document.getElementById("sidebar-backdrop").classList.toggle("active");
        }

        function switchTab(tabId) {
            document.querySelectorAll(".nav-item").forEach(b => {
                b.classList.remove("active");
                if (b.getAttribute("data-tab") === tabId) b.classList.add("active");
            });
            document.querySelectorAll(".tab-pane").forEach(c => c.classList.remove("active"));
            const content = document.getElementById(`tab-${tabId}`);
            if (content) content.classList.add("active");
            const titleEl = document.getElementById("main-view-title");
            if (titleEl) titleEl.innerText = VIEW_TITLES[tabId] || "QUẢN LÝ BÁN HÀNG";
            const sb = document.getElementById("app-sidebar");
            const bd = document.getElementById("sidebar-backdrop");
            if (sb) sb.classList.remove("mobile-open");
            if (bd) bd.classList.remove("active");
        }

        function switchPartnerTab(type) {
            document.querySelectorAll(".subtab-btn").forEach(b => b.classList.remove("active"));
            document.querySelectorAll(".partner-content").forEach(c => c.style.display = "none");
            if (type === 'customers') {
                document.getElementById("btn-subtab-cust").classList.add("active");
                document.getElementById("card-debt-cust").style.display = "block";
            } else {
                document.getElementById("btn-subtab-supp").classList.add("active");
                document.getElementById("card-debt-supp").style.display = "block";
            }
        }

        function updateClock() {
            const now = new Date();
            const el = document.getElementById("header-clock");
            if (el) el.innerText = String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0');
        }
        setInterval(updateClock, 1000);
        updateClock();

        function verifyLogin() {
            const secret = document.getElementById("secret-input").value.trim();
            if(!secret) return;
            const errEl = document.getElementById("login-error");
            errEl.style.display = "none";

            fetch(apiUrl("ping", secret), { headers: { "X-Sync-Token": secret } })
                .then(async r => {
                    if (!r.ok) {
                        let text = "";
                        try { const d = await r.json(); text = d.error || d.message; } catch(e) {}
                        throw new Error(text || `Mã bảo mật không đúng (${r.status})`);
                    }
                    return r.json();
                })
                .then(data => {
                    if(data.status === "ok") {
                        CURRENT_SECRET = secret;
                        localStorage.setItem("pos_sync_secret", secret);
                        document.getElementById("login-screen").style.display = "none";
                        document.getElementById("btn-dl-db").href = apiUrl("download-db", secret);
                        loadData();
                    } else {
                        errEl.innerText = data.error || "Mã bảo mật không đúng!";
                        errEl.style.display = "block";
                    }
                })
                .catch(err => {
                    errEl.innerText = "Lỗi kết nối: " + err.message;
                    errEl.style.display = "block";
                });
        }

        function logout() { localStorage.removeItem("pos_sync_secret"); location.reload(); }

        function loadData(showToast = false) {
            if(!CURRENT_SECRET) return;
            fetch(apiUrl("dashboard-data"), { headers: { "X-Sync-Token": CURRENT_SECRET } })
                .then(r => { if (!r.ok) throw new Error("HTTP " + r.status); return r.json(); })
                .then(data => {
                    if(data.status !== "ok") return;
                    GLOBAL_DATA = data.data;
                    renderData(data.data, data.meta);
                    if(showToast) alert("✓ Đã cập nhật dữ liệu mới nhất!");
                })
                .catch(err => console.error("Lỗi:", err));
        }

        function renderData(d, meta) {
            const storeName = d.store_name || "CỬA HÀNG VẬT LIỆU XÂY DỰNG & ĐA NGÀNH";
            document.getElementById("hdr-store-name").innerText = storeName;
            const syncTime = meta && meta.last_sync_time ? meta.last_sync_time : "--:--:--";
            document.getElementById("hdr-last-sync").innerText = "Cập nhật: " + syncTime;
            const elShort = document.getElementById("hdr-last-sync-short");
            if (elShort) {
                const shortTime = (syncTime.indexOf(' ') !== -1) ? syncTime.split(' ')[0] : syncTime;
                elShort.innerText = shortTime;
            }

            const syncStore = document.getElementById("sync-info-store");
            if (syncStore) syncStore.innerText = storeName;
            const syncTimeEl = document.getElementById("sync-info-time");
            if (syncTimeEl) syncTimeEl.innerText = syncTime;
            const syncCountEl = document.getElementById("sync-info-count");
            if (syncCountEl) syncCountEl.innerText = (meta && meta.sync_count ? meta.sync_count : 0);

            document.getElementById("kpi-today-rev").innerText = formatMoney(d.today.revenue);
            document.getElementById("kpi-today-inv").innerText = `${d.today.invoices} đơn hàng hôm nay`;
            document.getElementById("kpi-today-profit").innerText = formatMoney(d.today.profit);
            document.getElementById("kpi-today-cogs").innerText = `Giá vốn: ${formatMoney(d.today.cogs)}`;
            document.getElementById("kpi-cash").innerText = formatMoney(d.finance.cash);
            document.getElementById("kpi-bank").innerText = `Ngân hàng: ${formatMoney(d.finance.bank)}`;
            document.getElementById("kpi-cust-debt").innerText = formatMoney(d.finance.customer_debt);
            document.getElementById("kpi-supp-debt").innerText = `Nợ NCC: ${formatMoney(d.finance.supplier_debt)}`;
            document.getElementById("kpi-stock-val").innerText = formatMoney(d.inventory.total_value);
            document.getElementById("kpi-low-stock").innerText = `${d.inventory.low_stock_count} mặt hàng sắp hết`;

            // Update low stock alerts and badges
            const lowCount = d.inventory.low_stock_count || 0;
            const navBadge = document.getElementById("nav-low-stock-badge");
            const btnAlert = document.getElementById("btn-web-stock-alert");
            const alertCount = document.getElementById("web-alert-stock-count");
            if (navBadge) {
                if (lowCount > 0) {
                    navBadge.innerText = `⚠️ ${lowCount}`;
                    navBadge.style.display = "inline-block";
                } else {
                    navBadge.style.display = "none";
                }
            }
            if (btnAlert) {
                if (lowCount > 0) {
                    if (alertCount) alertCount.innerText = lowCount;
                    btnAlert.style.display = "inline-flex";
                } else {
                    btnAlert.style.display = "none";
                }
            }

            renderInvoicesTable("tbl-dash-invoices", d.recent_invoices.slice(0, 10));
            renderInvoicesTable("tbl-all-invoices", d.recent_invoices);
            renderPurchasesTable(d.recent_purchases || []);
            renderProductsTable(d.products || []);
            renderLowStockTable("tbl-dash-low-stock", (d.products || []).filter(p => {
                const q = parseFloat(p.stock_qty || 0);
                const m = parseFloat(p.min_stock || 0);
                return (m > 0 && q <= m) || (q <= 0);
            }));
            renderCustomersTable(d.all_customers || d.debt_customers || []);
            renderSuppliersTable(d.all_suppliers || d.debt_suppliers || []);
            renderFinanceTable(d.recent_transactions || []);
            renderAttendanceTable(d.attendance_logs || []);
            renderDashboardCharts(d.chart_data);

            // Render POS
            renderPosCategories();
            filterPosProducts();
            const posCustSelect = document.getElementById("pos-customer-select");
            if (posCustSelect) {
                const custs = d.all_customers || d.debt_customers || [];
                posCustSelect.innerHTML = `<option value="">Khách lẻ (Không lưu công nợ)</option>` + custs.map(c => `
                    <option value="${c.id}">${escapeHtml(c.name)}${c.phone ? ' (' + c.phone + ')' : ''}${c.current_debt > 0 ? ' [Nợ: ' + formatMoney(c.current_debt) + ']' : ''}</option>
                `).join("");
            }

            // Render HR modules
            renderEmployeesTable(d.employees || []);
            renderAdvancesTable(d.salary_advances || []);
            renderPayrollTable();

            // Render Reports
            renderReports();
        }

        let chartRevProfitInstance = null;
        let chartCashFlowInstance = null;

        function renderDashboardCharts(chartData) {
            if (!chartData) return;

            const badgeRev = document.getElementById("chart-rev-badge");
            if (badgeRev) {
                const revTotal = chartData.total_revenue || 0;
                const profitTotal = chartData.total_profit || 0;
                badgeRev.innerText = `Tổng 7N: DT ${formatMoney(revTotal)} | Lãi ${formatMoney(profitTotal)}`;
            }

            const badgeCash = document.getElementById("chart-cash-badge");
            if (badgeCash) {
                const inTotal = chartData.total_cash_in || 0;
                const outTotal = chartData.total_cash_out || 0;
                const netTotal = inTotal - outTotal;
                const sign = netTotal >= 0 ? "+" : "";
                badgeCash.innerText = `Tổng 7N: Thu ${formatMoney(inTotal)} | Chi ${formatMoney(outTotal)} | Ròng: ${sign}${formatMoney(netTotal)}`;
                if (netTotal < 0) {
                    badgeCash.style.background = "#fef2f2";
                    badgeCash.style.color = "#b91c1c";
                    badgeCash.style.border = "1px solid #fecaca";
                } else {
                    badgeCash.style.background = "#ecfdf5";
                    badgeCash.style.color = "#047857";
                    badgeCash.style.border = "1px solid #a7f3d0";
                }
            }

            if (typeof Chart === "undefined") {
                return;
            }

            const categories = chartData.categories || [];
            const revenues = chartData.revenues || [];
            const profits = chartData.profits || [];
            const cashIns = chartData.cash_ins || [];
            const cashOuts = chartData.cash_outs || [];

            const formatYAxis = (val) => {
                if (Math.abs(val) >= 1000000) return (val / 1000000).toFixed(1) + ' tr';
                if (Math.abs(val) >= 1000) return (val / 1000).toFixed(0) + ' k';
                return val;
            };

            const ctx1 = document.getElementById("chartRevenueProfit");
            if (ctx1) {
                if (chartRevProfitInstance) {
                    chartRevProfitInstance.destroy();
                }
                chartRevProfitInstance = new Chart(ctx1, {
                    type: "bar",
                    data: {
                        labels: categories,
                        datasets: [
                            {
                                label: "Doanh thu thuần",
                                data: revenues,
                                backgroundColor: "#2563eb",
                                borderRadius: 4
                            },
                            {
                                label: "Lợi nhuận gộp",
                                data: profits,
                                backgroundColor: "#059669",
                                borderRadius: 4
                            }
                        ]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: { position: "top", labels: { boxWidth: 12, font: { family: "Plus Jakarta Sans", size: 11 } } },
                            tooltip: {
                                callbacks: {
                                    label: function(context) {
                                        return ` ${context.dataset.label}: ${formatMoney(context.parsed.y)}`;
                                    }
                                }
                            }
                        },
                        scales: {
                            x: { grid: { display: false }, ticks: { font: { family: "Plus Jakarta Sans", size: 11 } } },
                            y: {
                                ticks: {
                                    callback: formatYAxis,
                                    font: { family: "Plus Jakarta Sans", size: 10 }
                                }
                            }
                        }
                    }
                });
            }

            const ctx2 = document.getElementById("chartCashFlow");
            if (ctx2) {
                if (chartCashFlowInstance) {
                    chartCashFlowInstance.destroy();
                }
                chartCashFlowInstance = new Chart(ctx2, {
                    type: "bar",
                    data: {
                        labels: categories,
                        datasets: [
                            {
                                label: "Tiền thu vào",
                                data: cashIns,
                                backgroundColor: "#10b981",
                                borderRadius: 4
                            },
                            {
                                label: "Tiền chi ra",
                                data: cashOuts,
                                backgroundColor: "#ef4444",
                                borderRadius: 4
                            }
                        ]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: { position: "top", labels: { boxWidth: 12, font: { family: "Plus Jakarta Sans", size: 11 } } },
                            tooltip: {
                                callbacks: {
                                    label: function(context) {
                                        return ` ${context.dataset.label}: ${formatMoney(context.parsed.y)}`;
                                    }
                                }
                            }
                        },
                        scales: {
                            x: { grid: { display: false }, ticks: { font: { family: "Plus Jakarta Sans", size: 11 } } },
                            y: {
                                ticks: {
                                    callback: formatYAxis,
                                    font: { family: "Plus Jakarta Sans", size: 10 }
                                }
                            }
                        }
                    }
                });
            }
        }

        function renderLowStockTable(tableId, list) {
            const tbody = document.querySelector(`#${tableId} tbody`);
            if (!tbody) return;
            if (!list || list.length === 0) {
                tbody.innerHTML = `<tr><td colspan="6" class="text-center" style="padding:24px; color:#64748b;">Tất cả hàng hóa đều đạt định mức tồn an toàn.</td></tr>`;
                return;
            }
            tbody.innerHTML = list.map(p => {
                const q = parseFloat(p.stock_qty || 0);
                const m = parseFloat(p.min_stock || 0);
                const isOut = q <= 0;
                return `<tr>
                    <td><strong>${escapeHtml(p.code)}</strong></td>
                    <td><strong>${escapeHtml(p.name)}</strong></td>
                    <td>${escapeHtml(p.unit_name || '')}</td>
                    <td class="text-right font-bold" style="color:${isOut ? '#dc2626' : '#d97706'};">${formatQty(q)} ${isOut ? '(HẾT HÀNG)' : '(Sắp hết)'}</td>
                    <td class="text-right font-bold">${formatQty(m)}</td>
                    <td class="text-center"><span class="badge ${isOut ? 'badge-danger' : 'badge-warning'}">${isOut ? 'HẾT HÀNG' : 'SẮP HẾT'}</span></td>
                </tr>`;
            }).join("");
        }

        function renderInvoicesTable(tableId, list) {
            document.querySelector(`#${tableId} tbody`).innerHTML = list.map(i => {
                const isCancelled = i.status === 'CANCELLED';
                return `
                <tr>
                    <td class="font-mono">${i.code}</td>
                    <td>${i.invoice_date}</td>
                    <td>${i.cashier_name}</td>
                    <td class="font-bold">${i.customer_name || 'Khách lẻ'}</td>
                    <td class="text-right font-bold">${formatMoney(i.total_amount)}</td>
                    <td class="text-right font-bold" style="color: #16a34a;">${formatMoney(i.paid_amount)}</td>
                    <td class="text-right font-bold" style="color: ${i.remaining_debt > 0 ? '#dc2626' : '#64748b'};">${formatMoney(i.remaining_debt)}</td>
                    <td><span class="badge-pill ${i.payment_method === 'TIEN_MAT' ? 'badge-method' : 'badge-bank'}">${i.payment_method === 'TIEN_MAT' ? 'Tiền mặt' : 'Chuyển khoản'}</span></td>
                    ${tableId === 'tbl-all-invoices' ? `<td><span class="badge-pill ${isCancelled ? 'badge-debt' : 'badge-paid'}">${isCancelled ? 'Đã hủy' : 'Hoàn thành'}</span></td>` : ''}
                    <td class="text-center">
                        <button class="btn-act btn-act-view" onclick="viewInvoiceDetails(${i.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/></svg> <span>Xem</span></button>
                    </td>
                </tr>
            `}).join("");
        }

        function renderPurchasesTable(list) {
            document.querySelector("#tbl-purchases tbody").innerHTML = list.map(p => `
                <tr>
                    <td class="font-mono">${p.code}</td>
                    <td>${p.receipt_date}</td>
                    <td class="font-bold">${p.supplier_name || 'NCC lẻ'}</td>
                    <td class="text-right font-bold">${formatMoney(p.total_amount)}</td>
                    <td class="text-right" style="color: #16a34a; font-weight: 700;">${formatMoney(p.paid_amount)}</td>
                    <td class="text-right" style="color: ${p.remaining_debt > 0 ? '#dc2626' : '#64748b'}; font-weight: 700;">${formatMoney(p.remaining_debt)}</td>
                    <td class="text-center">
                        ${p.remaining_debt > 0 ? `<button class="btn-act btn-act-pay" onclick="openPayPurchaseDebt(${p.id}, '${p.code}', ${p.remaining_debt})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg> <span>Trả nợ</span></button>` : `<span style="color:#16a34a; font-size:11.5px; font-weight:700; display:inline-flex; align-items:center; gap:2px;"><svg class="btn-icon" style="color:#16a34a; width:12px; height:12px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg> Đủ</span>`}
                    </td>
                </tr>
            `).join("");
        }

        function renderProductsTable(products) {
            document.querySelector("#tbl-products tbody").innerHTML = products.map(p => `
                <tr>
                    <td class="font-mono">${p.code}</td>
                    <td class="font-bold">${p.name}</td>
                    <td class="font-mono">${p.barcode || '-'}</td>
                    <td>${p.unit_name || 'Cái'}</td>
                    <td class="text-right">${formatMoney(p.cost_price)}</td>
                    <td class="text-right font-bold" style="color: var(--primary);">${formatMoney(p.retail_price)}</td>
                    <td class="text-right font-bold" style="color: ${p.stock_qty <= (p.min_stock || 0) ? '#dc2626' : 'var(--foreground)'};">${formatQty(p.stock_qty)}</td>
                    <td class="text-center" style="white-space:nowrap;">
                        <button class="btn-act btn-act-edit" onclick="openEditProductModal(${p.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> <span>Sửa</span></button>
                        <button class="btn-act btn-act-del" onclick="deleteProduct(${p.id}, '${p.code}', '${p.name}')" title="Xóa"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg></button>
                    </td>
                </tr>
            `).join("");
        }

        function renderCustomersTable(customers) {
            document.querySelector("#tbl-customers tbody").innerHTML = customers.map(c => `
                <tr>
                    <td class="font-mono">${c.code}</td>
                    <td class="font-bold">${c.name}</td>
                    <td>${c.phone || '-'}</td>
                    <td>${c.address || '-'}</td>
                    <td class="text-right font-bold" style="color: ${c.current_debt > 0 ? '#dc2626' : '#16a34a'};">${formatMoney(c.current_debt)}</td>
                    <td class="text-center" style="white-space:nowrap;">
                        <button class="btn-act btn-act-edit" onclick="openEditCustomerModal(${c.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> <span>Sửa</span></button>
                        ${c.current_debt > 0 ? `<button class="btn-act btn-act-pay" onclick="openPayCustomerModal(${c.id}, '${c.name}', ${c.current_debt})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg> <span>Thu nợ</span></button>` : ''}
                    </td>
                </tr>
            `).join("");
        }

        function renderSuppliersTable(suppliers) {
            document.querySelector("#tbl-suppliers tbody").innerHTML = suppliers.map(s => `
                <tr>
                    <td class="font-mono">${s.code}</td>
                    <td class="font-bold">${s.name}</td>
                    <td>${s.phone || '-'}</td>
                    <td class="text-right font-bold" style="color: ${s.current_debt > 0 ? '#ea580c' : '#16a34a'};">${formatMoney(s.current_debt)}</td>
                    <td class="text-center" style="white-space:nowrap;">
                        <button class="btn-act btn-act-edit" onclick="openEditSupplierModal(${s.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> <span>Sửa</span></button>
                        ${s.current_debt > 0 ? `<button class="btn-act btn-act-pay" onclick="openPaySupplierModal(${s.id}, '${s.name}', ${s.current_debt})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg> <span>Trả nợ</span></button>` : ''}
                    </td>
                </tr>
            `).join("");
        }

        function renderFinanceTable(transactions) {
            document.querySelector("#tbl-finance tbody").innerHTML = transactions.map(t => `
                <tr>
                    <td class="font-mono">${t.code}</td>
                    <td>${t.created_at}</td>
                    <td><span class="badge-pill ${t.trans_type === 'THU' ? 'badge-paid' : 'badge-debt'}">${t.trans_type}</span></td>
                    <td class="font-bold">${t.category}</td>
                    <td>${t.partner_name || '-'}</td>
                    <td class="text-right font-bold" style="color: ${t.trans_type === 'THU' ? '#16a34a' : '#dc2626'}">${t.trans_type === 'THU' ? '+' : '-'}${formatMoney(t.amount)}</td>
                    <td>${t.account_name || 'Tiền mặt'}</td>
                    <td>${t.note || ''}</td>
                </tr>
            `).join("");
        }

        function renderAttendanceTable(list) {
            const tbody = document.querySelector("#tbl-attendance tbody");
            if (!tbody) return;
            if (!list || list.length === 0) {
                tbody.innerHTML = '<tr><td colspan="11" class="text-center" style="padding: 24px; color: var(--muted-foreground);">Chưa có bản ghi chấm công nào.</td></tr>';
                return;
            }
            tbody.innerHTML = list.map((item, idx) => {
                const st = item.status || "Hợp lệ";
                let badgeStyle = "background: #ecfdf5; color: #16a34a; border: 1px solid #a7f3d0;";
                if (st.toLowerCase().includes("muộn")) {
                    badgeStyle = "background: #fff7ed; color: #c2410c; border: 1px solid #fed7aa;";
                }
                const inTime = item.check_in_time ? item.check_in_time.slice(0, 8) : "-";
                const outTime = item.check_out_time ? item.check_out_time.slice(0, 8) : "-";
                const hrs = parseFloat(item.total_hours || 0);
                return `
                    <tr>
                        <td class="text-center">${idx + 1}</td>
                        <td class="font-mono">${item.work_date || ""}</td>
                        <td class="font-mono font-bold">${item.employee_code || ""}</td>
                        <td class="font-bold">${item.employee_name || ""}</td>
                        <td class="text-center font-bold" style="color: #16a34a;">${inTime}</td>
                        <td class="text-center font-bold" style="color: ${outTime !== '-' ? '#0284c7' : '#64748b'};">${outTime}</td>
                        <td class="text-right font-bold">${hrs > 0 ? hrs.toFixed(1) + 'h' : '-'}</td>
                        <td class="font-mono" style="font-size: 11.5px; color: #475569;">${item.ip_address || '-'}</td>
                        <td class="text-center"><span class="badge-pill" style="${badgeStyle}">${st}</span></td>
                        <td style="color: #64748b; font-size: 12px;">${item.note || ''}</td>
                        <td class="text-center">
                            <button class="btn-act btn-act-edit" onclick="openEditAttendanceModal(${item.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> <span>Duyệt/Sửa</span></button>
                        </td>
                    </tr>
                `;
            }).join("");
        }

        
        // =====================================================================
        // WEB POS ENGINE (BÁN HÀNG 24/24 TRỰC TIẾP TRÊN WEB)
        // =====================================================================
        let posCart = [];
        let activePosCategory = "ALL";
        let reportPeriod = "today";
        let purchaseCart = [];

        function renderPosCategories() {
            const bar = document.getElementById("pos-category-bar");
            if (!bar) return;
            const cats = (GLOBAL_DATA.categories || []).map(c => c.name);
            let html = `<button class="pos-cat-btn ${activePosCategory === 'ALL' ? 'active' : ''}" onclick="selectPosCategory('ALL')">Tất cả (${(GLOBAL_DATA.products || []).length})</button>`;
            cats.forEach(c => {
                const cnt = (GLOBAL_DATA.products || []).filter(p => (p.category_name || '') === c).length;
                html += `<button class="pos-cat-btn ${activePosCategory === c ? 'active' : ''}" onclick="selectPosCategory('${escapeHtml(c)}')">${escapeHtml(c)} (${cnt})</button>`;
            });
            bar.innerHTML = html;
        }

        function selectPosCategory(cat) {
            activePosCategory = cat;
            renderPosCategories();
            filterPosProducts();
        }

        function filterPosProducts() {
            const grid = document.getElementById("pos-product-grid");
            if (!grid) return;
            const kw = (document.getElementById("pos-search-input")?.value || "").toLowerCase().trim();
            const prods = (GLOBAL_DATA.products || []).filter(p => {
                const matchCat = activePosCategory === 'ALL' || (p.category_name || '') === activePosCategory;
                if (!matchCat) return false;
                if (!kw) return true;
                const matchName = (p.name || '').toLowerCase().includes(kw);
                const matchCode = (p.code || '').toLowerCase().includes(kw);
                const matchBarcode = (p.barcode || '').toLowerCase().includes(kw);
                return matchName || matchCode || matchBarcode;
            });

            if (prods.length === 0) {
                grid.innerHTML = `<div style="grid-column: 1/-1; text-align:center; padding:40px; color:var(--muted-foreground);">Không tìm thấy sản phẩm nào phù hợp.</div>`;
                return;
            }

            grid.innerHTML = prods.map(p => {
                const stock = parseFloat(p.stock_qty || 0);
                const isOut = stock <= 0;
                const stockBadge = isOut 
                    ? `<span class="pos-prod-stock" style="background:#fee2e2; color:#dc2626; border:1px solid #fecaca;">Hết hàng (0)</span>` 
                    : `<span class="pos-prod-stock" style="background:#ecfdf5; color:#16a34a; border:1px solid #a7f3d0;">Còn ${formatQty(stock)} ${p.unit_name || ''}</span>`;
                return `
                    <div class="pos-prod-card ${isOut ? 'out-stock' : ''}" onclick="addToPosCart(${p.id})">
                        <div class="pos-prod-code">${escapeHtml(p.code)}</div>
                        <div class="pos-prod-name" title="${escapeHtml(p.name)}">${escapeHtml(p.name)}</div>
                        <div class="pos-prod-price">${formatMoney(p.retail_price)}</div>
                        ${stockBadge}
                    </div>
                `;
            }).join("");
        }

        function handlePosSearchKey(e) {
            if (e.key === "Enter") {
                const kw = (document.getElementById("pos-search-input")?.value || "").trim().toLowerCase();
                if (!kw) return;
                const exact = (GLOBAL_DATA.products || []).find(p => 
                    (p.barcode || '').toLowerCase() === kw || (p.code || '').toLowerCase() === kw
                );
                if (exact) {
                    addToPosCart(exact.id);
                    document.getElementById("pos-search-input").value = "";
                    filterPosProducts();
                    e.preventDefault();
                }
            }
        }

        function addToPosCart(pId) {
            const p = (GLOBAL_DATA.products || []).find(x => x.id === pId);
            if (!p) return;
            const existing = posCart.find(x => x.product_id === pId);
            if (existing) {
                existing.quantity += 1;
                existing.line_total = existing.quantity * existing.unit_price;
            } else {
                posCart.push({
                    product_id: p.id,
                    product_code: p.code,
                    product_name: p.name,
                    unit_name: p.unit_name || "Cái",
                    unit_price: parseFloat(p.retail_price || 0),
                    unit_cost: parseFloat(p.cost_price || 0),
                    quantity: 1,
                    line_total: parseFloat(p.retail_price || 0),
                    stock_qty: parseFloat(p.stock_qty || 0)
                });
            }
            renderPosCart();
        }

        function changePosCartQty(pId, delta) {
            const item = posCart.find(x => x.product_id === pId);
            if (!item) return;
            item.quantity += delta;
            if (item.quantity <= 0) {
                removePosCartItem(pId);
                return;
            }
            item.line_total = item.quantity * item.unit_price;
            renderPosCart();
        }

        function setPosCartQty(pId, val) {
            const item = posCart.find(x => x.product_id === pId);
            if (!item) return;
            const q = parseFloat(val) || 1;
            item.quantity = Math.max(0.1, q);
            item.line_total = item.quantity * item.unit_price;
            renderPosCart();
        }

        function removePosCartItem(pId) {
            posCart = posCart.filter(x => x.product_id !== pId);
            renderPosCart();
        }

        function clearPosCart() {
            if (posCart.length === 0) return;
            if (!confirm("Bạn có chắc chắn muốn xóa toàn bộ giỏ hàng?")) return;
            posCart = [];
            renderPosCart();
        }

        function renderPosCart() {
            const tbody = document.querySelector("#tbl-pos-cart tbody");
            const cntSpan = document.getElementById("pos-cart-count");
            if (cntSpan) cntSpan.innerText = posCart.length;

            if (!tbody) return;
            if (posCart.length === 0) {
                tbody.innerHTML = `<tr><td colspan="4" style="text-align:center; padding:24px; color:var(--muted-foreground);">Giỏ hàng đang trống.<br>Nhấn vào sản phẩm để chọn.</td></tr>`;
                calcPosTotals();
                return;
            }

            tbody.innerHTML = posCart.map(item => `
                <tr>
                    <td>
                        <div style="font-weight:700; line-height:1.2;">${escapeHtml(item.product_name)}</div>
                        <div style="font-size:11px; color:var(--muted-foreground);">${formatMoney(item.unit_price)} / ${item.unit_name}</div>
                    </td>
                    <td style="text-align:center; white-space:nowrap;">
                        <button type="button" class="cart-qty-btn" onclick="changePosCartQty(${item.product_id}, -1)">-</button>
                        <input type="number" class="cart-qty-input" value="${item.quantity}" onchange="setPosCartQty(${item.product_id}, this.value)">
                        <button type="button" class="cart-qty-btn" onclick="changePosCartQty(${item.product_id}, 1)">+</button>
                    </td>
                    <td style="text-align:right; font-weight:700; color:var(--primary);">${formatMoney(item.line_total)}</td>
                    <td style="text-align:center;">
                        <button type="button" class="btn-act btn-act-del" style="padding:2px 5px; font-size:11px;" onclick="removePosCartItem(${item.product_id})">✕</button>
                    </td>
                </tr>
            `).join("");

            calcPosTotals();
        }

        function calcPosTotals() {
            const subtotal = posCart.reduce((sum, it) => sum + it.line_total, 0);
            const discInput = document.getElementById("pos-discount");
            const discount = parseFloat(discInput?.value || 0) || 0;
            const total = Math.max(0, subtotal - discount);

            const subEl = document.getElementById("pos-subtotal");
            const totEl = document.getElementById("pos-total-amount");
            if (subEl) subEl.innerText = formatMoney(subtotal);
            if (totEl) totEl.innerText = formatMoney(total);

            const method = document.querySelector('input[name="pos-payment-method"]:checked')?.value || "TIEN_MAT";
            const cashPanel = document.getElementById("pos-cash-panel");
            const cashInput = document.getElementById("pos-cash-given");
            const changeVal = document.getElementById("pos-change-val");
            const changeLbl = document.getElementById("pos-change-label");

            if (method === "GHI_NO") {
                if (cashPanel) cashPanel.style.display = "none";
            } else {
                if (cashPanel) cashPanel.style.display = "block";
                let given = parseFloat(cashInput?.value || 0);
                if (given <= 0 || method === "CHUYEN_KHOAN") {
                    given = total;
                    if (cashInput && method === "CHUYEN_KHOAN") cashInput.value = total;
                }
                const diff = given - total;
                if (diff >= 0) {
                    if (changeLbl) changeLbl.innerText = "Tiền thừa trả khách:";
                    if (changeVal) { changeVal.innerText = formatMoney(diff); changeVal.style.color = "#16a34a"; }
                } else {
                    if (changeLbl) changeLbl.innerText = "Còn thiếu (Ghi nợ):";
                    if (changeVal) { changeVal.innerText = formatMoney(Math.abs(diff)); changeVal.style.color = "#dc2626"; }
                }
            }
        }

        function setPosQuickCash(amt) {
            const subtotal = posCart.reduce((sum, it) => sum + it.line_total, 0);
            const discount = parseFloat(document.getElementById("pos-discount")?.value || 0) || 0;
            const total = Math.max(0, subtotal - discount);
            const cashInput = document.getElementById("pos-cash-given");
            if (!cashInput) return;

            if (amt === 'EXACT') {
                cashInput.value = total;
            } else {
                cashInput.value = amt;
            }
            calcPosTotals();
        }

        function posCheckout() {
            if (posCart.length === 0) {
                alert("Giỏ hàng đang trống! Vui lòng chọn sản phẩm trước khi thanh toán.");
                return;
            }

            const subtotal = posCart.reduce((sum, it) => sum + it.line_total, 0);
            const discount = parseFloat(document.getElementById("pos-discount")?.value || 0) || 0;
            const total = Math.max(0, subtotal - discount);
            const custSelect = document.getElementById("pos-customer-select");
            const custId = custSelect?.value || null;
            const custName = custSelect?.selectedOptions[0]?.text || "Khách lẻ";
            const method = document.querySelector('input[name="pos-payment-method"]:checked')?.value || "TIEN_MAT";
            const note = (document.getElementById("pos-order-note")?.value || "").trim();

            let paid = total;
            let debt = 0;
            if (method === "GHI_NO") {
                if (!custId) {
                    alert("Thanh toán ghi nợ bắt buộc phải chọn Khách hàng cụ thể (không được để Khách lẻ)!");
                    return;
                }
                paid = 0;
                debt = total;
            } else {
                const given = parseFloat(document.getElementById("pos-cash-given")?.value || 0);
                if (given < total && method === "TIEN_MAT") {
                    if (!custId) {
                        alert("Khách đưa thiếu tiền! Nếu muốn cho nợ số tiền còn lại, vui lòng chọn Khách hàng cụ thể.");
                        return;
                    }
                    paid = Math.max(0, given);
                    debt = total - paid;
                } else {
                    paid = total;
                    debt = 0;
                }
            }

            const payload = {
                customer_id: custId ? parseInt(custId) : null,
                subtotal: subtotal,
                discount_amount: discount,
                total_amount: total,
                paid_amount: paid,
                remaining_debt: debt,
                payment_method: method,
                note: note,
                items: posCart.map(it => ({
                    product_id: it.product_id,
                    product_code: it.product_code,
                    product_name: it.product_name,
                    unit_name: it.unit_name,
                    quantity: it.quantity,
                    unit_price: it.unit_price,
                    unit_cost: it.unit_cost,
                    line_total: it.line_total,
                    discount_percent: 0,
                    discount_amount: 0,
                    note: ""
                }))
            };

            fetch(apiUrl("pos-checkout"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    showReceiptModal(res.invoice || payload, custName);
                    posCart = [];
                    if (document.getElementById("pos-discount")) document.getElementById("pos-discount").value = 0;
                    if (document.getElementById("pos-order-note")) document.getElementById("pos-order-note").value = "";
                    renderPosCart();
                    loadData(true);
                } else {
                    alert("Lỗi thanh toán: " + res.error);
                }
            }).catch(e => {
                alert("Lỗi kết nối máy chủ thanh toán: " + e);
            });
        }

        function showReceiptModal(inv, custName) {
            const storeName = GLOBAL_DATA.store_name || "CỬA HÀNG ĐA NGÀNH";
            const storeAddr = GLOBAL_DATA.store_address || "";
            const storePhone = GLOBAL_DATA.store_phone || "";

            document.getElementById("rcpt-store-name").innerText = storeName;
            document.getElementById("rcpt-store-addr").innerText = storeAddr ? `Địa chỉ: ${storeAddr}` : "";
            document.getElementById("rcpt-store-phone").innerText = storePhone ? `SĐT: ${storePhone}` : "";
            document.getElementById("rcpt-code-time").innerText = `Mã: ${inv.code || 'HD...'} | ${inv.invoice_date || ''}`;
            document.getElementById("rcpt-customer").innerText = `Khách hàng: ${custName || 'Khách lẻ'}`;

            const items = inv.items_detail || inv.items || [];
            document.getElementById("rcpt-items-body").innerHTML = items.map(it => `
                <tr>
                    <td style="padding:3px 0;">${escapeHtml(it.product_name || '')}</td>
                    <td style="text-align:center;">${formatQty(it.quantity || 1)}</td>
                    <td style="text-align:right;">${formatMoney(it.unit_price || 0)}</td>
                    <td style="text-align:right; font-weight:700;">${formatMoney(it.line_total || 0)}</td>
                </tr>
            `).join("");

            document.getElementById("rcpt-subtotal").innerText = formatMoney(inv.subtotal || 0);
            const disc = parseFloat(inv.discount_amount || 0);
            if (disc > 0) {
                document.getElementById("rcpt-disc-row").style.display = "flex";
                document.getElementById("rcpt-discount").innerText = "-" + formatMoney(disc);
            } else {
                document.getElementById("rcpt-disc-row").style.display = "none";
            }

            document.getElementById("rcpt-total").innerText = formatMoney(inv.total_amount || 0);
            document.getElementById("rcpt-paid").innerText = formatMoney(inv.paid_amount || 0);

            const debt = parseFloat(inv.remaining_debt || 0);
            if (debt > 0) {
                document.getElementById("rcpt-change-lbl").innerText = "Còn nợ:";
                document.getElementById("rcpt-change").innerText = formatMoney(debt);
                document.getElementById("rcpt-change").style.color = "#dc2626";
            } else {
                document.getElementById("rcpt-change-lbl").innerText = "Tiền thừa:";
                document.getElementById("rcpt-change").innerText = "0 đ";
                document.getElementById("rcpt-change").style.color = "#000";
            }

            const methodMap = { "TIEN_MAT": "Tiền mặt", "CHUYEN_KHOAN": "Chuyển khoản", "GHI_NO": "Ghi nợ" };
            document.getElementById("rcpt-method").innerText = methodMap[inv.payment_method] || inv.payment_method || "Tiền mặt";

            openModal("modal-pos-receipt");
        }

        // Keyboard Shortcuts: F2 for search, F9 for checkout
        document.addEventListener("keydown", function(e) {
            if (e.key === "F2") {
                const searchInp = document.getElementById("pos-search-input");
                if (searchInp) {
                    searchInp.focus();
                    searchInp.select();
                    e.preventDefault();
                }
            } else if (e.key === "F9") {
                const posTab = document.getElementById("tab-pos");
                if (posTab && posTab.classList.contains("active")) {
                    posCheckout();
                    e.preventDefault();
                }
            }
        });

        // =====================================================================
        // PURCHASES MODAL & ACTIONS
        // =====================================================================
        function openCreatePurchaseModal() {
            purchaseCart = [];
            const suppSelect = document.getElementById("pur-supplier-select");
            if (suppSelect) {
                const supps = GLOBAL_DATA.all_suppliers || GLOBAL_DATA.debt_suppliers || [];
                suppSelect.innerHTML = `<option value="">-- Chọn NCC (hoặc NCC lẻ) --</option>` + supps.map(s => `
                    <option value="${s.id}">${escapeHtml(s.name)}${s.phone ? ' (' + s.phone + ')' : ''}</option>
                `).join("");
            }

            const prodSelect = document.getElementById("pur-product-select");
            if (prodSelect) {
                const prods = GLOBAL_DATA.products || [];
                prodSelect.innerHTML = `<option value="">+ Chọn hàng hóa thêm vào phiếu...</option>` + prods.map(p => `
                    <option value="${p.id}">${escapeHtml(p.code)} - ${escapeHtml(p.name)} (${formatMoney(p.cost_price)})</option>
                `).join("");
            }

            if (document.getElementById("pur-discount")) document.getElementById("pur-discount").value = 0;
            if (document.getElementById("pur-note")) document.getElementById("pur-note").value = "";
            renderPurchaseCart();
            openModal("modal-create-purchase");
        }

        function addPurchaseItem(pId) {
            if (!pId) return;
            const p = (GLOBAL_DATA.products || []).find(x => x.id === parseInt(pId));
            if (!p) return;
            const existing = purchaseCart.find(x => x.product_id === p.id);
            if (existing) {
                existing.quantity += 1;
                existing.line_total = existing.quantity * existing.unit_cost;
            } else {
                purchaseCart.push({
                    product_id: p.id,
                    product_code: p.code,
                    product_name: p.name,
                    unit_name: p.unit_name || "Cái",
                    unit_cost: parseFloat(p.cost_price || 0),
                    quantity: 1,
                    line_total: parseFloat(p.cost_price || 0)
                });
            }
            renderPurchaseCart();
        }

        function removePurchaseItem(pId) {
            purchaseCart = purchaseCart.filter(x => x.product_id !== pId);
            renderPurchaseCart();
        }

        function renderPurchaseCart() {
            const tbody = document.querySelector("#tbl-pur-items tbody");
            if (!tbody) return;
            if (purchaseCart.length === 0) {
                tbody.innerHTML = `<tr><td colspan="6" class="text-center" style="padding:16px; color:var(--muted-foreground);">Chưa có sản phẩm nào trong phiếu nhập.</td></tr>`;
                calcPurchaseTotals();
                return;
            }

            tbody.innerHTML = purchaseCart.map(it => `
                <tr>
                    <td class="font-bold">${escapeHtml(it.product_name)}</td>
                    <td>${escapeHtml(it.unit_name)}</td>
                    <td class="text-right">
                        <input type="number" class="cart-qty-input" style="width:85px; text-align:right;" value="${it.unit_cost}" onchange="updatePurchaseCost(${it.product_id}, this.value)">
                    </td>
                    <td class="text-center">
                        <input type="number" class="cart-qty-input" style="width:60px;" value="${it.quantity}" onchange="updatePurchaseQty(${it.product_id}, this.value)">
                    </td>
                    <td class="text-right font-bold" style="color:var(--primary);">${formatMoney(it.line_total)}</td>
                    <td class="text-center">
                        <button class="btn-act btn-act-del" style="padding:2px 5px;" onclick="removePurchaseItem(${it.product_id})">✕</button>
                    </td>
                </tr>
            `).join("");

            calcPurchaseTotals();
        }

        function updatePurchaseCost(pId, val) {
            const it = purchaseCart.find(x => x.product_id === pId);
            if (!it) return;
            it.unit_cost = parseFloat(val) || 0;
            it.line_total = it.quantity * it.unit_cost;
            renderPurchaseCart();
        }

        function updatePurchaseQty(pId, val) {
            const it = purchaseCart.find(x => x.product_id === pId);
            if (!it) return;
            it.quantity = parseFloat(val) || 1;
            it.line_total = it.quantity * it.unit_cost;
            renderPurchaseCart();
        }

        function calcPurchaseTotals(manualPaid = false) {
            const subtotal = purchaseCart.reduce((sum, it) => sum + it.line_total, 0);
            const discount = parseFloat(document.getElementById("pur-discount")?.value || 0) || 0;
            const total = Math.max(0, subtotal - discount);

            const subEl = document.getElementById("pur-subtotal");
            const totEl = document.getElementById("pur-total");
            if (subEl) subEl.innerText = formatMoney(subtotal);
            if (totEl) totEl.innerText = formatMoney(total);

            const method = document.getElementById("pur-pay-method")?.value || "TIEN_MAT";
            const paidInp = document.getElementById("pur-paid");
            const debtEl = document.getElementById("pur-debt");

            if (!manualPaid) {
                if (paidInp) paidInp.value = method === "GHI_NO" ? 0 : total;
            }

            const paid = parseFloat(paidInp?.value || 0) || 0;
            const debt = Math.max(0, total - paid);
            if (debtEl) debtEl.innerText = formatMoney(debt);
        }

        function submitCreatePurchase() {
            if (purchaseCart.length === 0) {
                alert("Phiếu nhập chưa có hàng hóa nào! Vui lòng chọn sản phẩm.");
                return;
            }

            const subtotal = purchaseCart.reduce((sum, it) => sum + it.line_total, 0);
            const discount = parseFloat(document.getElementById("pur-discount")?.value || 0) || 0;
            const total = Math.max(0, subtotal - discount);
            const suppId = document.getElementById("pur-supplier-select")?.value || null;
            const method = document.getElementById("pur-pay-method")?.value || "TIEN_MAT";
            const paid = parseFloat(document.getElementById("pur-paid")?.value || 0);
            const debt = Math.max(0, total - paid);
            const note = (document.getElementById("pur-note")?.value || "").trim();

            if (debt > 0 && !suppId) {
                alert("Phiếu nhập ghi nợ bắt buộc phải chọn Nhà Cung Cấp cụ thể!");
                return;
            }

            const payload = {
                supplier_id: suppId ? parseInt(suppId) : null,
                subtotal: subtotal,
                discount_amount: discount,
                total_amount: total,
                paid_amount: paid,
                remaining_debt: debt,
                payment_method: method,
                note: note,
                items: purchaseCart.map(it => ({
                    product_id: it.product_id,
                    product_code: it.product_code,
                    product_name: it.product_name,
                    unit_name: it.unit_name,
                    quantity: it.quantity,
                    unit_cost: it.unit_cost,
                    line_total: it.line_total,
                    note: ""
                }))
            };

            fetch(apiUrl("create-purchase"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    alert(res.message || "Tạo phiếu nhập thành công!");
                    closeModal("modal-create-purchase");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        // =====================================================================
        // HR MANAGEMENT (NHÂN SỰ, CHẤM CÔNG, TẠM ỨNG, BẢNG LƯƠNG)
        // =====================================================================
        function switchHrSubtab(tab) {
            document.querySelectorAll("#tab-hr .subtab-btn").forEach(b => b.classList.remove("active"));
            document.querySelectorAll("#tab-hr .hr-subcontent").forEach(c => c.style.display = "none");

            if (tab === 'employees') {
                document.getElementById("btn-hr-sub-emp")?.classList.add("active");
                document.getElementById("hr-sub-employees").style.display = "block";
            } else if (tab === 'attendance') {
                document.getElementById("btn-hr-sub-att")?.classList.add("active");
                document.getElementById("hr-sub-attendance").style.display = "block";
            } else if (tab === 'advances') {
                document.getElementById("btn-hr-sub-adv")?.classList.add("active");
                document.getElementById("hr-sub-advances").style.display = "block";
            } else if (tab === 'payroll') {
                document.getElementById("btn-hr-sub-pay")?.classList.add("active");
                document.getElementById("hr-sub-payroll").style.display = "block";
                renderPayrollTable();
            }
        }

        function renderEmployeesTable(employees) {
            const tbody = document.querySelector("#tbl-hr-employees tbody");
            if (!tbody) return;
            if (!employees || employees.length === 0) {
                tbody.innerHTML = `<tr><td colspan="10" class="text-center" style="padding:24px; color:var(--muted-foreground);">Chưa có nhân viên nào. Nhấn "+ Thêm Nhân Viên" để tạo mới.</td></tr>`;
                return;
            }

            tbody.innerHTML = employees.map(e => {
                const bSal = parseFloat(e.base_salary || 0);
                const hRate = parseFloat(e.hourly_rate || 0);
                const ins = parseFloat(e.insurance_amount || 0);
                const allow = parseFloat(e.allowance_amount || 0);
                const isAct = e.is_active === 1 || e.is_active === "1";
                return `
                    <tr>
                        <td class="font-mono font-bold">${escapeHtml(e.code)}</td>
                        <td class="font-bold">${escapeHtml(e.full_name)}</td>
                        <td>${escapeHtml(e.phone || '-')}</td>
                        <td>${escapeHtml(e.position || 'Nhân viên')}</td>
                        <td class="text-right font-bold" style="color:var(--primary);">${bSal > 0 ? formatMoney(bSal) : '-'}</td>
                        <td class="text-right">${hRate > 0 ? formatMoney(hRate) + ' /h' : '-'}</td>
                        <td class="text-right" style="color:#dc2626;">${ins > 0 ? formatMoney(ins) : '-'}</td>
                        <td class="text-right">${allow > 0 ? formatMoney(allow) : '-'}</td>
                        <td class="text-center"><span class="badge ${isAct ? 'badge-success' : 'badge-danger'}">${isAct ? 'Đang làm' : 'Đã nghỉ'}</span></td>
                        <td class="text-center" style="white-space:nowrap;">
                            <button class="btn-act btn-act-edit" onclick="openEditEmployeeModal(${e.id})"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> <span>Sửa</span></button>
                            <button class="btn-act btn-act-del" onclick="deleteEmployee(${e.id}, '${e.code}', '${escapeHtml(e.full_name)}')" title="Xóa nhân viên"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg></button>
                        </td>
                    </tr>
                `;
            }).join("");
        }

        function toggleEmpSalaryType() {
            const type = document.querySelector('input[name="emp-salary-type"]:checked')?.value || "BASE";
            const basePanel = document.getElementById("emp-base-panel");
            const hourlyPanel = document.getElementById("emp-hourly-panel");
            if (type === "BASE") {
                if (basePanel) basePanel.style.display = "block";
                if (hourlyPanel) hourlyPanel.style.display = "none";
                onEmpBaseSalaryInput();
            } else {
                if (basePanel) basePanel.style.display = "none";
                if (hourlyPanel) hourlyPanel.style.display = "block";
                const insInp = document.getElementById("emp-insurance");
                if (insInp) insInp.value = 0;
            }
        }

        function onEmpBaseSalaryInput() {
            const bSal = parseFloat(document.getElementById("emp-base-salary")?.value || 0) || 0;
            const dailyRate = Math.round(bSal / 24);
            const dailyTxt = document.getElementById("emp-daily-rate-txt");
            if (dailyTxt) dailyTxt.innerText = formatMoney(dailyRate);

            // Auto calculate 10.5% BHXH
            const ins = Math.round(bSal * 0.105);
            const insInp = document.getElementById("emp-insurance");
            if (insInp) insInp.value = ins;
        }

        function openAddEmployeeModal() {
            document.getElementById("modal-emp-title").innerText = "Thêm Nhân Viên Mới";
            document.getElementById("emp-id").value = "";
            document.getElementById("emp-code").value = "";
            document.getElementById("emp-name").value = "";
            document.getElementById("emp-phone").value = "";
            document.getElementById("emp-position").value = "Nhân viên bán hàng";
            document.getElementById("emp-username").value = "";
            document.getElementById("emp-password").value = "123456";
            document.getElementById("emp-base-salary").value = "5000000";
            document.getElementById("emp-hourly-rate").value = "25000";
            document.getElementById("emp-allowance").value = "0";
            document.getElementById("emp-allowance-desc").value = "";
            
            const rBase = document.querySelector('input[name="emp-salary-type"][value="BASE"]');
            if (rBase) rBase.checked = true;
            toggleEmpSalaryType();
            openModal("modal-employee");
        }

        function openEditEmployeeModal(id) {
            const emp = (GLOBAL_DATA.employees || []).find(x => x.id === id);
            if (!emp) return;
            document.getElementById("modal-emp-title").innerText = "Sửa Nhân Viên: " + emp.full_name;
            document.getElementById("emp-id").value = emp.id;
            document.getElementById("emp-code").value = emp.code;
            document.getElementById("emp-name").value = emp.full_name;
            document.getElementById("emp-phone").value = emp.phone || "";
            document.getElementById("emp-position").value = emp.position || "Nhân viên";
            document.getElementById("emp-username").value = emp.username || "";
            document.getElementById("emp-password").value = emp.password_plain || "123456";
            document.getElementById("emp-base-salary").value = emp.base_salary || 0;
            document.getElementById("emp-hourly-rate").value = emp.hourly_rate || 0;
            document.getElementById("emp-allowance").value = emp.allowance_amount || 0;
            document.getElementById("emp-allowance-desc").value = emp.allowance_details || "";

            const bSal = parseFloat(emp.base_salary || 0);
            if (bSal > 0) {
                const rBase = document.querySelector('input[name="emp-salary-type"][value="BASE"]');
                if (rBase) rBase.checked = true;
                document.getElementById("emp-insurance").value = emp.insurance_amount || Math.round(bSal * 0.105);
            } else {
                const rHourly = document.querySelector('input[name="emp-salary-type"][value="HOURLY"]');
                if (rHourly) rHourly.checked = true;
                document.getElementById("emp-insurance").value = 0;
            }
            toggleEmpSalaryType();
            openModal("modal-employee");
        }

        function submitEmployee() {
            const name = (document.getElementById("emp-name")?.value || "").trim();
            if (!name) { alert("Vui lòng nhập họ và tên nhân viên!"); return; }

            const type = document.querySelector('input[name="emp-salary-type"]:checked')?.value || "BASE";
            const bSal = type === "BASE" ? (parseFloat(document.getElementById("emp-base-salary")?.value) || 0) : 0;
            const hRate = type === "HOURLY" ? (parseFloat(document.getElementById("emp-hourly-rate")?.value) || 0) : 0;
            const ins = type === "BASE" ? (parseFloat(document.getElementById("emp-insurance")?.value) || Math.round(bSal * 0.105)) : 0;

            const payload = {
                id: document.getElementById("emp-id").value || null,
                code: (document.getElementById("emp-code")?.value || "").trim(),
                full_name: name,
                phone: (document.getElementById("emp-phone")?.value || "").trim(),
                position: (document.getElementById("emp-position")?.value || "").trim(),
                username: (document.getElementById("emp-username")?.value || "").trim(),
                password_plain: (document.getElementById("emp-password")?.value || "").trim(),
                base_salary: bSal,
                hourly_rate: hRate,
                commission_rate: 0,
                insurance_amount: ins,
                allowance_amount: parseFloat(document.getElementById("emp-allowance")?.value) || 0,
                allowance_details: (document.getElementById("emp-allowance-desc")?.value || "").trim(),
                ot_multiplier: 1.5,
                is_active: 1
            };

            fetch(apiUrl("save-employee"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-employee");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function deleteEmployee(id, code, name) {
            if (!confirm(`Bạn có chắc chắn muốn xóa / ngừng kích hoạt nhân viên "${name}" (${code})?`)) return;
            fetch(apiUrl("delete-employee"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({ id: id, code: code })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') loadData(true);
                else alert("Lỗi: " + res.error);
            });
        }

        function renderAdvancesTable(advances) {
            const tbody = document.querySelector("#tbl-hr-advances tbody");
            if (!tbody) return;
            if (!advances || advances.length === 0) {
                tbody.innerHTML = `<tr><td colspan="6" class="text-center" style="padding:24px; color:var(--muted-foreground);">Chưa có khoản tạm ứng lương nào trong hệ thống.</td></tr>`;
                return;
            }

            tbody.innerHTML = advances.map(a => `
                <tr>
                    <td class="font-mono font-bold">${escapeHtml(a.employee_code)}</td>
                    <td class="font-bold">${escapeHtml(a.employee_name || a.employee_code)}</td>
                    <td class="font-mono">${escapeHtml(a.month_year || '')}</td>
                    <td>${escapeHtml(a.advance_date || '')}</td>
                    <td class="text-right font-bold" style="color:#d97706;">${formatMoney(a.amount)}</td>
                    <td>${escapeHtml(a.reason || 'Tạm ứng lương')}</td>
                </tr>
            `).join("");
        }

        function openAddAdvanceModal() {
            const sel = document.getElementById("adv-emp-select");
            if (sel) {
                const emps = GLOBAL_DATA.employees || [];
                sel.innerHTML = `<option value="">-- Chọn nhân viên --</option>` + emps.map(e => `
                    <option value="${e.code}">${escapeHtml(e.code)} - ${escapeHtml(e.full_name)}</option>
                `).join("");
            }

            const now = new Date();
            const ym = now.toISOString().slice(0, 7);
            const ymd = now.toISOString().slice(0, 10);
            if (document.getElementById("adv-month")) document.getElementById("adv-month").value = ym;
            if (document.getElementById("adv-date")) document.getElementById("adv-date").value = ymd;
            if (document.getElementById("adv-amount")) document.getElementById("adv-amount").value = "";
            openModal("modal-salary-advance");
        }

        function submitSalaryAdvance() {
            const code = document.getElementById("adv-emp-select")?.value;
            if (!code) { alert("Vui lòng chọn nhân viên!"); return; }
            const amt = parseFloat(document.getElementById("adv-amount")?.value) || 0;
            if (amt <= 0) { alert("Vui lòng nhập số tiền tạm ứng hợp lệ!"); return; }

            const payload = {
                employee_code: code,
                month_year: document.getElementById("adv-month")?.value,
                advance_date: document.getElementById("adv-date")?.value,
                amount: amt,
                reason: (document.getElementById("adv-reason")?.value || "").trim() || "Tạm ứng lương"
            };

            fetch(apiUrl("save-advance"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-salary-advance");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function renderPayrollTable() {
            const tbody = document.querySelector("#tbl-hr-payroll tbody");
            if (!tbody) return;
            const monthInp = document.getElementById("hr-payroll-month");
            const curMonth = monthInp?.value || (new Date()).toISOString().slice(0, 7);
            if (monthInp && !monthInp.value) monthInp.value = curMonth;

            const emps = GLOBAL_DATA.employees || [];
            if (emps.length === 0) {
                tbody.innerHTML = `<tr><td colspan="11" class="text-center" style="padding:24px; color:var(--muted-foreground);">Chưa có dữ liệu nhân viên.</td></tr>`;
                return;
            }

            const attLogs = GLOBAL_DATA.attendance_logs || [];
            const advances = GLOBAL_DATA.salary_advances || [];
            const payrolls = GLOBAL_DATA.payrolls || [];

            tbody.innerHTML = emps.map(e => {
                const bSal = parseFloat(e.base_salary || 0);
                const hRate = parseFloat(e.hourly_rate || 0);
                const isBase = bSal > 0;

                // Tính công thực tế trong tháng
                const empLogs = attLogs.filter(a => 
                    (a.employee_code || '').toUpperCase() === (e.code || '').toUpperCase() &&
                    (a.work_date || '').startsWith(curMonth)
                );
                const workDays = empLogs.length > 0 ? empLogs.length : 24.0; // Mặc định 24 công nếu chưa có log
                const totalHours = empLogs.reduce((sum, a) => sum + parseFloat(a.total_hours || 8.0), 0) || (workDays * 8.0);

                let mainSalary = 0;
                let insDeduction = 0;

                if (isBase) {
                    // Logic 24 công chuẩn: Lương cơ bản / 24 * số ngày công
                    const dailyRate = bSal / 24.0;
                    mainSalary = Math.round(dailyRate * Math.min(workDays, 24));
                    // BHXH 10.5%
                    insDeduction = parseFloat(e.insurance_amount || 0) || Math.round(bSal * 0.105);
                } else if (hRate > 0) {
                    mainSalary = Math.round(hRate * totalHours);
                    insDeduction = 0; // Part-time không trừ BHXH cơ bản
                }

                const allowance = parseFloat(e.allowance_amount || 0);

                // Tạm ứng của nhân viên trong tháng
                const empAdvances = advances.filter(a => 
                    (a.employee_code || '').toUpperCase() === (e.code || '').toUpperCase() &&
                    (a.month_year || '').startsWith(curMonth)
                );
                const advanceTotal = empAdvances.reduce((sum, a) => sum + parseFloat(a.amount || 0), 0);

                const netSalary = Math.max(0, mainSalary + allowance - insDeduction - advanceTotal);

                // Trạng thái từ bảng lương
                const pr = payrolls.find(p => (p.employee_code || '').toUpperCase() === (e.code || '').toUpperCase() && p.month_year === curMonth);
                const isPaid = pr && (pr.payment_status === 'PAID' || pr.payment_status === 'Đã thanh toán');

                return `
                    <tr>
                        <td class="font-mono font-bold">${escapeHtml(e.code)}</td>
                        <td class="font-bold">${escapeHtml(e.full_name)}</td>
                        <td>${escapeHtml(e.position || 'Nhân viên')}</td>
                        <td class="text-right">${isBase ? (workDays + ' công') : (totalHours.toFixed(1) + ' giờ')}</td>
                        <td class="text-right font-bold">${formatMoney(mainSalary)}</td>
                        <td class="text-right">${allowance > 0 ? formatMoney(allowance) : '0 đ'}</td>
                        <td class="text-right" style="color:#dc2626;">${insDeduction > 0 ? '-' + formatMoney(insDeduction) : '0 đ'}</td>
                        <td class="text-right" style="color:#d97706;">${advanceTotal > 0 ? '-' + formatMoney(advanceTotal) : '0 đ'}</td>
                        <td class="text-right font-bold" style="color:#16a34a; font-size:14px;">${formatMoney(netSalary)}</td>
                        <td class="text-center">
                            <span class="badge ${isPaid ? 'badge-success' : 'badge-warning'}">${isPaid ? 'Đã thanh toán' : 'Chưa chi'}</span>
                        </td>
                        <td class="text-center">
                            ${!isPaid ? `<button class="btn-act btn-act-pay" onclick="submitPayrollPayment('${e.code}', '${curMonth}')"><svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg> <span>Chi Lương</span></button>` : `<span style="color:#16a34a; font-weight:700; font-size:11.5px;">✓ Đã chi</span>`}
                        </td>
                    </tr>
                `;
            }).join("");
        }

        function submitPayrollPayment(empCode, monthYear) {
            if (!confirm(`Xác nhận đã thanh toán lương tháng ${monthYear} cho nhân viên ${empCode}?`)) return;
            fetch(apiUrl("save-payroll-status"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({ employee_code: empCode, month_year: monthYear, status: "Đã thanh toán" })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') loadData(true);
                else alert("Lỗi: " + res.error);
            });
        }

        // =====================================================================
        // REPORTS ENGINE
        // =====================================================================
        function setReportPeriod(p) {
            reportPeriod = p;
            document.querySelectorAll("#tab-reports .subtab-btn").forEach(b => b.classList.remove("active"));
            const btn = document.getElementById("btn-rep-" + p);
            if (btn) btn.classList.add("active");
            renderReports();
        }

        function renderReports() {
            const invoices = (GLOBAL_DATA.recent_invoices || []).filter(i => i.status !== 'CANCELLED');
            const now = new Date();
            const todayStr = now.toISOString().slice(0, 10);
            const monthStr = now.toISOString().slice(0, 7);

            let filteredInvoices = invoices;
            if (reportPeriod === 'today') {
                filteredInvoices = invoices.filter(i => (i.invoice_date || '').startsWith(todayStr));
            } else if (reportPeriod === '7days') {
                const d7 = new Date(); d7.setDate(d7.getDate() - 7);
                const d7Str = d7.toISOString().slice(0, 10);
                filteredInvoices = invoices.filter(i => (i.invoice_date || '').slice(0, 10) >= d7Str);
            } else if (reportPeriod === 'month') {
                filteredInvoices = invoices.filter(i => (i.invoice_date || '').startsWith(monthStr));
            }

            const totalRev = filteredInvoices.reduce((sum, i) => sum + parseFloat(i.total_amount || 0), 0);
            const totalCogs = filteredInvoices.reduce((sum, i) => sum + parseFloat(i.total_cost || 0), 0);
            const grossProfit = totalRev - totalCogs;

            // Finance expenses (CHI)
            const transactions = GLOBAL_DATA.recent_transactions || [];
            let filteredTrans = transactions.filter(t => t.trans_type === 'CHI');
            if (reportPeriod === 'today') {
                filteredTrans = filteredTrans.filter(t => (t.created_at || '').startsWith(todayStr));
            } else if (reportPeriod === '7days') {
                const d7 = new Date(); d7.setDate(d7.getDate() - 7);
                filteredTrans = filteredTrans.filter(t => (t.created_at || '').slice(0, 10) >= d7.toISOString().slice(0, 10));
            } else if (reportPeriod === 'month') {
                filteredTrans = filteredTrans.filter(t => (t.created_at || '').startsWith(monthStr));
            }
            const totalExpense = filteredTrans.reduce((sum, t) => sum + parseFloat(t.amount || 0), 0);
            const netProfit = grossProfit - totalExpense;

            const repRev = document.getElementById("rep-rev");
            const repInv = document.getElementById("rep-inv-count");
            const repProf = document.getElementById("rep-profit");
            const repCogs = document.getElementById("rep-cogs");
            const repExp = document.getElementById("rep-expense");
            const repNet = document.getElementById("rep-net-profit");

            if (repRev) repRev.innerText = formatMoney(totalRev);
            if (repInv) repInv.innerText = `${filteredInvoices.length} đơn bán hàng`;
            if (repProf) repProf.innerText = formatMoney(grossProfit);
            if (repCogs) repCogs.innerText = `Giá vốn: ${formatMoney(totalCogs)}`;
            if (repExp) repExp.innerText = formatMoney(totalExpense);
            if (repNet) {
                repNet.innerText = formatMoney(netProfit);
                repNet.style.color = netProfit >= 0 ? "#16a34a" : "#dc2626";
            }

            // Top Products Table (from catalog stock and sales)
            const topTbody = document.querySelector("#tbl-report-top-products tbody");
            if (topTbody) {
                const prods = [...(GLOBAL_DATA.products || [])];
                prods.sort((a, b) => parseFloat(b.retail_price || 0) - parseFloat(a.retail_price || 0));
                topTbody.innerHTML = prods.slice(0, 10).map((p, idx) => `
                    <tr>
                        <td class="text-center font-bold">${idx + 1}</td>
                        <td class="font-mono font-bold">${escapeHtml(p.code)}</td>
                        <td class="font-bold">${escapeHtml(p.name)}</td>
                        <td>${escapeHtml(p.unit_name || 'Cái')}</td>
                        <td class="text-right font-bold" style="color:var(--primary);">${formatQty(p.stock_qty || 0)}</td>
                        <td class="text-right font-bold">${formatMoney(p.retail_price || 0)}</td>
                    </tr>
                `).join("");
            }
        }

        // Modals management
        function openModal(id) { document.getElementById(id).classList.add("active"); }
        function closeModal(id) { document.getElementById(id).classList.remove("active"); }

        // Product Modal
        function openAddProductModal() {
            document.getElementById("modal-product-title").innerText = "Thêm Hàng Hóa Mới";
            document.getElementById("p-id").value = "";
            document.getElementById("p-code").value = "";
            document.getElementById("p-barcode").value = "";
            document.getElementById("p-name").value = "";
            document.getElementById("p-unit").value = "Cái";
            document.getElementById("p-cost").value = "0";
            document.getElementById("p-retail").value = "0";
            document.getElementById("p-stock").value = "0";
            document.getElementById("p-min-stock").value = "0";
            openModal("modal-product");
        }

        function openEditProductModal(id) {
            const p = GLOBAL_DATA.products.find(x => x.id === id);
            if (!p) return;
            document.getElementById("modal-product-title").innerText = "Sửa Hàng Hóa: " + p.name;
            document.getElementById("p-id").value = p.id;
            document.getElementById("p-code").value = p.code;
            document.getElementById("p-barcode").value = p.barcode || "";
            document.getElementById("p-name").value = p.name;
            document.getElementById("p-unit").value = p.unit_name || "Cái";
            document.getElementById("p-cost").value = p.cost_price;
            document.getElementById("p-retail").value = p.retail_price;
            document.getElementById("p-stock").value = p.stock_qty;
            document.getElementById("p-min-stock").value = p.min_stock || 0;
            openModal("modal-product");
        }

        function submitProduct() {
            const name = document.getElementById("p-name").value.trim();
            if (!name) { alert("Vui lòng nhập tên hàng hóa!"); return; }
            const retail_val = parseFloat(document.getElementById("p-retail").value) || 0;
            const payload = {
                id: document.getElementById("p-id").value,
                code: document.getElementById("p-code").value.trim(),
                barcode: document.getElementById("p-barcode").value.trim(),
                name: name,
                unit_name: document.getElementById("p-unit").value.trim(),
                cost_price: parseFloat(document.getElementById("p-cost").value) || 0,
                retail_price: retail_val,
                wholesale_price: retail_val,
                stock_qty: parseFloat(document.getElementById("p-stock").value) || 0,
                min_stock: parseFloat(document.getElementById("p-min-stock").value) || 0
            };
            fetch(apiUrl("save-product"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-product");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function deleteProduct(id, code, name) {
            if (!confirm(`Bạn có chắc chắn muốn ngừng kinh doanh sản phẩm "${name}" (${code})?`)) return;
            fetch(apiUrl("delete-product"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({ id: id, code: code })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') loadData(true);
                else alert("Lỗi: " + res.error);
            });
        }

        // Customer Modal
        function openAddCustomerModal() {
            document.getElementById("modal-customer-title").innerText = "Thêm Khách Hàng";
            document.getElementById("c-id").value = "";
            document.getElementById("c-code").value = "";
            document.getElementById("c-name").value = "";
            document.getElementById("c-phone").value = "";
            document.getElementById("c-address").value = "";
            document.getElementById("c-init-debt").value = "0";
            document.getElementById("c-init-debt-group").style.display = "block";
            openModal("modal-customer");
        }

        function openEditCustomerModal(id) {
            const list = GLOBAL_DATA.all_customers || GLOBAL_DATA.debt_customers || [];
            const c = list.find(x => x.id === id);
            if (!c) return;
            document.getElementById("modal-customer-title").innerText = "Sửa Khách Hàng: " + c.name;
            document.getElementById("c-id").value = c.id;
            document.getElementById("c-code").value = c.code;
            document.getElementById("c-name").value = c.name;
            document.getElementById("c-phone").value = c.phone || "";
            document.getElementById("c-address").value = c.address || "";
            document.getElementById("c-init-debt-group").style.display = "none";
            openModal("modal-customer");
        }

        function submitCustomer() {
            const name = document.getElementById("c-name").value.trim();
            if (!name) { alert("Vui lòng nhập tên khách hàng!"); return; }
            const payload = {
                id: document.getElementById("c-id").value,
                code: document.getElementById("c-code").value.trim(),
                name: name,
                phone: document.getElementById("c-phone").value.trim(),
                address: document.getElementById("c-address").value.trim(),
                initial_debt: parseFloat(document.getElementById("c-init-debt").value) || 0
            };
            fetch(apiUrl("save-customer"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify(payload)
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-customer");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function openPayCustomerModal(id, name, debt) {
            document.getElementById("pay-c-id").value = id;
            document.getElementById("pay-c-name").innerText = name;
            document.getElementById("pay-c-debt").innerText = formatMoney(debt);
            document.getElementById("pay-c-amount").value = debt;
            openModal("modal-pay-customer");
        }

        function submitPayCustomerDebt() {
            const c_id = document.getElementById("pay-c-id").value;
            const amount = parseFloat(document.getElementById("pay-c-amount").value) || 0;
            if (amount <= 0) { alert("Vui lòng nhập số tiền hợp lệ!"); return; }
            fetch(apiUrl("pay-customer-debt"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    customer_id: c_id,
                    amount: amount,
                    account_id: document.getElementById("pay-c-account").value,
                    note: document.getElementById("pay-c-note").value.trim()
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-pay-customer");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        // Supplier Modal
        function openAddSupplierModal() {
            document.getElementById("modal-supplier-title").innerText = "Thêm Nhà Cung Cấp";
            document.getElementById("s-id").value = "";
            document.getElementById("s-code").value = "";
            document.getElementById("s-name").value = "";
            document.getElementById("s-phone").value = "";
            document.getElementById("s-address").value = "";
            openModal("modal-supplier");
        }

        function openEditSupplierModal(id) {
            const list = GLOBAL_DATA.all_suppliers || GLOBAL_DATA.debt_suppliers || [];
            const s = list.find(x => x.id === id);
            if (!s) return;
            document.getElementById("modal-supplier-title").innerText = "Sửa Nhà Cung Cấp: " + s.name;
            document.getElementById("s-id").value = s.id;
            document.getElementById("s-code").value = s.code;
            document.getElementById("s-name").value = s.name;
            document.getElementById("s-phone").value = s.phone || "";
            document.getElementById("s-address").value = s.address || "";
            openModal("modal-supplier");
        }

        function submitSupplier() {
            const name = document.getElementById("s-name").value.trim();
            if (!name) { alert("Vui lòng nhập tên NCC!"); return; }
            fetch(apiUrl("save-supplier"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    id: document.getElementById("s-id").value,
                    code: document.getElementById("s-code").value.trim(),
                    name: name,
                    phone: document.getElementById("s-phone").value.trim(),
                    address: document.getElementById("s-address").value.trim()
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-supplier");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function openPaySupplierModal(id, name, debt) {
            document.getElementById("pay-s-id").value = id;
            document.getElementById("pay-s-name").innerText = name;
            document.getElementById("pay-s-debt").innerText = formatMoney(debt);
            document.getElementById("pay-s-amount").value = debt;
            openModal("modal-pay-supplier");
        }

        function submitPaySupplierDebt() {
            const s_id = document.getElementById("pay-s-id").value;
            const amount = parseFloat(document.getElementById("pay-s-amount").value) || 0;
            if (amount <= 0) { alert("Vui lòng nhập số tiền!"); return; }
            fetch(apiUrl("pay-supplier-debt"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    supplier_id: s_id,
                    amount: amount,
                    account_id: document.getElementById("pay-s-account").value,
                    note: document.getElementById("pay-s-note").value.trim()
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-pay-supplier");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        // Invoice Detail & Pay
        function viewInvoiceDetails(id) {
            ACTIVE_INVOICE_ID = id;
            const inv = GLOBAL_DATA.recent_invoices.find(x => x.id === id);
            if (!inv) return;
            document.getElementById("inv-detail-title").innerText = "Chi Tiết Đơn Hàng: " + inv.code;
            document.getElementById("inv-detail-cust").innerText = (inv.customer_name || "Khách lẻ") + (inv.customer_phone ? ` (${inv.customer_phone})` : '');
            document.getElementById("inv-detail-time").innerText = inv.invoice_date;
            document.getElementById("inv-detail-total").innerText = formatMoney(inv.total_amount);
            document.getElementById("inv-detail-paid").innerText = formatMoney(inv.paid_amount);
            document.getElementById("inv-detail-debt").innerText = formatMoney(inv.remaining_debt);

            const isCancelled = inv.status === 'CANCELLED';
            document.getElementById("btn-cancel-invoice").style.display = isCancelled ? "none" : "inline-flex";

            const debtSec = document.getElementById("inv-pay-debt-section");
            if (inv.remaining_debt > 0 && !isCancelled) {
                debtSec.style.display = "block";
                document.getElementById("inv-pay-amount").value = inv.remaining_debt;
            } else {
                debtSec.style.display = "none";
            }

            fetch(apiUrl("invoice-items") + "&id=" + id, { headers: { "X-Sync-Token": CURRENT_SECRET } })
                .then(r => r.json()).then(res => {
                    const items = res.items || [];
                    document.getElementById("inv-detail-items").innerHTML = items.map(it => `
                        <tr>
                            <td class="font-bold">${it.product_name} <span class="font-mono">(${it.product_code})</span></td>
                            <td>${it.unit_name || 'Cái'}</td>
                            <td class="text-right">${formatQty(it.quantity)}</td>
                            <td class="text-right">${formatMoney(it.unit_price)}</td>
                            <td class="text-right font-bold">${formatMoney(it.line_total)}</td>
                        </tr>
                    `).join("");
                    openModal("modal-invoice-detail");
                });
        }

        function submitPayInvoiceDebt() {
            const amount = parseFloat(document.getElementById("inv-pay-amount").value) || 0;
            if (amount <= 0) { alert("Vui lòng nhập số tiền!"); return; }
            fetch(apiUrl("pay-invoice-debt"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    invoice_id: ACTIVE_INVOICE_ID,
                    amount: amount,
                    account_id: document.getElementById("inv-pay-account").value
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-invoice-detail");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function confirmCancelInvoice() {
            if (!confirm("Bạn có chắc chắn muốn HỦY đơn hàng này? Tồn kho của các mặt hàng sẽ được hoàn trả lại.")) return;
            fetch(apiUrl("cancel-invoice"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({ invoice_id: ACTIVE_INVOICE_ID })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-invoice-detail");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        function openPayPurchaseDebt(receiptId, code, debt) {
            const amountStr = prompt(`Nhập số tiền trả nợ cho phiếu nhập ${code} (Nợ hiện tại: ${formatMoney(debt)}):`, debt);
            if (!amountStr) return;
            const amount = parseFloat(amountStr);
            if (isNaN(amount) || amount <= 0) { alert("Số tiền không hợp lệ!"); return; }
            fetch(apiUrl("pay-purchase-debt"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({ receipt_id: receiptId, amount: amount, account_id: 1 })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') loadData(true);
                else alert("Lỗi: " + res.error);
            });
        }

        // Transactions Modal
        function openCreateTransactionModal(type) {
            document.getElementById("trans-type").value = type;
            document.getElementById("modal-trans-title").innerText = type === 'THU' ? "Tạo Phiếu Thu Tiền" : "Tạo Phiếu Chi Tiền";
            document.getElementById("btn-submit-trans").className = type === 'THU' ? "btn-header btn-success" : "btn-header btn-danger";
            document.getElementById("trans-cat").value = type === 'THU' ? "Thu bán hàng" : "Chi tiền hàng";
            document.getElementById("trans-amount").value = "";
            document.getElementById("trans-partner").value = "";
            document.getElementById("trans-note").value = "";
            openModal("modal-transaction");
        }

        function submitTransaction() {
            const amount = parseFloat(document.getElementById("trans-amount").value) || 0;
            const cat = document.getElementById("trans-cat").value.trim();
            if (amount <= 0 || !cat) { alert("Vui lòng nhập hạng mục và số tiền!"); return; }
            fetch(apiUrl("save-transaction"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    trans_type: document.getElementById("trans-type").value,
                    category: cat,
                    amount: amount,
                    account_id: document.getElementById("trans-account").value,
                    partner_name: document.getElementById("trans-partner").value.trim(),
                    note: document.getElementById("trans-note").value.trim()
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    closeModal("modal-transaction");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        // Attendance Modals
        function openEditAttendanceModal(id) {
            const item = GLOBAL_DATA.attendance_logs.find(x => x.id === id);
            if (!item) return;
            document.getElementById("modal-att-title").innerText = "Duyệt / Sửa Chấm Công";
            document.getElementById("att-id").value = item.id;
            document.getElementById("att-emp-select-group").style.display = "none";
            document.getElementById("att-emp-name-group").style.display = "block";
            document.getElementById("att-emp-name").innerText = `${item.employee_name} (${item.employee_code})`;
            document.getElementById("att-date").value = item.work_date;
            document.getElementById("att-status").value = item.status || "Đúng giờ (Đã duyệt)";
            document.getElementById("att-checkin").value = item.check_in_time ? item.check_in_time.slice(0, 8) : "";
            document.getElementById("att-checkout").value = item.check_out_time ? item.check_out_time.slice(0, 8) : "";
            document.getElementById("att-note").value = item.note || "";
            openModal("modal-attendance");
        }

        function openAddAttendanceModal() {
            document.getElementById("modal-att-title").innerText = "Bổ Sung Chấm Công";
            document.getElementById("att-id").value = "";
            document.getElementById("att-emp-select-group").style.display = "block";
            document.getElementById("att-emp-name-group").style.display = "none";
            const sel = document.getElementById("att-emp-select");
            sel.innerHTML = (GLOBAL_DATA.employees || []).map(e => `<option value="${e.code}|${e.full_name}">${e.full_name} (${e.code})</option>`).join("");
            document.getElementById("att-date").value = new Date().toISOString().split('T')[0];
            document.getElementById("att-status").value = "Đúng giờ (Đã duyệt)";
            document.getElementById("att-checkin").value = "08:00:00";
            document.getElementById("att-checkout").value = "17:00:00";
            document.getElementById("att-note").value = "Chủ bổ sung công qua Portal";
            openModal("modal-attendance");
        }

        function submitAttendance() {
            const attId = document.getElementById("att-id").value;
            if (attId) {
                fetch(apiUrl("update-attendance-log"), {
                    method: "POST",
                    headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                    body: JSON.stringify({
                        id: attId,
                        status: document.getElementById("att-status").value,
                        check_in_time: document.getElementById("att-checkin").value.trim(),
                        check_out_time: document.getElementById("att-checkout").value.trim(),
                        note: document.getElementById("att-note").value.trim()
                    })
                }).then(r => r.json()).then(res => {
                    if (res.status === 'ok') {
                        closeModal("modal-attendance");
                        loadData(true);
                    } else alert("Lỗi: " + res.error);
                });
            } else {
                const empVal = document.getElementById("att-emp-select").value.split("|");
                fetch(apiUrl("add-manual-attendance"), {
                    method: "POST",
                    headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                    body: JSON.stringify({
                        employee_code: empVal[0],
                        employee_name: empVal[1],
                        work_date: document.getElementById("att-date").value,
                        check_in_time: document.getElementById("att-checkin").value.trim(),
                        check_out_time: document.getElementById("att-checkout").value.trim(),
                        status: document.getElementById("att-status").value,
                        note: document.getElementById("att-note").value.trim()
                    })
                }).then(r => r.json()).then(res => {
                    if (res.status === 'ok') {
                        closeModal("modal-attendance");
                        loadData(true);
                    } else alert("Lỗi: " + res.error);
                });
            }
        }

        // Store info Modal
        function openStoreInfoModal() {
            document.getElementById("cfg-store-name").value = GLOBAL_DATA.store_name || "";
            document.getElementById("cfg-store-phone").value = GLOBAL_DATA.store_phone || "";
            document.getElementById("cfg-store-address").value = GLOBAL_DATA.store_address || "";
            document.getElementById("cfg-sync-secret").value = CURRENT_SECRET;
            openModal("modal-store-info");
        }

        function submitStoreInfo() {
            const name = document.getElementById("cfg-store-name").value.trim();
            const secret = document.getElementById("cfg-sync-secret").value.trim();
            if (!name) { alert("Vui lòng nhập tên cửa hàng!"); return; }
            fetch(apiUrl("update-store-info"), {
                method: "POST",
                headers: { "Content-Type": "application/json", "X-Sync-Token": CURRENT_SECRET },
                body: JSON.stringify({
                    store_name: name,
                    store_phone: document.getElementById("cfg-store-phone").value.trim(),
                    store_address: document.getElementById("cfg-store-address").value.trim(),
                    sync_secret: secret
                })
            }).then(r => r.json()).then(res => {
                if (res.status === 'ok') {
                    if (secret && secret !== CURRENT_SECRET) {
                        CURRENT_SECRET = secret;
                        localStorage.setItem("pos_sync_secret", secret);
                    }
                    closeModal("modal-store-info");
                    loadData(true);
                } else alert("Lỗi: " + res.error);
            });
        }

        // Filters
        function filterInvoices() {
            if(!GLOBAL_DATA) return;
            const q = document.getElementById("search-invoices").value.toLowerCase();
            const filtered = GLOBAL_DATA.recent_invoices.filter(i => i.code.toLowerCase().includes(q) || (i.customer_name && i.customer_name.toLowerCase().includes(q)));
            renderInvoicesTable("tbl-all-invoices", filtered);
        }

        function filterPurchases() {
            if(!GLOBAL_DATA || !GLOBAL_DATA.recent_purchases) return;
            const q = document.getElementById("search-purchases").value.toLowerCase();
            const filtered = GLOBAL_DATA.recent_purchases.filter(p => p.code.toLowerCase().includes(q) || (p.supplier_name && p.supplier_name.toLowerCase().includes(q)));
            renderPurchasesTable(filtered);
        }

        function filterProducts() {
            if(!GLOBAL_DATA || !GLOBAL_DATA.products) return;
            const q = document.getElementById("search-products").value.toLowerCase();
            const filtered = GLOBAL_DATA.products.filter(p => p.name.toLowerCase().includes(q) || p.code.toLowerCase().includes(q) || (p.barcode && p.barcode.toLowerCase().includes(q)));
            renderProductsTable(filtered);
        }

        function filterCustomers() {
            if(!GLOBAL_DATA) return;
            const q = document.getElementById("search-customers").value.toLowerCase();
            const list = GLOBAL_DATA.all_customers || GLOBAL_DATA.debt_customers || [];
            const filtered = list.filter(c => c.name.toLowerCase().includes(q) || c.code.toLowerCase().includes(q) || (c.phone && c.phone.includes(q)));
            renderCustomersTable(filtered);
        }

        function filterSuppliers() {
            if(!GLOBAL_DATA) return;
            const q = document.getElementById("search-suppliers").value.toLowerCase();
            const list = GLOBAL_DATA.all_suppliers || GLOBAL_DATA.debt_suppliers || [];
            const filtered = list.filter(s => s.name.toLowerCase().includes(q) || s.code.toLowerCase().includes(q) || (s.phone && s.phone.includes(q)));
            renderSuppliersTable(filtered);
        }

        function filterAttendance() {
            if (!GLOBAL_DATA || !GLOBAL_DATA.attendance_logs) return;
            const q = (document.getElementById("search-attendance").value || "").toLowerCase();
            const filtered = GLOBAL_DATA.attendance_logs.filter(a =>
                (a.employee_name && a.employee_name.toLowerCase().includes(q)) ||
                (a.employee_code && a.employee_code.toLowerCase().includes(q)) ||
                (a.work_date && a.work_date.toLowerCase().includes(q))
            );
            renderAttendanceTable(filtered);
        }

        if(CURRENT_SECRET) {
            document.getElementById("secret-input").value = CURRENT_SECRET;
            verifyLogin();
        }

        setInterval(() => {
            if(CURRENT_SECRET && document.getElementById("login-screen").style.display === "none") {
                loadData(false);
            }
        }, 5000);

        // Khóa tuyệt đối cử chỉ thu phóng (Pinch-to-zoom & Double-tap zoom) trên Mobile
        document.addEventListener('gesturestart', function(e) { e.preventDefault(); }, { passive: false });
        document.addEventListener('gesturechange', function(e) { e.preventDefault(); }, { passive: false });
        document.addEventListener('gestureend', function(e) { e.preventDefault(); }, { passive: false });

        let lastTouchEnd = 0;
        document.addEventListener('touchend', function(event) {
            const now = Date.now();
            if (now - lastTouchEnd <= 300) {
                event.preventDefault();
            }
            lastTouchEnd = now;
        }, { passive: false });

        document.addEventListener('touchmove', function(event) {
            if (event.scale !== undefined && event.scale !== 1) {
                event.preventDefault();
            }
        }, { passive: false });
    </script>
</body>
</html>
"""

HTML_ATTENDANCE = r"""<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no, viewport-fit=cover">
    <title>Chấm Công Nhân Viên - Cửa Hàng Đa Ngành</title>
    <style>
        :root { --primary: #2563eb; --primary-dark: #1d4ed8; --success: #15803d; --danger: #dc2626; --bg: #f8fafc; --card: #ffffff; --border: #cbd5e1; --text-dark: #0f172a; --text-muted: #64748b; }
        * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
        html, body { touch-action: manipulation; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
        input, select, textarea, button { font-size: 16px !important; }
        body { background: var(--bg); color: var(--text-dark); min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 16px 12px; }
        .container { width: 100%; max-width: 520px; }
        .card { background: var(--card); border-radius: 14px; border: 1px solid var(--border); box-shadow: 0 4px 12px rgba(15, 23, 42, 0.05); margin-bottom: 16px; overflow: hidden; }
        .card-header { padding: 14px 18px; border-bottom: 1px solid #e2e8f0; display: flex; justify-content: space-between; align-items: center; background: #fafafa; }
        .card-title { font-size: 15px; font-weight: 800; color: #1e3a8a; }
        .card-body { padding: 18px; }
        .brand-box { text-align: center; margin-bottom: 18px; padding: 10px 0; }
        .brand-title { font-size: 20px; font-weight: 800; color: #1e40af; text-transform: uppercase; }
        .brand-sub { font-size: 12.5px; color: var(--text-muted); font-weight: 600; margin-top: 4px; }
        .clock-card { background: linear-gradient(135deg, #1e3a8a, #2563eb); color: #fff; border-radius: 12px; padding: 14px 18px; text-align: center; margin-bottom: 16px; box-shadow: 0 4px 10px rgba(37, 99, 235, 0.2); }
        .clock-time { font-size: 32px; font-weight: 900; letter-spacing: 2px; font-family: 'Consolas', monospace; }
        .clock-date { font-size: 13px; font-weight: 600; opacity: 0.9; margin-top: 2px; }
        .alert { padding: 12px 14px; border-radius: 8px; font-size: 13px; font-weight: 600; margin-bottom: 14px; line-height: 1.4; }
        .alert-success { background: #dcfce7; color: #15803d; border: 1px solid #86efac; }
        .alert-danger { background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; }
        .alert-info { background: #e0f2fe; color: #0369a1; border: 1px solid #7dd3fc; }
        .wifi-badge { padding: 12px 14px; border-radius: 10px; font-size: 13px; font-weight: 700; margin-bottom: 16px; border: 1.5px solid; }
        .wifi-ok { background: #ecfdf5; color: #047857; border-color: #10b981; }
        .wifi-err { background: #fff1f2; color: #be123c; border-color: #f43f5e; }
        .form-group { margin-bottom: 14px; }
        .form-label { display: block; font-size: 13px; font-weight: 700; color: #334155; margin-bottom: 6px; }
        .form-control { width: 100%; padding: 12px 14px; border: 1.5px solid var(--border); border-radius: 8px; font-size: 14px; outline: none; }
        .form-control:focus { border-color: var(--primary); background: #f0f7ff; }
        .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; border: none; border-radius: 8px; font-weight: 800; font-size: 14px; padding: 12px 20px; cursor: pointer; width: 100%; text-decoration: none; }
        .btn-success { background: #15803d; color: #fff; }
        .btn-primary { background: #2563eb; color: #fff; }
        .btn-outline { background: #ffffff; color: #475569; border: 1px solid var(--border); }
        .btn-checkin { background: #15803d; font-size: 15px; padding: 15px; border-radius: 10px; }
        .btn-checkout { background: #0284c7; font-size: 15px; padding: 15px; border-radius: 10px; }
        .user-box { display: flex; justify-content: space-between; align-items: center; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 12px 14px; margin-bottom: 16px; }
        .user-avatar { width: 42px; height: 42px; border-radius: 50%; background: #2563eb; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; }
        .today-box { background: #fafafa; border: 1px dashed #cbd5e1; border-radius: 10px; padding: 12px 14px; margin-bottom: 16px; }
        .today-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; font-size: 13px; }
        .today-item-title { color: var(--text-muted); font-size: 11.5px; font-weight: 600; text-transform: uppercase; }
        .today-item-val { font-size: 15px; font-weight: 800; color: var(--text-dark); margin-top: 2px; }
        table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
        th { background: #f8fafc; color: #475569; font-weight: 700; padding: 9px 10px; border-bottom: 1px solid var(--border); text-align: left; }
        td { padding: 9px 10px; border-bottom: 1px solid #e2e8f0; }
        .text-center { text-align: center; }
    </style>
</head>
<body>
    <div class="container">
        <div class="brand-box">
            <div class="brand-title">Cửa Hàng Đa Ngành</div>
            <div class="brand-sub">HỆ THỐNG CHẤM CÔNG NHÂN VIÊN TRỰC TUYẾN</div>
        </div>

        <div class="clock-card">
            <div class="clock-time" id="live-clock">--:--:--</div>
            <div class="clock-date"><?= date('l, d/m/Y') ?></div>
        </div>

        <?php if ($msg_error): ?><div class="alert alert-danger"><svg style="width:16px;height:16px;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg><?= htmlspecialchars($msg_error) ?></div><?php endif; ?>
        <?php if ($msg_success): ?><div class="alert alert-success"><svg style="width:16px;height:16px;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="9 12 12 15 16 10"/></svg><?= htmlspecialchars($msg_success) ?></div><?php endif; ?>
        <?php if ($msg_info): ?><div class="alert alert-info"><svg style="width:16px;height:16px;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg><?= htmlspecialchars($msg_info) ?></div><?php endif; ?>

        <?php if (!$current_emp): ?>
            <div class="card">
                <div class="card-header"><span class="card-title" style="display:inline-flex; align-items:center; gap:8px;"><svg style="width:18px;height:18px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>ĐĂNG NHẬP CHẤM CÔNG</span></div>
                <div class="card-body">
                    <div class="wifi-badge <?= $is_wifi_ok ? 'wifi-ok' : 'wifi-err' ?>">
                        <?php if ($is_wifi_ok): ?>
                            <div><svg style="width:16px;height:16px;stroke:#15803d;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></svg><strong>Wi-Fi Cửa Hàng Hợp Lệ</strong> (IP: 127.0.0.1)</div>
                        <?php else: ?>
                            <div><svg style="width:16px;height:16px;stroke:#b91c1c;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="1" y1="1" x2="23" y2="23"/><path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"/><path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"/><path d="M10.71 5.05A16 16 0 0 1 22.58 9"/><path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></svg><strong>CẢNH BÁO: Chưa kết nối Wi-Fi Cửa Hàng</strong> (IP: 127.0.0.1)</div>
                        <?php endif; ?>
                    </div>
                    <form method="POST">
                        <input type="hidden" name="login_action" value="1">
                        <div class="form-group">
                            <label class="form-label">Tài khoản (Username):</label>
                            <input type="text" name="username" class="form-control" required autofocus>
                        </div>
                        <div class="form-group">
                            <label class="form-label">Mật khẩu:</label>
                            <input type="password" name="password" class="form-control" required>
                        </div>
                        <button type="submit" class="btn btn-primary">ĐĂNG NHẬP CHẤM CÔNG</button>
                    </form>
                    <div style="text-align: center; margin-top: 14px; font-size: 12px;">
                        <a href="index.php" style="color: #64748b; text-decoration: none; display:inline-flex; align-items:center; gap:6px;"><svg style="width:14px;height:14px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>Quản lý / Chủ cửa hàng đăng nhập tại đây &rarr;</a>
                    </div>
                </div>
            </div>
        <?php else: ?>
            <div class="user-box">
                <div style="display:flex; align-items:center; gap:10px;">
                    <div class="user-avatar"><?= mb_strtoupper(mb_substr($current_emp['name'], 0, 1, 'UTF-8'), 'UTF-8') ?></div>
                    <div>
                        <div style="font-weight: 800; font-size: 15px; color: #1e40af;"><?= htmlspecialchars($current_emp['name']) ?></div>
                        <div style="font-size: 12px; color: #64748b;">Mã: <?= htmlspecialchars($current_emp['code']) ?> • <?= htmlspecialchars($current_emp['position']) ?></div>
                    </div>
                </div>
                <a href="?page=cham-cong&action=logout" class="btn btn-outline" style="width: auto; padding: 6px 12px; font-size: 12px;">Đăng xuất</a>
            </div>

            <div class="wifi-badge <?= $is_wifi_ok ? 'wifi-ok' : 'wifi-err' ?>">
                <?php if ($is_wifi_ok): ?>
                    <div><svg style="width:16px;height:16px;stroke:#15803d;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></svg><strong>Wi-Fi Hợp Lệ:</strong> Đã khớp vị trí cửa hàng.</div>
                <?php else: ?>
                    <div><svg style="width:16px;height:16px;stroke:#b91c1c;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="1" y1="1" x2="23" y2="23"/><path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"/><path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"/><path d="M10.71 5.05A16 16 0 0 1 22.58 9"/><path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></svg><strong>Cảnh báo:</strong> Cần kết nối Wi-Fi cửa hàng để được xác nhận công!</div>
                <?php endif; ?>
            </div>

            <div class="card">
                <div class="card-header">
                    <span class="card-title" style="display:inline-flex; align-items:center; gap:8px;"><svg style="width:18px;height:18px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>XÁC NHẬN CÔNG HÔM NAY</span>
                    <span style="font-size: 12px; font-weight: 700; color: #15803d;">18/10/2026</span>
                </div>
                <div class="card-body">
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px;">
                        <form method="POST">
                            <input type="hidden" name="check_in_action" value="1">
                            <button type="submit" class="btn btn-success btn-checkin" <?= !$is_wifi_ok ? 'disabled style="opacity:0.6; cursor:not-allowed;"' : '' ?>>
                                <svg style="width:16px;height:16px;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>VÀO CA
                            </button>
                        </form>
                        <form method="POST">
                            <input type="hidden" name="check_out_action" value="1">
                            <button type="submit" class="btn btn-primary btn-checkout" <?= !$is_wifi_ok ? 'disabled style="opacity:0.6; cursor:not-allowed;"' : '' ?>>
                                <svg style="width:16px;height:16px;vertical-align:middle;margin-right:6px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/></svg>HẾT CA
                            </button>
                        </form>
                    </div>

                    <div class="today-box">
                        <div class="today-grid">
                            <div>
                                <div class="today-item-title">Giờ vào</div>
                                <div class="today-item-val" style="color: #15803d;"><?= (!empty($today_log['check_in_time'])) ? htmlspecialchars(substr($today_log['check_in_time'], 0, 8)) : '--:--:--' ?></div>
                            </div>
                            <div>
                                <div class="today-item-title">Giờ ra</div>
                                <div class="today-item-val" style="color: #0284c7;"><?= (!empty($today_log['check_out_time'])) ? htmlspecialchars(substr($today_log['check_out_time'], 0, 8)) : '--:--:--' ?></div>
                            </div>
                            <div style="margin-top: 6px;">
                                <div class="today-item-title">Tổng giờ</div>
                                <div class="today-item-val"><?= (floatval($today_log['total_hours'] ?? 0) > 0) ? floatval($today_log['total_hours']) . 'h' : '-' ?></div>
                            </div>
                            <div style="margin-top: 6px;">
                                <div class="today-item-title">Trạng thái</div>
                                <div class="today-item-val" style="color: #15803d; font-size: 13.5px;"><?= htmlspecialchars($today_log['status'] ?? 'Chưa chấm') ?></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card">
                <div class="card-header">
                    <span class="card-title" style="display:inline-flex; align-items:center; gap:8px;"><svg style="width:18px;height:18px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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"/></svg>CÔNG THÁNG <?= date('m/Y') ?></span>
                    <span style="font-size: 12px; font-weight: 700; color: #1e40af;"><?= count($month_logs) ?> ngày | <?= $total_month_hours ?>h</span>
                </div>
                <div style="overflow-x: auto;">
                    <table>
                        <thead>
                            <tr>
                                <th class="text-center">Ngày</th>
                                <th class="text-center">Vào</th>
                                <th class="text-center">Ra</th>
                                <th class="text-center">Tổng giờ</th>
                                <th class="text-center">Trạng thái</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php if (empty($month_logs)): ?>
                                <tr><td colspan="5" class="text-center" style="padding: 16px; color: #94a3b8;">Chưa có bản ghi nào.</td></tr>
                            <?php else: foreach ($month_logs as $ml): ?>
                                <tr>
                                    <td class="text-center font-mono"><strong><?= date('d/m', strtotime($ml['work_date'])) ?></strong></td>
                                    <td class="text-center" style="color: #15803d; font-weight: 700;"><?= htmlspecialchars(substr($ml['check_in_time'] ?? '--', 0, 8)) ?></td>
                                    <td class="text-center" style="color: #0284c7; font-weight: 700;"><?= htmlspecialchars(substr($ml['check_out_time'] ?? '--', 0, 8)) ?></td>
                                    <td class="text-center"><strong><?= floatval($ml['total_hours'] ?? 0) ?>h</strong></td>
                                    <td class="text-center" style="font-size: 11px; font-weight: 700; color: #15803d;"><?= htmlspecialchars($ml['status'] ?? 'Hợp lệ') ?></td>
                                </tr>
                            <?php endforeach; endif; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        <?php endif; ?>
    </div>
    <script>
        function updateClock() {
            const now = new Date();
            const el = document.getElementById('live-clock');
            if (el) el.textContent = String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') + ':' + String(now.getSeconds()).padStart(2, '0');
        }
        setInterval(updateClock, 1000);
        updateClock();
    </script>
</body>
</html>
<?php
}

$page = $_GET['page'] ?? '';
$req_uri = $_SERVER['REQUEST_URI'] ?? '';
if ($page === 'cham-cong' || strpos($req_uri, 'cham-cong') !== false) {
    render_employee_attendance_page();
    exit;
}

// -----------------------------------------------------------------------------

// =============================================================================

// =============================================================================

// =============================================================================

// =============================================================================

// =============================================================================
// WEB PORTAL QUAN LY CHO CHU CUA HANG - GIAO DIEN CHUAN THEME MOSMIND 2026
// =============================================================================
?>
"""

class CloudSyncHandler(BaseHTTPRequestHandler):
    server_version = "OfflinePOS-CloudSync/2.0"

    def check_auth(self) -> bool:
        token = self.headers.get("X-Sync-Token", "").strip()
        if not token:
            parsed = urlparse(self.path)
            qs = parse_qs(parsed.query)
            token = qs.get("token", [""])[0].strip()

        if not token:
            return False

        current = get_server_secret()
        if token == current:
            return True
        if current == DEFAULT_SECRET:
            set_server_secret(token)
            return True

        old_token = self.headers.get("X-Sync-Old-Token", "").strip()
        if not old_token:
            parsed = urlparse(self.path)
            qs = parse_qs(parsed.query)
            old_token = qs.get("old_token", [""])[0].strip()
        if old_token and old_token == current:
            set_server_secret(token)
            return True
        return False

    def get_real_client_ip(self) -> str:
        cf_ip = self.headers.get("CF-Connecting-IP", "").strip()
        if cf_ip: return cf_ip
        xf = self.headers.get("X-Forwarded-For", "").strip()
        if xf: return xf.split(",")[0].strip()
        return self.client_address[0]

    def send_json(self, status_code: int, data: dict):
        body = json.dumps(data, ensure_ascii=False).encode("utf-8")
        self.send_response(status_code)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "X-Sync-Token, X-Sync-Old-Token, Content-Type, Content-Encoding")
        self.end_headers()

    def do_GET(self):
        parsed = urlparse(self.path)
        path = parsed.path
        qs = parse_qs(parsed.query)
        api = qs.get("api", [""])[0].strip()
        page = qs.get("page", [""])[0].strip()

        if path == "/api/my-ip" or api == "my-ip":
            meta = get_meta()
            client_ip = self.get_real_client_ip()
            store_ips = meta.get("store_wifi_ips", "")
            self.send_json(200, {
                "status": "ok",
                "ip": client_ip,
                "store_wifi_ips": store_ips,
                "time": datetime.now().strftime("%H:%M:%S %d/%m/%Y")
            })
            return

        if path == "/api/ping" or api == "ping":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Sai mã bảo mật (Invalid Secret Token)"})
                return
            meta = get_meta()
            self.send_json(200, {
                "status": "ok",
                "message": "Máy chủ đồng bộ đang hoạt động 24/24",
                "server_name": meta.get("store_name", "Cloud POS Server"),
                "last_sync_time": meta.get("last_sync_time", "Chưa có")
            })
            return

        if path == "/api/get-attendance-logs" or api == "get-attendance-logs":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Sai mã bảo mật"})
                return
            logs = []
            if ATT_DB_FILE.exists():
                try:
                    c_att = get_sqlite_conn(ATT_DB_FILE)
                    c_att.row_factory = sqlite3.Row
                    cur = c_att.cursor()
                    cur.execute("SELECT * FROM attendance_logs ORDER BY work_date DESC, id DESC LIMIT 500")
                    logs = [dict(r) for r in cur.fetchall()]
                    c_att.close()
                except Exception:
                    pass
            if not logs:
                conn = get_db_connection()
                if conn:
                    try:
                        conn.row_factory = sqlite3.Row
                        ensure_hr_tables(conn)
                        cur = conn.cursor()
                        cur.execute("SELECT * FROM attendance_logs ORDER BY work_date DESC, id DESC LIMIT 500")
                        logs = [dict(r) for r in cur.fetchall()]
                    except Exception:
                        pass
                    finally:
                        conn.close()
            self.send_json(200, {"status": "ok", "logs": logs})
            return

        # PULL CLOUD EVENTS (Desktop App kéo các thay đổi từ Web về máy)
        if path == "/api/pull-cloud-events" or api == "pull-cloud-events":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            events_map = {ev["id"]: ev for ev in get_pending_events()}
            conn = get_db_connection()
            if conn:
                try:
                    conn.row_factory = sqlite3.Row
                    cur = conn.cursor()
                    cur.execute("SELECT * FROM cloud_sync_events WHERE is_synced_to_desktop = 0 ORDER BY id ASC")
                    for r in cur.fetchall():
                        ev_id = int(r["id"])
                        if ev_id not in events_map:
                            events_map[ev_id] = {
                                "id": ev_id,
                                "entity_type": r["entity_type"],
                                "action": r["action"],
                                "entity_id": r["entity_id"],
                                "payload": json.loads(r["payload"]) if isinstance(r["payload"], str) else r["payload"],
                                "created_at": r["created_at"]
                            }
                except Exception:
                    pass
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "events": list(events_map.values())})
            return

        if path == "/api/dashboard-data" or api == "dashboard-data":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Chưa đăng nhập hoặc sai mã bảo mật"})
                return
            conn = get_db_connection()
            if not conn:
                self.send_json(200, {"status": "ok", "meta": get_meta(), "data": {
                    "store_name": "CỬA HÀNG (Chờ đồng bộ lần đầu)",
                    "today": {"revenue": 0, "profit": 0, "invoices": 0, "cogs": 0, "paid": 0, "debt": 0},
                    "finance": {"cash": 0, "bank": 0, "customer_debt": 0, "supplier_debt": 0, "accounts": []},
                    "inventory": {"total_value": 0, "low_stock_count": 0},
                    "recent_invoices": [], "recent_purchases": [], "products": [], "debt_customers": [],
                    "all_customers": [], "debt_suppliers": [], "all_suppliers": [], "recent_transactions": [],
                    "attendance_logs": [], "categories": [], "units": [], "employees": [], "salary_advances": [], "payrolls": []
                }})
                return
            try:
                data = query_dashboard_data(conn)
                meta = get_meta()
                self.send_json(200, {"status": "ok", "meta": meta, "data": data})
            except Exception as e:
                self.send_json(500, {"status": "error", "error": f"Lỗi truy vấn dữ liệu: {str(e)}"})
            finally:
                conn.close()
            return

        if path == "/api/invoice-items" or api == "invoice-items":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            inv_id = int(qs.get("id", [0])[0])
            conn = get_db_connection()
            if not conn or not inv_id:
                self.send_json(200, {"status": "ok", "items": []})
                return
            try:
                items = get_invoice_items(conn, inv_id)
                self.send_json(200, {"status": "ok", "items": items})
            finally:
                conn.close()
            return

        if path == "/api/purchase-items" or api == "purchase-items":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            rec_id = int(qs.get("id", [0])[0])
            conn = get_db_connection()
            if not conn or not rec_id:
                self.send_json(200, {"status": "ok", "items": []})
                return
            try:
                items = get_purchase_items(conn, rec_id)
                self.send_json(200, {"status": "ok", "items": items})
            finally:
                conn.close()
            return

        if path == "/api/download-db" or api == "download-db":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            if not DB_FILE.exists():
                self.send_json(404, {"status": "error", "error": "Chưa có file dữ liệu trên máy chủ"})
                return
            with open(DB_FILE, "rb") as f:
                content = f.read()
            self.send_response(200)
            self.send_header("Content-Type", "application/x-sqlite3")
            self.send_header("Content-Disposition", f'attachment; filename="backup_pos_{datetime.now().strftime("%Y%m%d_%H%M%S")}.db"')
            self.send_header("Content-Length", str(len(content)))
            self.end_headers()
            self.wfile.write(content)
            return

        if path == "/cham-cong" or page == "cham-cong":
            body = HTML_ATTENDANCE.encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return

        if path == "/" or path == "/index.html":
            body = HTML_PORTAL.encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return

        self.send_json(404, {"status": "error", "error": "Not Found"})

    def do_POST(self):
        parsed = urlparse(self.path)
        path = parsed.path
        qs = parse_qs(parsed.query)
        api = qs.get("api", [""])[0].strip()

        content_len = int(self.headers.get("Content-Length", 0))
        raw_body = self.rfile.read(content_len) if content_len > 0 else b""

        # ACK CLOUD EVENTS (Desktop báo nhận và áp dụng event xong)
        if path == "/api/ack-cloud-events" or api == "ack-cloud-events":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            ids = data.get("event_ids", [])
            if not isinstance(ids, list): ids = [ids]
            id_set = set(ids)

            curr = get_pending_events()
            rem = [e for e in curr if e.get("id") not in id_set]
            save_pending_events(rem)

            conn = get_db_connection()
            if conn and ids:
                try:
                    cur = conn.cursor()
                    q = f"UPDATE cloud_sync_events SET is_synced_to_desktop = 1 WHERE id IN ({','.join(['?']*len(ids))})"
                    cur.execute(q, ids)
                    conn.commit()
                except Exception:
                    pass
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "acknowledged": len(ids)})
            return

        # UPDATE STORE IP
        if path == "/api/update-store-ip" or api == "update-store-ip":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Sai mã bảo mật"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            store_ips = str(data.get("store_wifi_ips", "")).strip()
            meta = get_meta()
            meta["store_wifi_ips"] = store_ips
            meta["store_ip_updated_at"] = datetime.now().strftime("%H:%M:%S %d/%m/%Y")
            save_meta(meta)
            self.send_json(200, {"status": "ok", "message": "Đã cập nhật IP Wi-Fi cửa hàng!", "store_wifi_ips": store_ips})
            return

        # UPDATE STORE INFO
        if path == "/api/update-store-info" or api == "update-store-info":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            meta = get_meta()
            if data.get("store_name"): meta["store_name"] = str(data["store_name"]).strip()
            if data.get("sync_secret"): meta["sync_secret"] = str(data["sync_secret"]).strip()
            save_meta(meta)
            conn = get_db_connection()
            if conn:
                try:
                    cur = conn.cursor()
                    if data.get("store_name"): cur.execute("INSERT OR REPLACE INTO app_settings (key, value) VALUES ('store_name', ?)", (meta["store_name"],))
                    if data.get("store_phone"): cur.execute("INSERT OR REPLACE INTO app_settings (key, value) VALUES ('store_phone', ?)", (str(data["store_phone"]).strip(),))
                    if data.get("store_address"): cur.execute("INSERT OR REPLACE INTO app_settings (key, value) VALUES ('store_address', ?)", (str(data["store_address"]).strip(),))
                    conn.commit()
                except Exception:
                    pass
                finally:
                    conn.close()
            record_cloud_event("store_settings", "update", "info", data)
            self.send_json(200, {"status": "ok", "message": "Đã cập nhật thông tin cửa hàng thành công!"})
            return

        # SYNC EMPLOYEES
        if path == "/api/sync-employees" or api == "sync-employees":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Sai mã bảo mật"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            employees = data.get("employees", [])
            conn = get_db_connection()
            count = 0
            if conn and employees:
                try:
                    ensure_hr_tables(conn)
                    cur = conn.cursor()
                    for emp in employees:
                        cur.execute("""
                            INSERT INTO employees (id, code, full_name, phone, position, username, password_hash, password_plain, base_salary, hourly_rate, is_active, updated_at)
                            VALUES (:id, :code, :full_name, :phone, :position, :username, :password_hash, :password_plain, :base_salary, :hourly_rate, :is_active, CURRENT_TIMESTAMP)
                            ON CONFLICT(code) DO UPDATE SET
                                full_name = excluded.full_name, phone = excluded.phone, position = excluded.position,
                                username = excluded.username, password_hash = excluded.password_hash,
                                password_plain = excluded.password_plain, base_salary = excluded.base_salary,
                                hourly_rate = excluded.hourly_rate, is_active = excluded.is_active, updated_at = CURRENT_TIMESTAMP
                        """, {
                            "id": emp.get("id"), "code": emp.get("code"), "full_name": emp.get("full_name"),
                            "phone": emp.get("phone"), "position": emp.get("position", ""), "username": emp.get("username"),
                            "password_hash": emp.get("password_hash", ""), "password_plain": emp.get("password_plain", ""),
                            "base_salary": emp.get("base_salary", 0.0), "hourly_rate": emp.get("hourly_rate", 0.0),
                            "is_active": emp.get("is_active", 1)
                        })
                        count += 1
                    conn.commit()
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "count": count, "message": f"Đã đồng bộ {count} nhân viên"})
            return

        # SYNC DB SNAPSHOT
        if path == "/api/sync" or api == "sync":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Sai mã bảo mật (Sync Secret Key)"})
                return
            content_encoding = self.headers.get("Content-Encoding", "").lower()
            if "gzip" in content_encoding or (len(raw_body) > 2 and raw_body[:2] == bytes([0x1f, 0x8b])):
                try: raw_db = gzip.decompress(raw_body)
                except Exception: raw_db = raw_body
            else: raw_db = raw_body

            if len(raw_db) < 16 or not raw_db.startswith(b"SQLite format 3\0"):
                self.send_json(400, {"status": "error", "error": "Dữ liệu không đúng định dạng SQLite chuẩn"})
                return

            tmp_file = BASE_DIR / "cloud_pos.db.tmp"
            with open(tmp_file, "wb") as f:
                f.write(raw_db)

            # Bảo toàn dữ liệu chấm công và events chưa sync
            if DB_FILE.exists():
                try:
                    old_conn = get_sqlite_conn(DB_FILE)
                    new_conn = get_sqlite_conn(tmp_file)
                    ensure_hr_tables(new_conn)
                    old_conn.row_factory = sqlite3.Row
                    old_cur = old_conn.cursor()
                    old_cur.execute("SELECT * FROM attendance_logs")
                    for ol in old_cur.fetchall():
                        d = dict(ol)
                        new_conn.execute("""
                            INSERT INTO attendance_logs (employee_id, employee_code, employee_name, work_date, check_in_time, check_out_time, total_hours, ip_address, status, note, synced, created_at)
                            SELECT :employee_id, :employee_code, :employee_name, :work_date, :check_in_time, :check_out_time, :total_hours, :ip_address, :status, :note, :synced, :created_at
                            WHERE NOT EXISTS (SELECT 1 FROM attendance_logs WHERE UPPER(employee_code) = UPPER(:employee_code2) AND work_date = :work_date2 AND check_in_time = :check_in_time2)
                        """, {**d, "employee_code2": d.get("employee_code"), "work_date2": d.get("work_date"), "check_in_time2": d.get("check_in_time")})
                    
                    old_cur.execute("SELECT * FROM cloud_sync_events WHERE is_synced_to_desktop = 0")
                    for ev in old_cur.fetchall():
                        d_ev = dict(ev)
                        new_conn.execute("INSERT INTO cloud_sync_events (entity_type, action, entity_id, payload, is_synced_to_desktop, created_at) VALUES (?, ?, ?, ?, 0, ?)",
                                         (d_ev["entity_type"], d_ev["action"], d_ev["entity_id"], d_ev["payload"], d_ev["created_at"]))
                    new_conn.commit()
                    old_conn.close()
                    new_conn.close()
                except Exception as e:
                    print(f"Error preserving sync data: {e}")

            if sys.platform == "win32" and DB_FILE.exists():
                try: os.replace(str(tmp_file), str(DB_FILE))
                except Exception:
                    import shutil
                    shutil.copyfile(str(tmp_file), str(DB_FILE))
                    try: os.remove(str(tmp_file))
                    except Exception: pass
            else: os.replace(str(tmp_file), str(DB_FILE))

            meta = get_meta()
            meta["last_sync_time"] = datetime.now().strftime("%H:%M:%S %d/%m/%Y")
            meta["sync_count"] = meta.get("sync_count", 0) + 1
            save_meta(meta)
            self.send_json(200, {"status": "ok", "message": "Đã đồng bộ thành công lên máy chủ 24/24", "timestamp": meta["last_sync_time"], "bytes_received": len(raw_db)})
            return

        # POS CHECKOUT
        if path == "/api/pos-checkout" or api == "pos-checkout":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            items = data.get("items", [])
            if not items:
                self.send_json(400, {"status": "error", "error": "Giỏ hàng rỗng"})
                return
            conn = get_db_connection()
            if not conn:
                self.send_json(500, {"status": "error", "error": "Chưa có CSDL trên máy chủ"})
                return
            try:
                cur = conn.cursor()
                c_id = data.get("customer_id")
                subtotal = float(data.get("subtotal", 0))
                discount = float(data.get("discount_amount", 0))
                total_amt = float(data.get("total_amount", max(0, subtotal - discount)))
                pay_method = data.get("payment_method", "TIEN_MAT")
                paid_amt = float(data.get("paid_amount", total_amt))
                rem_debt = float(data.get("remaining_debt", max(0, total_amt - paid_amt)))
                note = data.get("note", "Bán hàng qua Web POS")
                inv_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                code = f"HD{datetime.now().strftime('%y%m%d')}{int(time.time()%10000):04d}"

                total_cost = 0.0
                for it in items:
                    cur.execute("SELECT cost_price FROM products WHERE id = ?", (it.get("product_id"),))
                    cp_row = cur.fetchone()
                    total_cost += float(it.get("quantity", 1)) * (float(cp_row[0]) if cp_row and cp_row[0] else 0.0)

                cur.execute("""
                    INSERT INTO sales_invoices (code, invoice_date, user_id, customer_id, warehouse_id, subtotal, discount_amount, shipping_fee, tax_amount, total_amount, previous_debt, total_payment_required, paid_amount, remaining_debt, total_cost, status, payment_method, note, created_at)
                    VALUES (?, ?, 1, ?, 1, ?, ?, 0.0, 0.0, ?, 0.0, ?, ?, ?, ?, 'COMPLETED', ?, ?, ?)
                """, (code, inv_date, c_id, subtotal, discount, total_amt, total_amt, paid_amt, rem_debt, total_cost, pay_method, note, inv_date))
                inv_id = cur.lastrowid

                for it in items:
                    p_id = it.get("product_id")
                    qty = float(it.get("quantity", 1))
                    price = float(it.get("unit_price", 0))
                    lt = float(it.get("line_total", qty * price))
                    u_name = str(it.get("unit_name", "Cái"))
                    cur.execute("SELECT id FROM units WHERE UPPER(name) = UPPER(?) LIMIT 1", (u_name,))
                    u_row = cur.fetchone()
                    u_id = u_row[0] if u_row else 1
                    cur.execute("""
                        INSERT INTO sales_invoice_items (invoice_id, product_id, unit_id, unit_name, conversion_rate, quantity, quantity_base, unit_price, discount_percent, discount_amount, line_total, unit_cost, line_cost, note)
                        VALUES (?, ?, ?, ?, 1.0, ?, ?, ?, 0.0, 0.0, ?, 0.0, 0.0, ?)
                    """, (inv_id, p_id, u_id, u_name, qty, qty, price, lt, it.get("note", "")))
                    cur.execute("UPDATE stock_balances SET quantity = quantity - ? WHERE product_id = ? AND warehouse_id = 1", (qty, p_id))

                if rem_debt > 0 and c_id:
                    cur.execute("UPDATE customers SET current_debt = current_debt + ? WHERE id = ?", (rem_debt, c_id))

                if paid_amt > 0:
                    t_code = f"PT_{code}"
                    acc_id = 2 if pay_method == "CHUYEN_KHOAN" else 1
                    cur.execute("""
                        INSERT INTO cash_transactions (code, trans_type, account_id, amount, partner_type, partner_id, category, document_type, document_id, document_code, note)
                        VALUES (?, 'THU', ?, ?, 'CUSTOMER', ?, 'Thu tiền bán hàng', 'INVOICE', ?, ?, ?)
                    """, (t_code, acc_id, paid_amt, c_id, inv_id, code, f"Thu tiền đơn bán hàng {code} qua Web POS"))
                    cur.execute("UPDATE cash_accounts SET current_balance = current_balance + ? WHERE id = ?", (paid_amt, acc_id))

                conn.commit()

                payload = {
                    "id": inv_id, "code": code, "invoice_date": inv_date, "customer_id": c_id,
                    "subtotal": subtotal, "discount_amount": discount, "total_amount": total_amt,
                    "paid_amount": paid_amt, "remaining_debt": rem_debt, "total_cost": total_cost,
                    "payment_method": pay_method, "note": note, "items": items
                }
                record_cloud_event("invoice_create", "create", code, payload)
                self.send_json(200, {"status": "ok", "message": "Thanh toán thành công!", "invoice": payload})
            except Exception as e:
                self.send_json(500, {"status": "error", "error": str(e)})
            finally:
                conn.close()
            return

        # CREATE PURCHASE
        if path == "/api/create-purchase" or api == "create-purchase":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            items = data.get("items", [])
            conn = get_db_connection()
            if not conn:
                self.send_json(500, {"status": "error", "error": "Chưa có CSDL"})
                return
            try:
                cur = conn.cursor()
                s_id = data.get("supplier_id")
                subtotal = float(data.get("subtotal", 0))
                discount = float(data.get("discount_amount", 0))
                total_amt = float(data.get("total_amount", max(0, subtotal - discount)))
                pay_method = data.get("payment_method", "TIEN_MAT")
                paid_amt = float(data.get("paid_amount", total_amt))
                rem_debt = float(data.get("remaining_debt", max(0, total_amt - paid_amt)))
                note = data.get("note", "Nhập hàng từ Web Portal")
                rec_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                code = f"PN{datetime.now().strftime('%y%m%d')}{int(time.time()%10000):04d}"

                cur.execute("""
                    INSERT INTO purchase_receipts (code, receipt_date, user_id, supplier_id, warehouse_id, subtotal, discount_amount, shipping_fee, tax_amount, total_amount, previous_debt, paid_amount, remaining_debt, payment_method, status, note, created_at)
                    VALUES (?, ?, 1, ?, 1, ?, ?, 0.0, 0.0, ?, 0.0, ?, ?, ?, 'COMPLETED', ?, ?)
                """, (code, rec_date, s_id, subtotal, discount, total_amt, paid_amt, rem_debt, pay_method, note, rec_date))
                rec_id = cur.lastrowid

                for it in items:
                    p_id = it.get("product_id")
                    qty = float(it.get("quantity", 1))
                    cost = float(it.get("unit_cost", 0))
                    lt = float(it.get("line_total", qty * cost))
                    u_name = str(it.get("unit_name", "Cái"))
                    cur.execute("SELECT id FROM units WHERE UPPER(name) = UPPER(?) LIMIT 1", (u_name,))
                    u_row = cur.fetchone()
                    u_id = u_row[0] if u_row else 1
                    cur.execute("""
                        INSERT INTO purchase_receipt_items (receipt_id, product_id, unit_id, unit_name, conversion_rate, quantity, quantity_base, unit_cost, discount_amount, allocated_fee, line_total, note)
                        VALUES (?, ?, ?, ?, 1.0, ?, ?, ?, 0.0, 0.0, ?, ?)
                    """, (rec_id, p_id, u_id, u_name, qty, qty, cost, lt, it.get("note", "")))
                    cur.execute("""
                        INSERT INTO stock_balances (warehouse_id, product_id, quantity, cost_price)
                        VALUES (1, ?, ?, ?)
                        ON CONFLICT(warehouse_id, product_id) DO UPDATE SET quantity = quantity + excluded.quantity, cost_price = excluded.cost_price
                    """, (p_id, qty, cost))
                    cur.execute("UPDATE products SET cost_price = ? WHERE id = ?", (cost, p_id))

                if rem_debt > 0 and s_id:
                    cur.execute("UPDATE suppliers SET current_debt = current_debt + ? WHERE id = ?", (rem_debt, s_id))

                if paid_amt > 0:
                    t_code = f"PC_{code}"
                    acc_id = 2 if pay_method == "CHUYEN_KHOAN" else 1
                    cur.execute("""
                        INSERT INTO cash_transactions (code, trans_type, account_id, amount, partner_type, partner_id, category, document_type, document_id, document_code, note)
                        VALUES (?, 'CHI', ?, ?, 'SUPPLIER', ?, 'Trả tiền mua hàng', 'PURCHASE', ?, ?, ?)
                    """, (t_code, acc_id, paid_amt, s_id, rec_id, code, f"Thanh toán phiếu nhập {code} qua Web"))
                    cur.execute("UPDATE cash_accounts SET current_balance = current_balance - ? WHERE id = ?", (paid_amt, acc_id))

                conn.commit()

                payload = {
                    "id": rec_id, "code": code, "receipt_date": rec_date, "supplier_id": s_id,
                    "subtotal": subtotal, "discount_amount": discount, "total_amount": total_amt,
                    "paid_amount": paid_amt, "remaining_debt": rem_debt, "payment_method": pay_method,
                    "note": note, "items": items
                }
                record_cloud_event("purchase_create", "create", code, payload)
                self.send_json(200, {"status": "ok", "message": "Lập phiếu nhập thành công!", "receipt": payload})
            except Exception as e:
                self.send_json(500, {"status": "error", "error": str(e)})
            finally:
                conn.close()
            return

        # SAVE EMPLOYEE
        if path == "/api/save-employee" or api == "save-employee":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            name = (data.get("full_name") or "").strip()
            if not name:
                self.send_json(400, {"status": "error", "error": "Họ và tên không được để trống"})
                return
            conn = get_db_connection()
            if not conn:
                self.send_json(500, {"status": "error", "error": "Chưa có CSDL"})
                return
            try:
                ensure_hr_tables(conn)
                cur = conn.cursor()
                emp_id = int(data.get("id") or 0)
                code = (data.get("code") or "").strip().upper()
                phone = (data.get("phone") or "").strip()
                pos = (data.get("position") or "Nhân viên bán hàng").strip()
                username = (data.get("username") or "").strip().lower()
                pwd = data.get("password_plain", "123456")
                b_sal = float(data.get("base_salary") or 0)
                h_rate = float(data.get("hourly_rate") or 0)
                ins = float(data.get("insurance_amount") or (round(b_sal * 0.105) if b_sal > 0 else 0))
                allow = float(data.get("allowance_amount") or 0)
                al_det = (data.get("allowance_details") or "").strip()
                ot_m = float(data.get("ot_multiplier") or 1.5)
                is_act = int(data.get("is_active", 1))

                if emp_id > 0:
                    cur.execute("""
                        UPDATE employees SET full_name = ?, phone = ?, position = ?, username = ?, password_plain = ?,
                                            base_salary = ?, hourly_rate = ?, insurance_amount = ?, allowance_amount = ?,
                                            allowance_details = ?, ot_multiplier = ?, is_active = ?, updated_at = CURRENT_TIMESTAMP
                        WHERE id = ?
                    """, (name, phone, pos, username, pwd, b_sal, h_rate, ins, allow, al_det, ot_m, is_act, emp_id))
                    action = "save"
                else:
                    if not code:
                        cur.execute("SELECT COALESCE(MAX(id), 0) + 1 FROM employees")
                        code = f"NV{cur.fetchone()[0]:04d}"
                    if not username: username = code.lower()
                    cur.execute("""
                        INSERT INTO employees (code, full_name, phone, position, username, password_plain, password_hash,
                                               base_salary, hourly_rate, insurance_amount, allowance_amount, allowance_details,
                                               ot_multiplier, is_active)
                        VALUES (?, ?, ?, ?, ?, ?, '', ?, ?, ?, ?, ?, ?, ?)
                    """, (code, name, phone, pos, username, pwd, b_sal, h_rate, ins, allow, al_det, ot_m, is_act))
                    emp_id = cur.lastrowid
                    action = "save"

                conn.commit()
                payload = {
                    "id": emp_id, "code": code, "full_name": name, "phone": phone, "position": pos,
                    "username": username, "password_plain": pwd, "base_salary": b_sal, "hourly_rate": h_rate,
                    "insurance_amount": ins, "allowance_amount": allow, "allowance_details": al_det,
                    "ot_multiplier": ot_m, "is_active": is_act
                }
                record_cloud_event("employee_save", action, code, payload)
                self.send_json(200, {"status": "ok", "message": "Lưu nhân viên thành công!", "employee": payload})
            except Exception as e:
                self.send_json(500, {"status": "error", "error": str(e)})
            finally:
                conn.close()
            return

        # DELETE EMPLOYEE
        if path == "/api/delete-employee" or api == "delete-employee":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            emp_id = int(data.get("id") or 0)
            code = (data.get("code") or "").strip()
            conn = get_db_connection()
            if conn:
                try:
                    cur = conn.cursor()
                    cur.execute("UPDATE employees SET is_active = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ? OR UPPER(code) = UPPER(?)", (emp_id, code))
                    conn.commit()
                    record_cloud_event("employee_save", "delete", code, {"id": emp_id, "code": code, "is_active": 0})
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": "Đã ngừng kích hoạt nhân viên!"})
            return

        # SAVE ADVANCE
        if path == "/api/save-advance" or api == "save-advance":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            code = (data.get("employee_code") or "").strip().upper()
            amt = float(data.get("amount") or 0)
            adv_date = data.get("advance_date") or datetime.now().strftime("%Y-%m-%d")
            my = data.get("month_year") or adv_date[:7]
            reason = data.get("reason", "Tạm ứng lương")
            if amt <= 0 or not code:
                self.send_json(400, {"status": "error", "error": "Dữ liệu tạm ứng không hợp lệ"})
                return
            conn = get_db_connection()
            if conn:
                try:
                    ensure_hr_tables(conn)
                    cur = conn.cursor()
                    cur.execute("INSERT INTO hr_salary_advances (month_year, employee_code, advance_date, amount, reason) VALUES (?, ?, ?, ?, ?)", (my, code, adv_date, amt, reason))
                    t_code = f"PC_UNG_{datetime.now().strftime('%y%m%d')}{int(time.time()%1000):03d}"
                    cur.execute("INSERT INTO cash_transactions (code, trans_type, account_id, amount, partner_name, category, note) VALUES (?, 'CHI', 1, ?, ?, 'Tạm ứng lương', ?)", (t_code, amt, code, f"Tạm ứng lương tháng {my} cho {code}: {reason}"))
                    cur.execute("UPDATE cash_accounts SET current_balance = current_balance - ? WHERE id = 1", (amt,))
                    conn.commit()
                    payload = {"employee_code": code, "month_year": my, "advance_date": adv_date, "amount": amt, "reason": reason}
                    record_cloud_event("salary_advance", "save", code, payload)
                    self.send_json(200, {"status": "ok", "message": "Lập phiếu tạm ứng thành công!", "advance": payload})
                finally:
                    conn.close()
            return

        # SAVE PAYROLL STATUS
        if path == "/api/save-payroll-status" or api == "save-payroll-status":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            code = (data.get("employee_code") or "").strip().upper()
            my = data.get("month_year") or datetime.now().strftime("%Y-%m")
            status = data.get("status", "Đã thanh toán")
            conn = get_db_connection()
            if conn:
                try:
                    ensure_hr_tables(conn)
                    cur = conn.cursor()
                    cur.execute("UPDATE hr_payrolls SET payment_status = ?, updated_at = CURRENT_TIMESTAMP WHERE UPPER(employee_code) = UPPER(?) AND month_year = ?", (status, code, my))
                    conn.commit()
                    record_cloud_event("payroll_paid", "save", code, {"employee_code": code, "month_year": my, "status": status})
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": "Cập nhật thanh toán lương thành công!"})
            return

        # SAVE PRODUCT
        if path == "/api/save-product" or api == "save-product":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            name = (data.get("name") or "").strip()
            if not name:
                self.send_json(400, {"status": "error", "error": "Tên hàng hóa không được để trống"})
                return
            conn = get_db_connection()
            if not conn:
                self.send_json(500, {"status": "error", "error": "Chưa có CSDL"})
                return
            try:
                cur = conn.cursor()
                p_id = int(data.get("id") or 0)
                code = (data.get("code") or "").strip()
                barcode = (data.get("barcode") or "").strip()
                retail = float(data.get("retail_price") or 0)
                cost = float(data.get("cost_price") or 0)
                stock_qty = float(data.get("stock_qty") or 0)
                min_stock = float(data.get("min_stock") or 0)
                unit_name = (data.get("unit_name") or "Cái").strip()

                cur.execute("SELECT id FROM units WHERE UPPER(name) = UPPER(?) LIMIT 1", (unit_name,))
                u_row = cur.fetchone()
                if u_row: u_id = u_row[0]
                else:
                    cur.execute("INSERT INTO units (name) VALUES (?)", (unit_name,))
                    u_id = cur.lastrowid

                if p_id > 0:
                    cur.execute("""
                        UPDATE products SET name = ?, barcode = ?, cost_price = ?, retail_price = ?, wholesale_price = ?,
                                            min_stock = ?, base_unit_id = ?, is_active = 1, updated_at = CURRENT_TIMESTAMP
                        WHERE id = ?
                    """, (name, barcode, cost, retail, retail, min_stock, u_id, p_id))
                    cur.execute("INSERT OR REPLACE INTO stock_balances (warehouse_id, product_id, quantity, cost_price) VALUES (1, ?, ?, ?)", (p_id, stock_qty, cost))
                    action = "save"
                else:
                    if not code:
                        cur.execute("SELECT COALESCE(MAX(id), 0) + 1 FROM products")
                        code = f"HH{cur.fetchone()[0]:04d}"
                    cur.execute("""
                        INSERT INTO products (code, barcode, name, base_unit_id, cost_price, retail_price, wholesale_price, min_stock, is_active)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)
                    """, (code, barcode, name, u_id, cost, retail, retail, min_stock))
                    p_id = cur.lastrowid
                    cur.execute("INSERT OR REPLACE INTO stock_balances (warehouse_id, product_id, quantity, cost_price) VALUES (1, ?, ?, ?)", (p_id, stock_qty, cost))
                    action = "save"
                conn.commit()
                payload = {"id": p_id, "code": code, "name": name, "barcode": barcode, "cost_price": cost, "retail_price": retail, "stock_qty": stock_qty, "min_stock": min_stock, "unit_name": unit_name}
                record_cloud_event("product", action, code, payload)
                self.send_json(200, {"status": "ok", "message": "Lưu hàng hóa thành công!", "product": payload})
            finally:
                conn.close()
            return

        # DELETE PRODUCT
        if path == "/api/delete-product" or api == "delete-product":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            p_id = int(data.get("id") or 0)
            code = (data.get("code") or "").strip()
            conn = get_db_connection()
            if conn:
                try:
                    cur = conn.cursor()
                    cur.execute("UPDATE products SET is_active = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ? OR code = ?", (p_id, code))
                    conn.commit()
                    record_cloud_event("product", "delete", code or str(p_id), {"id": p_id, "code": code})
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": "Đã ngừng kinh doanh sản phẩm!"})
            return

        # SAVE CUSTOMER
        if path == "/api/save-customer" or api == "save-customer":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            name = (data.get("name") or "").strip()
            conn = get_db_connection()
            if not conn:
                self.send_json(500, {"status": "error", "error": "Chưa có CSDL"})
                return
            try:
                cur = conn.cursor()
                c_id = int(data.get("id") or 0)
                code = (data.get("code") or "").strip()
                phone = (data.get("phone") or "").strip()
                addr = (data.get("address") or "").strip()
                init_debt = float(data.get("initial_debt") or 0)
                if c_id > 0:
                    cur.execute("UPDATE customers SET name = ?, phone = ?, address = ?, is_active = 1 WHERE id = ?", (name, phone, addr, c_id))
                else:
                    if not code:
                        cur.execute("SELECT COALESCE(MAX(id), 0) + 1 FROM customers")
                        code = f"KH{cur.fetchone()[0]:04d}"
                    cur.execute("INSERT INTO customers (code, name, phone, address, initial_debt, current_debt, is_active) VALUES (?, ?, ?, ?, ?, ?, 1)", (code, name, phone, addr, init_debt, init_debt))
                    c_id = cur.lastrowid
                conn.commit()
                payload = {"id": c_id, "code": code, "name": name, "phone": phone, "address": addr, "initial_debt": init_debt}
                record_cloud_event("customer", "save", code, payload)
                self.send_json(200, {"status": "ok", "message": "Lưu khách hàng thành công!", "customer": payload})
            finally:
                conn.close()
            return

        # PAY CUSTOMER DEBT
        if path == "/api/pay-customer-debt" or api == "pay-customer-debt":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            c_id = int(data.get("customer_id") or 0)
            amount = float(data.get("amount") or 0)
            acc_id = int(data.get("account_id") or 1)
            note = data.get("note", "Thu nợ khách hàng")
            conn = get_db_connection()
            if conn:
                try:
                    cur = conn.cursor()
                    cur.execute("SELECT name, code FROM customers WHERE id = ?", (c_id,))
                    row = cur.fetchone()
                    if row:
                        cust_name, cust_code = row[0], row[1]
                        cur.execute("UPDATE customers SET current_debt = MAX(0, current_debt - ?) WHERE id = ?", (amount, c_id))
                        t_code = f"PT{datetime.now().strftime('%y%m%d')}{int(time.time()%1000):03d}"
                        cur.execute("INSERT INTO cash_transactions (code, trans_type, account_id, amount, partner_type, partner_id, partner_name, category, note) VALUES (?, 'THU', ?, ?, 'CUSTOMER', ?, ?, 'Thu nợ khách hàng', ?)", (t_code, acc_id, amount, c_id, cust_name, note))
                        cur.execute("UPDATE cash_accounts SET current_balance = current_balance + ? WHERE id = ?", (amount, acc_id))
                        conn.commit()
                        payload = {"customer_id": c_id, "customer_code": cust_code, "customer_name": cust_name, "amount": amount, "account_id": acc_id, "trans_code": t_code, "note": note}
                        record_cloud_event("customer_debt_pay", "pay", cust_code, payload)
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": f"Đã thu {amount} đ nợ khách hàng thành công!"})
            return

        # SAVE TRANSACTION
        if path == "/api/save-transaction" or api == "save-transaction":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            t_type = (data.get("trans_type") or "THU").upper()
            amt = float(data.get("amount") or 0)
            cat = data.get("category", "Thu khác" if t_type == "THU" else "Chi khác")
            p_name = data.get("partner_name", "")
            note = data.get("note", "")
            acc_id = int(data.get("account_id") or 1)
            conn = get_db_connection()
            if conn and amt > 0:
                try:
                    cur = conn.cursor()
                    prefix = "PT" if t_type == "THU" else "PC"
                    code = f"{prefix}{datetime.now().strftime('%y%m%d')}{int(time.time()%1000):03d}"
                    cur.execute("INSERT INTO cash_transactions (code, trans_type, account_id, amount, partner_name, category, note) VALUES (?, ?, ?, ?, ?, ?, ?)", (code, t_type, acc_id, amt, p_name, cat, note))
                    delta = amt if t_type == "THU" else -amt
                    cur.execute("UPDATE cash_accounts SET current_balance = current_balance + ? WHERE id = ?", (delta, acc_id))
                    conn.commit()
                    payload = {"code": code, "trans_type": t_type, "account_id": acc_id, "amount": amt, "category": cat, "partner_name": p_name, "note": note}
                    record_cloud_event("transaction", "save", code, payload)
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": f"Đã tạo phiếu {t_type} thành công!"})
            return

        # CANCEL INVOICE
        if path == "/api/cancel-invoice" or api == "cancel-invoice":
            if not self.check_auth():
                self.send_json(401, {"status": "error", "error": "Unauthorized"})
                return
            data = json.loads(raw_body.decode("utf-8")) if raw_body else {}
            inv_id = int(data.get("invoice_id") or 0)
            reason = data.get("reason", "Hủy từ Portal Online")
            conn = get_db_connection()
            if conn:
                try:
                    cur = conn.cursor()
                    cur.execute("SELECT code, customer_id, remaining_debt, status FROM sales_invoices WHERE id = ?", (inv_id,))
                    inv_row = cur.fetchone()
                    if inv_row and inv_row[3] != "CANCELLED":
                        code, c_id, r_debt = inv_row[0], inv_row[1], float(inv_row[2])
                        cur.execute("SELECT product_id, quantity FROM sales_invoice_items WHERE invoice_id = ?", (inv_id,))
                        for it in cur.fetchall():
                            cur.execute("UPDATE stock_balances SET quantity = quantity + ? WHERE product_id = ? AND warehouse_id = 1", (it[1], it[0]))
                        if r_debt > 0 and c_id:
                            cur.execute("UPDATE customers SET current_debt = MAX(0, current_debt - ?) WHERE id = ?", (r_debt, c_id))
                        cur.execute("UPDATE sales_invoices SET status = 'CANCELLED', note = note || ' [HỦY: ' || ? || ']' WHERE id = ?", (reason, inv_id))
                        conn.commit()
                        record_cloud_event("invoice_cancel", "cancel", code, {"invoice_id": inv_id, "invoice_code": code, "reason": reason})
                finally:
                    conn.close()
            self.send_json(200, {"status": "ok", "message": "Đã hủy đơn hàng và hoàn lại tồn kho thành công!"})
            return

        self.send_json(404, {"status": "error", "error": "Not Found"})

def run_server(port: int = 8000, host: str = "0.0.0.0"):
    server_address = (host, port)
    httpd = HTTPServer(server_address, CloudSyncHandler)
    print(f"=================================================================")
    print(f"  CLOUD POS SYNC SERVER & WEB MANAGEMENT PORTAL 24/24")
    print(f"  Listening on: http://{host}:{port}")
    print(f"  Secret Key: {get_server_secret()}")
    print(f"=================================================================")
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nShutting down server...")
        httpd.server_close()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Cloud POS Sync Server")
    parser.add_argument("--port", type=int, default=int(os.environ.get("PORT", 8000)), help="Port to listen on")
    parser.add_argument("--host", type=str, default="0.0.0.0", help="Host address")
    parser.add_argument("--secret", type=str, default="", help="Sync Secret Key")
    args = parser.parse_args()

    if args.secret:
        set_server_secret(args.secret)

    run_server(port=args.port, host=args.host)
