"""
core/inventory.py — Xử lý logic Nhập - Xuất - Tồn
"""
import sqlite3
import os


def _get_conn(db_path: str) -> sqlite3.Connection:
    """Mở kết nối với WAL + foreign keys enabled."""
    conn = sqlite3.connect(db_path)
    conn.execute("PRAGMA journal_mode=WAL")
    conn.execute("PRAGMA foreign_keys=ON")
    return conn

def ensure_category_schema(db_path: str):
    """"Bảo đảm bảng product_categories tồn tại và products có category_id."""
    if not os.path.exists(db_path):
        return
    conn = _get_conn(db_path)
    c = conn.cursor()
    # Tạo bảng product_categories nếu chưa có
    c.execute("""
    CREATE TABLE IF NOT EXISTS product_categories (
        id          INTEGER PRIMARY KEY,
        name        TEXT NOT NULL UNIQUE,
        description TEXT,
        gtgt_rate   REAL DEFAULT 0.0,
        tncn_rate   REAL DEFAULT 0.0,
        is_active   INTEGER DEFAULT 1,
        created_at  TEXT DEFAULT (datetime('now','localtime'))
    )
    """)
    # Kiểm tra cột category_id trong bảng products
    dinfo = c.execute("PRAGMA table_info(products)").fetchall()
    cols = [col[1] for col in dinfo]
    if "category_id" not in cols:
        c.execute("ALTER TABLE products ADD COLUMN category_id INTEGER REFERENCES product_categories(id)")
    
    # Kiểm tra cột gtgt_rate và tncn_rate trong bảng product_categories (cho database cũ)
    cinfo = c.execute("PRAGMA table_info(product_categories)").fetchall()
    ccols = [col[1] for col in cinfo]
    
    if "gtgt_rate" not in ccols:
        c.execute("ALTER TABLE product_categories ADD COLUMN gtgt_rate REAL DEFAULT 0.0")
    if "tncn_rate" not in ccols:
        c.execute("ALTER TABLE product_categories ADD COLUMN tncn_rate REAL DEFAULT 0.0")
        
    # Nạp 6 nhóm mặc định theo chuẩn TT 40/2021 nếu bảng trống
    # This block is removed as seed data is now centralized in db_init.py
    # count = c.execute("SELECT COUNT(*) FROM product_categories").fetchone()[0]
    # if count == 0:
    #     default_cats = [
    #         ("Nhóm 1", "Phân phối, cung cấp hàng hóa: Bán buôn, Bán lẻ, Đại lý bán đúng giá hưởng hoa hồng, Thương mại tạp hóa, Siêu thị mini, Cửa hàng vật tư, Bán hàng online thuần thương mại. (Kh.bao gồm sản xuất)", 1.0, 0.5),
    #         ("Nhóm 2", "Sản xuất, gia công, xây dựng có bao thầu: Sản xuất, chế biến, Gia công cơ khí, Gia công may mặc, Xây dựng lắp đặt có bao thầu vật tư, Khai thác, chế biến. (Có yếu tố tạo ra sản phẩm)", 2.0, 1.0),
    #         ("Nhóm 3", "Dịch vụ gắn với hàng hóa: Nhà hàng, Quán ăn, Cafe tại chỗ, Dịch vụ vận tải có hàng hóa, Sửa chữa có thay thế linh kiện, Cắt tóc có bán mỹ phẩm. (Cung ứng DV + Hàng hóa)", 3.0, 1.5),
    #         ("Nhóm 4", "Dịch vụ thuần túy: Spa, Massage, Khách sạn, Lưu trú, Tư vấn, Thiết kế, Kế toán DV, Sửa chữa chỉ tính công, Dạy học, Lập trình phần mềm, Marketing, Môi giới, DV nền tảng số. (Kh.bao thầu vật tư)", 5.0, 2.0),
    #         ("Nhóm 5", "Cho thuê tài sản: Cho thuê nhà, Cho thuê đất, mặt bằng, Cho thuê xe, Cho thuê máy móc, Cho thuê kho bãi. (Theo mẫu 01/TTS)", 5.0, 5.0),
    #         ("Nhóm 6", "Tùy chỉnh: Trường hợp đặc thù, Miễn giảm, Doanh thu dưới 100tr/năm, Doanh thu nền tảng số xuyên biên giới, Ngành đặc biệt chưa quy chuẩn.", 0.0, 0.0),
    #     ]
    #     c.executemany("""
    #         INSERT INTO product_categories (name, description, gtgt_rate, tncn_rate)
    #         VALUES (?, ?, ?, ?)
    #     """, default_cats)
        
    conn.commit()
    conn.close()

def get_stock_summary(db_path: str):
    """
    Tính toán báo cáo Nhập-Xuất-Tồn cho tất cả sản phẩm.
    """
    if not os.path.exists(db_path):
        return []
        
    ensure_category_schema(db_path)
    
    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    
    # Query tính tổng nhập, xuất theo từng sản phẩm
    sql = """
    SELECT 
        p.code, 
        p.name, 
        p.unit,
        p.purchase_price,
        p.sale_price,
        p.category_id,
        c.name as category_name,
        c.gtgt_rate,
        c.tncn_rate,
        SUM(CASE WHEN m.type = 'in' THEN m.quantity ELSE 0 END) as total_in,
        SUM(CASE WHEN m.type = 'out' THEN m.quantity ELSE 0 END) as total_out,
        (SUM(CASE WHEN m.type = 'in' THEN m.quantity ELSE 0 END) - 
         SUM(CASE WHEN m.type = 'out' THEN m.quantity ELSE 0 END)) as balance
    FROM products p
    LEFT JOIN product_categories c ON p.category_id = c.id
    LEFT JOIN inventory_movements m ON p.id = m.product_id
    GROUP BY p.id
    """
    rows = c.execute(sql).fetchall()
    conn.close()
    return [dict(r) for r in rows]

def add_movement(db_path: str, product_id: int, move_type: str, qty: float, price: float, voucher_id: int = None):
    """Thêm một dòng biến động kho."""
    conn = _get_conn(db_path)
    c = conn.cursor()
    c.execute("""
        INSERT INTO inventory_movements (product_id, voucher_id, move_date, type, quantity, unit_price, total_value)
        VALUES (?, ?, date('now'), ?, ?, ?, ?)
    """, (product_id, voucher_id, move_type, qty, price, qty * price))
    conn.commit()
    conn.close()

def add_product(db_path: str, code: str, name: str, unit: str, category_id: int, purchase_price: float, sale_price: float):
    """Thêm sản phẩm mới vào danh mục."""
    ensure_category_schema(db_path)
    conn = _get_conn(db_path)
    c = conn.cursor()
    c.execute("""
        INSERT INTO products (code, name, unit, category_id, purchase_price, sale_price, is_active)
        VALUES (?, ?, ?, ?, ?, ?, 1)
    """, (code, name, unit, category_id, purchase_price, sale_price))
    conn.commit()
    conn.close()

def update_product(db_path: str, old_code: str, new_code: str, name: str, unit: str, category_id: int, buy: float, sell: float):
    """Cập nhật thông tin sản phẩm."""
    conn = _get_conn(db_path)
    c = conn.cursor()
    c.execute("""
        UPDATE products 
        SET code=?, name=?, unit=?, category_id=?, purchase_price=?, sale_price=?
        WHERE code=?
    """, (new_code, name, unit, category_id, buy, sell, old_code))
    conn.commit()
    conn.close()

def delete_product(db_path: str, code: str):
    """Xóa sản phẩm (nếu chưa có phát sinh kho)."""
    conn = _get_conn(db_path)
    c = conn.cursor()
    # Kiểm tra xem có phát sinh kho không
    pid = c.execute("SELECT id FROM products WHERE code=?", (code,)).fetchone()
    if not pid:
        conn.close()
        return
    
    pid = pid[0]
    moves = c.execute("SELECT COUNT(*) FROM inventory_movements WHERE product_id=?", (pid,)).fetchone()[0]
    
    if moves > 0:
        # Nếu đã có phát sinh, chỉ đánh dấu is_active = 0 (soft delete)
        c.execute("UPDATE products SET is_active=0 WHERE id=?", (pid,))
    else:
        # Nếu chưa có gì, xóa hẳn
        c.execute("DELETE FROM products WHERE id=?", (pid,))
        
    conn.commit()
    conn.close()

def get_categories(db_path: str):
    """Lấy danh sách nhóm hàng hóa."""
    ensure_category_schema(db_path)
    conn = _get_conn(db_path)
    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    rows = c.execute("SELECT * FROM product_categories ORDER BY name").fetchall()
    conn.close()
    return [dict(r) for r in rows]

def add_category(db_path: str, name: str, description: str, gtgt_rate: float, tncn_rate: float):
    ensure_category_schema(db_path)
    conn = _get_conn(db_path)
    c = conn.cursor()
    c.execute("INSERT INTO product_categories (name, description, gtgt_rate, tncn_rate) VALUES (?, ?, ?, ?)", (name, description, gtgt_rate, tncn_rate))
    conn.commit()
    conn.close()

def update_category(db_path: str, cat_id: int, name: str, description: str, gtgt_rate: float, tncn_rate: float):
    ensure_category_schema(db_path)
    conn = _get_conn(db_path)
    c = conn.cursor()
    c.execute("UPDATE product_categories SET name=?, description=?, gtgt_rate=?, tncn_rate=? WHERE id=?", (name, description, gtgt_rate, tncn_rate, cat_id))
    conn.commit()
    conn.close()

def delete_category(db_path: str, cat_id: int):
    ensure_category_schema(db_path)
    conn = _get_conn(db_path)
    c = conn.cursor()
    # ♻️ Upgrade 7: Guard — kiểm tra sản phẩm đang dùng nhóm này
    used = c.execute(
        "SELECT COUNT(*) FROM products WHERE category_id=? AND is_active=1", (cat_id,)
    ).fetchone()[0]
    if used > 0:
        conn.close()
        raise ValueError(f"Không thể xóa: có {used} sản phẩm đang dùng nhóm này.")
    c.execute("DELETE FROM product_categories WHERE id=?", (cat_id,))
    conn.commit()
    conn.close()

def get_next_product_code(db_path: str) -> str:
    """Sinh mã sản phẩm tiếp theo (HH001, HH002...)."""
    if not os.path.exists(db_path):
        return "HH001"

    conn = _get_conn(db_path)
    c = conn.cursor()
    # Tìm mã HHxxx lớn nhất
    row = c.execute("SELECT code FROM products WHERE code LIKE 'HH%' ORDER BY code DESC LIMIT 1").fetchone()
    conn.close()
    
    if not row:
        return "HH001"
    
    last_code = row[0]
    try:
        # Tách phần số (ví dụ HH005 -> 5)
        num_part = int(last_code[2:])
        return f"HH{num_part + 1:03d}"
    except:
        return "HH001"


