"""
revenue_db.py — CRUD operations cho bảng daily_revenue (Doanh thu hàng ngày).
Database riêng: data/revenue.db (tách biệt với DB kế toán).

⚠️ NGUYÊN TẮC PHÁP LÝ (HKD_LEGAL_MASTER_PACK_V2):
1. Thuế & Kế toán: Tuân thủ Luật TNCN 109/2025/QH15 + Luật GTGT 48/2024/QH15 (Từ 01/01/2026).
2. Bảo mật (NĐ 13/2023/NĐ-CP): KHÔNG LƯU SĐT/Tiểu sử Khách hàng vào DB nếu chưa có xác nhận "Đồng ý" (Consent).
3. Người sử dụng có trách nhiệm kiểm tra và thực hiện nghĩa vụ thuế/bảo vệ dữ liệu cá nhân.
"""

import sqlite3
import os
from datetime import datetime
from typing import Optional

# ── Ngưỡng doanh thu HKD — Nghị quyết 198/2025/QH15 (hiệu lực 01/01/2026) ──
REVENUE_THRESHOLD      = 500_000_000     # 500 triệu VND/năm — ngưỡng miễn thuế
REVENUE_EINVOICE       = 1_000_000_000   # 1 tỷ VND/năm — bắt buộc HĐĐT
REVENUE_DEDUCT_METHOD  = 3_000_000_000   # 3 tỷ VND/năm — chuyển sang phương pháp khấu trừ
REVENUE_HIGH_RATE      = 50_000_000_000  # 50 tỷ VND/năm — thuế suất cao/DN

# 4 nhóm ngưỡng doanh thu chính thức theo NQ 198/2025/QH15
HKD_GROUPS = [
    {
        "group": 1,
        "label": "Nhóm 1 — Dưới 500 triệu",
        "min": 0,
        "max": 500_000_000,
        "tax_method": "miễn_thuế",
        "gtgt_pct": 0.0,
        "tncn_pct": 0.0,
        "einvoice_required": False,
        "accounting_required": False,
        "declare_freq": "1 lần/năm (chậm nhất 31/01 năm sau)",
        "note": "Miễn thuế GTGT và TNCN. Khai doanh thu 1 lần/năm. Không bắt buộc HĐĐT & sổ sách kế toán.",
        "color": "success",
    },
    {
        "group": 2,
        "label": "Nhóm 2 — 500 triệu – 1 tỷ",
        "min": 500_000_000,
        "max": 1_000_000_000,
        "tax_method": "khấu_trừ_trực_tiếp",
        "gtgt_pct": None,    # Theo tỷ lệ % ngành nghề (TT40/2021)
        "tncn_pct": None,    # Tự chọn: tỷ lệ % DT hoặc (DT − chi phí) x 15%
        "einvoice_required": False,
        "accounting_required": False,
        "declare_freq": "Theo quý",
        "note": "Phát sinh thuế GTGT + TNCN. Tự kê khai theo quý. Chưa bắt buộc HĐĐT.",
        "color": "warning",
    },
    {
        "group": 3,
        "label": "Nhóm 3 — 1 tỷ – 3 tỷ",
        "min": 1_000_000_000,
        "max": 3_000_000_000,
        "tax_method": "khấu_trừ_trực_tiếp",
        "gtgt_pct": None,
        "tncn_pct": None,
        "einvoice_required": True,   # Bắt buộc HĐĐT khởi tạo từ máy tính tiền (POS)
        "accounting_required": False,
        "declare_freq": "Theo quý",
        "note": "Bắt buộc HĐĐT khởi tạo từ POS (máy tính tiền). Tự kê khai theo quý.",
        "color": "warning",
    },
    {
        "group": 4,
        "label": "Nhóm 4 — 3 tỷ – 50 tỷ",
        "min": 3_000_000_000,
        "max": 50_000_000_000,
        "tax_method": "khấu_trừ",
        "gtgt_pct": None,     # Phương pháp khấu trừ như doanh nghiệp
        "tncn_pct": 17.0,    # TNCN ~ 15–17% trên lợi nhuận (DT − chi phí)
        "einvoice_required": True,
        "accounting_required": True,
        "declare_freq": "Theo quý",
        "note": "Phương pháp khấu trừ như doanh nghiệp. TNCN ≈ 15–17% lợi nhuận. Bắt buộc kế toán và HĐĐT.",
        "color": "danger",
    },
    {
        "group": 5,
        "label": "Nhóm 5 — Trên 50 tỷ",
        "min": 50_000_000_000,
        "max": float("inf"),
        "tax_method": "khấu_trừ_cao",
        "gtgt_pct": None,
        "tncn_pct": 20.0,    # TNCN ≈ 20%
        "einvoice_required": True,
        "accounting_required": True,
        "declare_freq": "Theo quý",
        "note": "Quy mô cực lớn. TNCN ≈ 20%. Khuyến nghị chuyển đổi lên Hình thức Doanh nghiệp để hưởng ưu đãi SME.",
        "color": "danger",
    },
]

def classify_hkd_group(revenue: float) -> dict:
    """Xếc định HKD thuộc nhóm nào theo NQ 198/2025/QH15."""
    for g in HKD_GROUPS:
        if g["min"] <= revenue < g["max"]:
            return g
    return HKD_GROUPS[-1]

CATEGORIES = {
    # -- DOANH THU (Đẩy vào S1a) --
    "thu_ban_hang":       "💰 Bán hàng (Thu tiền mặt)",
    "thu_ban_hang_ck":    "💳 Bán hàng (Thu chuyển khoản)",
    "thu_no_cong":        "📝 Bán nợ (Ghi nhận nợ công)",
    "thu_tra_hang_tm":    "🔄 Trả hàng (Chi tiền mặt)",
    "thu_tra_hang_ck":    "🔄 Trả hàng (Chi chuyển khoản)",
    
    # -- CHI PHÍ (Đẩy vào S1b - sau này) --
    "chi_nhap_hang":  "📉 Chi nhập hàng hóa",
    "chi_hoat_dong":  "🏢 Chi hoạt động (Điện, nước, thuê...)",
    "chi_luong":      "👤 Chi trả lương",
    "khac":           "📦 Khác",
}

CATEGORY_KEYS   = list(CATEGORIES.keys())
CATEGORY_LABELS = list(CATEGORIES.values())


def _get_default_db_path() -> str:
    """Trả về đường dẫn mặc định của revenue.db."""
    from core.utils import get_company_root_path
    data_dir = get_company_root_path("data")
    os.makedirs(data_dir, exist_ok=True)
    return os.path.join(data_dir, "revenue.db")


def get_revenue_db_path() -> str:
    """Lấy đường dẫn DB (public API)."""
    return _get_default_db_path()


def init_revenue_db(db_path: Optional[str] = None) -> str:
    """
    Khởi tạo database revenue. Tạo bảng nếu chưa có.
    Trả về đường dẫn DB đang dùng.
    """
    if db_path is None:
        db_path = _get_default_db_path()

    conn = sqlite3.connect(db_path)
    conn.execute("PRAGMA journal_mode=WAL")
    conn.execute("""
        CREATE TABLE IF NOT EXISTS daily_revenue (
            id          INTEGER PRIMARY KEY AUTOINCREMENT,
            entry_date  TEXT NOT NULL,
            amount      REAL NOT NULL CHECK(amount >= 0),
            category    TEXT NOT NULL DEFAULT 'thu_ban_hang',
            note        TEXT DEFAULT '',
            product_code TEXT,
            quantity    REAL,
            created_at  TEXT DEFAULT (datetime('now','localtime')),
            invoice_code TEXT
        )
    """)
    conn.execute("CREATE INDEX IF NOT EXISTS idx_date ON daily_revenue(entry_date)")

    # Cấu trúc bảng daily_expense (mới tách)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS daily_expense (
            id          INTEGER PRIMARY KEY AUTOINCREMENT,
            entry_date  TEXT NOT NULL,
            amount      REAL NOT NULL CHECK(amount >= 0),
            category    TEXT NOT NULL DEFAULT 'chi_khac',
            note        TEXT DEFAULT '',
            product_code TEXT,
            quantity    REAL,
            created_at  TEXT DEFAULT (datetime('now','localtime')),
            partner_name TEXT,
            is_paid     INTEGER DEFAULT 1,
            invoice_code TEXT
        )
    """)
    conn.execute("CREATE INDEX IF NOT EXISTS idx_expense_date ON daily_expense(entry_date)")
    
    # 🔄 MIGRATION: Chuyển dữ liệu "Chi" cũ từ daily_revenue sang daily_expense
    try:
        # 1. Thêm cột mới (nếu thiếu) vào daily_revenue
        cursor = conn.execute("PRAGMA table_info(daily_revenue)")
        cols = [row[1] for row in cursor.fetchall()]
        if "product_code" not in cols: conn.execute("ALTER TABLE daily_revenue ADD COLUMN product_code TEXT")
        if "quantity" not in cols: conn.execute("ALTER TABLE daily_revenue ADD COLUMN quantity REAL")
        if "partner_name" not in cols: conn.execute("ALTER TABLE daily_revenue ADD COLUMN partner_name TEXT")
        if "is_paid" not in cols: conn.execute("ALTER TABLE daily_revenue ADD COLUMN is_paid INTEGER DEFAULT 1")
        if "invoice_code" not in cols: conn.execute("ALTER TABLE daily_revenue ADD COLUMN invoice_code TEXT")
        
        # 2. Di chuyển các dòng chi (chi_%)
        # Lưu ý: cần đảm bảo các cột tồn tại trước khi chạy INSERT (đã thực hiện ở buớc trên)
        conn.execute("""
            INSERT INTO daily_expense (entry_date, amount, category, note, product_code, quantity, partner_name, is_paid, invoice_code, created_at)
            SELECT entry_date, amount, category, note, product_code, quantity, partner_name, is_paid, invoice_code, created_at
            FROM daily_revenue
            WHERE category LIKE 'chi_%'
        """)
        
        # 3. Xóa các dòng thu khỏi bảng daily_revenue
        conn.execute("DELETE FROM daily_revenue WHERE category LIKE 'chi_%'")
    except Exception as e:
        print(f"Migration error: {e}")

    # Bảng lưu metadata đồng bộ Google Drive/Sheets
    conn.execute("""
        CREATE TABLE IF NOT EXISTS gs_sync_meta (
            key     TEXT PRIMARY KEY,
            value   TEXT NOT NULL,
            updated TEXT DEFAULT (datetime('now','localtime'))
        )
    """)

    conn.commit()
    conn.close()
    return db_path


def get_gs_meta(key: str, db_path: Optional[str] = None) -> Optional[str]:
    """Đọc giá trị metadata GS Sync từ DB."""
    if db_path is None:
        db_path = _get_default_db_path()
    try:
        conn = sqlite3.connect(db_path)
        row = conn.execute("SELECT value FROM gs_sync_meta WHERE key=?", (key,)).fetchone()
        conn.close()
        return row[0] if row else None
    except Exception:
        return None


def set_gs_meta(key: str, value: str, db_path: Optional[str] = None) -> None:
    """Lưu giá trị metadata GS Sync vào DB."""
    if db_path is None:
        db_path = _get_default_db_path()
    try:
        conn = sqlite3.connect(db_path)
        conn.execute("""
            INSERT INTO gs_sync_meta (key, value, updated)
            VALUES (?, ?, datetime('now','localtime'))
            ON CONFLICT(key) DO UPDATE SET value=excluded.value, updated=excluded.updated
        """, (key, value))
        conn.commit()
        conn.close()
    except Exception as e:
        import logging
        logging.warning(f"set_gs_meta error: {e}")


def add_revenue(
    amount: float,
    entry_date: Optional[str] = None,
    category: str = "thu_ban_hang",
    note: str = "",
    product_code: Optional[str] = None,
    quantity: Optional[float] = None,
    partner_name: Optional[str] = None,
    is_paid: int = 1,
    invoice_code: Optional[str] = None,
    db_path: Optional[str] = None,
) -> int:
    """
    Thêm một bản ghi doanh thu mới.
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if entry_date is None:
        entry_date = datetime.now().strftime("%Y-%m-%d")
    if category not in CATEGORY_KEYS:
        category = "khac"

    conn = sqlite3.connect(db_path)
    cur = conn.execute(
        """
        INSERT INTO daily_revenue (entry_date, amount, category, note, product_code, quantity, partner_name, is_paid, invoice_code)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        """,
        (entry_date, float(amount), category, note.strip(), product_code, quantity, partner_name, is_paid, invoice_code),
    )
    row_id = cur.lastrowid
    conn.commit()
    conn.close()
    return row_id


def get_revenue_by_id(entry_id: int, db_path: Optional[str] = None) -> Optional[dict]:
    """Lấy thông tin chi tiết một bản ghi theo ID."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return None

    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    row = conn.execute("SELECT * FROM daily_revenue WHERE id = ?", (entry_id,)).fetchone()
    conn.close()
    
    if row:
        d = dict(row)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        return d
    return None


def get_recent_entries(limit: int = 100, db_path: Optional[str] = None) -> list[dict]:
    """
    Lấy các bản ghi mới nhất.

    Returns:
        List[dict] với keys: id, entry_date, amount, category, category_label, note, created_at
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return []

    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    rows = conn.execute(
        "SELECT * FROM daily_revenue ORDER BY entry_date DESC, id DESC LIMIT ?",
        (limit,),
    ).fetchall()
    conn.close()

    result = []
    for r in rows:
        d = dict(r)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        result.append(d)
    return result


def get_entries_by_month(year: int, month: int, db_path: Optional[str] = None) -> list[dict]:
    """Lấy tất cả bản ghi của một tháng cụ thể."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return []

    month_str = f"{year}-{month:02d}"
    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    rows = conn.execute(
        "SELECT * FROM daily_revenue WHERE entry_date LIKE ? ORDER BY entry_date DESC, id DESC",
        (f"{month_str}%",),
    ).fetchall()
    conn.close()

    result = []
    for r in rows:
        d = dict(r)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        result.append(d)
    return result


def get_monthly_summary(year: int, month: int, db_path: Optional[str] = None) -> dict:
    """
    Lấy tổng kết doanh thu của một tháng.

    Returns:
        dict: {total, count, year, month}
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return {"total": 0.0, "count": 0, "year": year, "month": month}

    month_str = f"{year}-{month:02d}"
    conn = sqlite3.connect(db_path)
    # Lấy tổng Doanh thu (Chỉ Thu)
    row = conn.execute(
        "SELECT COALESCE(SUM(CASE WHEN category LIKE 'thu_tra_hang%' THEN -amount WHEN category LIKE 'thu_%' OR category = 'ban_hang' OR category = 'dich_vu' THEN amount ELSE 0 END), 0), COUNT(*) "
        "FROM daily_revenue WHERE entry_date LIKE ?",
        (f"{month_str}%",),
    ).fetchone()
    conn.close()
    return {"total": row[0], "count": row[1], "year": year, "month": month}


def get_daily_summary(date_str: str, db_path: Optional[str] = None) -> dict:
    """
    Lấy tổng doanh thu của một ngày cụ thể.

    Args:
        date_str: Ngày 'YYYY-MM-DD'
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return {"total": 0.0, "count": 0, "date": date_str}

    conn = sqlite3.connect(db_path)
    row = conn.execute(
        "SELECT COALESCE(SUM(CASE WHEN category LIKE 'thu_tra_hang%' THEN -amount WHEN category LIKE 'thu_%' OR category = 'ban_hang' OR category = 'dich_vu' THEN amount ELSE 0 END), 0), COUNT(*) "
        "FROM daily_revenue WHERE entry_date = ?",
        (date_str,),
    ).fetchone()
    conn.close()
    return {"total": row[0], "count": row[1], "date": date_str}


def get_yearly_summary(year: int, db_path: Optional[str] = None) -> dict:
    """
    Lấy tổng kết doanh thu của cả năm, bao gồm breakdown theo tháng.

    Returns:
        dict: {
            total: float,
            count: int,
            year: int,
            monthly_breakdown: list[dict],  # 12 tháng
            threshold: float,               # 500_000_000
            threshold_pct: float,           # % đã đạt
            is_exempt: bool,
            warning_level: str,             # 'safe' | 'warning' | 'danger'
        }
    """
    if db_path is None:
        db_path = _get_default_db_path()

    monthly = []
    conn = None

    if os.path.exists(db_path):
        conn = sqlite3.connect(db_path)
        year_str = str(year)
        for m in range(1, 13):
            month_str = f"{year}-{m:02d}"
            row = conn.execute(
                "SELECT COALESCE(SUM(CASE WHEN category LIKE 'thu_tra_hang%' THEN -amount WHEN category LIKE 'thu_%' OR category = 'ban_hang' OR category = 'dich_vu' THEN amount ELSE 0 END), 0), COUNT(*) "
                "FROM daily_revenue WHERE entry_date LIKE ?",
                (f"{month_str}%",),
            ).fetchone()
            monthly.append({"month": m, "total": row[0], "count": row[1]})
        conn.close()
    else:
        monthly = [{"month": m, "total": 0.0, "count": 0} for m in range(1, 13)]

    total = sum(m["total"] for m in monthly)
    pct = (total / REVENUE_THRESHOLD * 100) if REVENUE_THRESHOLD > 0 else 0

    if pct >= 100:
        warning = "danger"
    elif pct >= 80:
        warning = "warning"
    else:
        warning = "safe"

    return {
        "total": total,
        "count": sum(m["count"] for m in monthly),
        "year": year,
        "monthly_breakdown": monthly,
        "threshold": float(REVENUE_THRESHOLD),
        "threshold_pct": round(pct, 1),
        "is_exempt": total <= REVENUE_THRESHOLD,
        "warning_level": warning,
    }


def delete_revenue(entry_id: int, db_path: Optional[str] = None) -> bool:
    """
    Xóa một bản ghi doanh thu theo ID.

    Returns:
        True nếu xóa thành công, False nếu không tìm thấy.
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return False

    conn = sqlite3.connect(db_path)
    cur = conn.execute("DELETE FROM daily_revenue WHERE id = ?", (entry_id,))
    affected = cur.rowcount
    conn.commit()
    conn.close()
    return affected > 0


def update_revenue(
    entry_id: int,
    amount: Optional[float] = None,
    entry_date: Optional[str] = None,
    category: Optional[str] = None,
    note: Optional[str] = None,
    product_code: Optional[str] = None,
    quantity: Optional[float] = None,
    partner_name: Optional[str] = None,
    is_paid: Optional[int] = None,
    invoice_code: Optional[str] = None,
    db_path: Optional[str] = None,
) -> bool:
    """Cập nhật thông tin một bản ghi."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return False

    fields = []
    values = []
    if amount is not None:
        fields.append("amount = ?")
        values.append(float(amount))
    if entry_date is not None:
        fields.append("entry_date = ?")
        values.append(entry_date)
    if category is not None:
        fields.append("category = ?")
        values.append(category)
    if note is not None:
        fields.append("note = ?")
        values.append(note)
    if product_code is not None:
        fields.append("product_code = ?")
        values.append(product_code)
    if quantity is not None:
        fields.append("quantity = ?")
        values.append(quantity)
    if partner_name is not None:
        fields.append("partner_name = ?")
        values.append(partner_name)
    if is_paid is not None:
        fields.append("is_paid = ?")
        values.append(is_paid)
    if invoice_code is not None:
        fields.append("invoice_code = ?")
        values.append(invoice_code)

    if not fields:
        return False

    values.append(entry_id)
    sql = f"UPDATE daily_revenue SET {', '.join(fields)} WHERE id = ?"
    conn = sqlite3.connect(db_path)
    cur = conn.execute(sql, values)
    affected = cur.rowcount
    conn.commit()
    conn.close()
    return affected > 0


# ==============================================================================
# EXPENSE DATABASE METHODS (daily_expense)
# ==============================================================================

def add_expense(
    amount: float,
    entry_date: Optional[str] = None,
    category: str = "chi_khac",
    note: str = "",
    product_code: Optional[str] = None,
    quantity: Optional[float] = None,
    partner_name: Optional[str] = None,
    is_paid: int = 1,
    invoice_code: Optional[str] = None,
    db_path: Optional[str] = None,
) -> int:
    """Thêm một bản ghi chi phí mới."""
    if db_path is None:
        db_path = _get_default_db_path()
    if entry_date is None:
        entry_date = datetime.now().strftime("%Y-%m-%d")

    conn = sqlite3.connect(db_path)
    cur = conn.execute(
        """
        INSERT INTO daily_expense (entry_date, amount, category, note, product_code, quantity, partner_name, is_paid, invoice_code)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        """,
        (entry_date, float(amount), category, note.strip(), product_code, quantity, partner_name, is_paid, invoice_code),
    )
    row_id = cur.lastrowid
    conn.commit()
    conn.close()
    return row_id


def get_expenses_by_month(year: int, month: int, db_path: Optional[str] = None) -> list[dict]:
    """Lấy danh sách chi phí trong tháng cụ thể."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return []

    month_str = f"{year}-{month:02d}"
    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    rows = conn.execute(
        """
        SELECT id, entry_date, amount, category, note, product_code, quantity, created_at, partner_name, is_paid, invoice_code
        FROM daily_expense
        WHERE entry_date LIKE ?
        ORDER BY date(entry_date) DESC, id DESC
        """,
        (f"{month_str}%",),
    ).fetchall()
    conn.close()

    results = []
    for r in rows:
        d = dict(r)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        results.append(d)
    return results


def get_recent_expenses(limit: int = 100, db_path: Optional[str] = None) -> list[dict]:
    """
    Lấy các bản ghi chi phí mới nhất.
    """
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return []

    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    rows = conn.execute(
        "SELECT * FROM daily_expense ORDER BY entry_date DESC, id DESC LIMIT ?",
        (limit,),
    ).fetchall()
    conn.close()

    result = []
    for r in rows:
        d = dict(r)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        result.append(d)
    return result


def delete_expense(entry_id: int, db_path: Optional[str] = None) -> bool:
    """Xóa một bản ghi chi phí theo ID."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return False

    conn = sqlite3.connect(db_path)
    cur = conn.execute("DELETE FROM daily_expense WHERE id = ?", (entry_id,))
    affected = cur.rowcount
    conn.commit()
    conn.close()
    return affected > 0


def get_expense_by_id(entry_id: int, db_path: Optional[str] = None) -> Optional[dict]:
    """Lấy chi tiết một khoản chi phí theo ID."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return None

    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    row = conn.execute(
        """
        SELECT id, entry_date, amount, category, note, product_code, quantity, created_at, partner_name, is_paid, invoice_code
        FROM daily_expense
        WHERE id = ?
        """,
        (entry_id,),
    ).fetchone()
    conn.close()

    if row:
        d = dict(row)
        d["category_label"] = CATEGORIES.get(d["category"], d["category"])
        return d
    return None


def update_expense(
    entry_id: int,
    amount: Optional[float] = None,
    entry_date: Optional[str] = None,
    category: Optional[str] = None,
    note: Optional[str] = None,
    product_code: Optional[str] = None,
    quantity: Optional[float] = None,
    partner_name: Optional[str] = None,
    is_paid: Optional[int] = None,
    invoice_code: Optional[str] = None,
    db_path: Optional[str] = None,
) -> bool:
    """Cập nhật thông tin một bản ghi chi phí."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return False

    fields = []
    values = []
    if amount is not None:
        fields.append("amount = ?")
        values.append(float(amount))
    if entry_date is not None:
        fields.append("entry_date = ?")
        values.append(entry_date)
    if category is not None:
        fields.append("category = ?")
        values.append(category)
    if note is not None:
        fields.append("note = ?")
        values.append(note)
    if product_code is not None:
        fields.append("product_code = ?")
        values.append(product_code)
    if quantity is not None:
        fields.append("quantity = ?")
        values.append(quantity)
    if partner_name is not None:
        fields.append("partner_name = ?")
        values.append(partner_name)
    if is_paid is not None:
        fields.append("is_paid = ?")
        values.append(is_paid)
    if invoice_code is not None:
        fields.append("invoice_code = ?")
        values.append(invoice_code)

    if not fields:
        return False

    values.append(entry_id)
    sql = f"UPDATE daily_expense SET {', '.join(fields)} WHERE id = ?"
    conn = sqlite3.connect(db_path)
    cur = conn.execute(sql, values)
    affected = cur.rowcount
    conn.commit()
    conn.close()
    return affected > 0

def get_total_entry_count(db_path: Optional[str] = None) -> int:
    """Lấy tổng số lượng chứng từ (Thu + Chi) hiện có."""
    if db_path is None:
        db_path = _get_default_db_path()
    if not os.path.exists(db_path):
        return 0
    try:
        conn = sqlite3.connect(db_path)
        r_count = conn.execute("SELECT COUNT(*) FROM daily_revenue").fetchone()[0]
        e_count = conn.execute("SELECT COUNT(*) FROM daily_expense").fetchone()[0]
        conn.close()
        return (r_count or 0) + (e_count or 0)
    except:
        return 0
