from __future__ import annotations

"""Four Pillars Classification and Double-Entry Accounting Engine for DSCons ERP."""

import logging
from decimal import Decimal
from typing import Any

logger = logging.getLogger(__name__)

# Core Business Pillars constants
PILLAR_1_CONSTRUCTION = "Trụ cột 1: Thi công Xây lắp & Thủy lợi"
PILLAR_2_LOGISTICS = "Trụ cột 2: Vận tải Xe Ben & Logistics"
PILLAR_3_MACHINERY = "Trụ cột 3: Cho thuê Ca máy Đào"
PILLAR_4_MATERIALS = "Trụ cột 4: Mua bán Vật tư & San lấp"
PILLAR_GNA_ADMIN = "Chi phí Quản lý & Vận hành Doanh nghiệp"
PILLAR_FINANCIAL = "Chi phí Tài chính & Ngân hàng"


class FourPillarsAccountingEngine:
    """Classifies input invoices based on genuine line items into 4 business pillars and generates accounting entries."""

    @staticmethod
    def classify_invoice_and_account(
        inv: dict[str, Any], items: list[dict[str, Any]]
    ) -> dict[str, Any]:
        """Classify an invoice and compute double-entry ledger accounts.

        Returns:
            {
                "pillar": str,
                "pillar_code": str,
                "debit_account": str,
                "debit_vat_account": str,
                "credit_account": str,
                "payment_requirement": str,
                "cost_category_summary": str,
                "explanation": str
            }
        """
        seller_name = str(inv.get("seller_name") or "").lower()
        seller_tax = str(inv.get("seller_tax_code") or "").strip()
        total_amount = Decimal(str(inv.get("total_amount_vnd") or 0))

        # Check banking / finance institutions
        is_bank = (
            "ngân hàng" in seller_name
            or "techcombank" in seller_name
            or "acb" in seller_name
            or "vietinbank" in seller_name
            or "vpbank" in seller_name
            or "mbbank" in seller_name
            or "bidv" in seller_name
            or "vietcombank" in seller_name
        )

        # Check telecom / office / IT
        is_telecom_office = (
            "viễn thông" in seller_name
            or "viettel" in seller_name
            or "vnpt" in seller_name
            or "mobifone" in seller_name
            or "fpt" in seller_name
            or "phần mềm" in seller_name
            or "văn phòng phẩm" in seller_name
        )

        # Aggregate item names and categories
        item_names = [str(it.get("item_name") or "").lower() for it in items]
        all_items_text = " ".join(item_names)

        # 1. Financial & Banking
        if is_bank and (not all_items_text or "phí" in all_items_text or "dịch vụ" in all_items_text):
            return {
                "pillar": PILLAR_FINANCIAL,
                "pillar_code": "financial",
                "debit_account": "635",
                "debit_vat_account": "1331",
                "credit_account": "1121",
                "payment_requirement": "TRU_TU_DONG_TAI_KHOAN",
                "cost_category_summary": "Phí dịch vụ ngân hàng / Phí chuyển tiền",
                "explanation": f"Hóa đơn phí dịch vụ tài chính ngân hàng từ {inv.get('seller_name')}.",
            }

        # 2. General Administrative (G&A)
        if is_telecom_office or "tiếp khách" in all_items_text or "văn phòng phẩm" in all_items_text:
            return {
                "pillar": PILLAR_GNA_ADMIN,
                "pillar_code": "gna",
                "debit_account": "642",
                "debit_vat_account": "1331",
                "credit_account": "331" if total_amount >= 20_000_000 else "1111/1121",
                "payment_requirement": "BAT_BUOC_CHUYEN_KHOAN_UNC" if total_amount >= 20_000_000 else "TIEN_MAT_HOAC_UNC",
                "cost_category_summary": "Chi phí quản lý doanh nghiệp / Viễn thông / VP",
                "explanation": f"Hóa đơn chi phí quản lý vận hành văn phòng từ {inv.get('seller_name')}.",
            }

        # 3. Machinery & Equipment Rental / Repair (Trụ Cột 3)
        machinery_keywords = [
            "máy đào", "may dao", "ca máy", "ca may", "kobelco", "komatsu", "sumitomo",
            "yanmar", "piston", "thủy lực", "xilanh", "đĩa lỗ", "mặt chà", "bơm thủy lực",
            "xích máy đào", "dầu thủy lực", "phụ tùng máy xúc", "máy ủi", "máy lu", "lu rung"
        ]
        has_machinery = any(any(k in it_name for k in machinery_keywords) for it_name in item_names)

        # 4. Transport & Fleet Logistics (Trụ Cột 2)
        transport_fleet_keywords = [
            "dầu do", "dầu diezel", "xăng dầu", "petrolimex", "săm lốp", "lốp xe", "xe ben",
            "ô tô tải", "xe tải", "đăng kiểm", "cầu đường", "phí đường bộ", "howo"
        ]
        has_transport_fleet = any(any(k in it_name for k in transport_fleet_keywords) for it_name in item_names) or (
            "petrolimex" in seller_name and ("dầu" in all_items_text or "do 0,05s" in all_items_text)
        )

        # 5. Civil Construction Materials & Subcontractors (Trụ Cột 1)
        construction_keywords = [
            "xi măng", "ximang", "gạch", "cát ", "cát xây", "cát bê tông", "đá 1x2", "đá 4x6",
            "đá hộc", "bê tông", "thép", "sắt", "tôn mạ", "tôn lạnh", "xà gồ", "ống thép",
            "inox", "đá granite", "cáp điện", "dây điện", "đèn led", "chiếu sáng", "ống cống",
            "cọc bê tông", "chống thấm", "sơn", "vữa", "nhựa đường", "nhũ tương", "thạch cao",
            "cửa cuốn", "nhôm kính", "vách kính", "thi công", "lắp dựng", "xây lắp"
        ]
        has_construction = any(any(k in it_name for k in construction_keywords) for it_name in item_names)

        # 6. Commercial Trading Materials (Trụ Cột 4)
        is_trading_partner = seller_tax == "0201805660" or "trung kiên" in seller_name

        # Decision Logic:
        if is_trading_partner:
            pillar = PILLAR_4_MATERIALS
            pillar_code = "pillar_4"
            debit_acc = "1561"
            explanation = "Mua bán vật tư thương mại / san lấp mặt bằng (Trụ Cột 4 - Đối tác Trung Kiên)."
        elif has_machinery and not has_construction:
            pillar = PILLAR_3_MACHINERY
            pillar_code = "pillar_3"
            debit_acc = "623"
            explanation = "Thuê ca máy đào / phụ tùng bảo dưỡng hệ thống máy cơ giới phục vụ thi công (Trụ Cột 3)."
        elif has_transport_fleet and not has_construction:
            pillar = PILLAR_2_LOGISTICS
            pillar_code = "pillar_2"
            debit_acc = "154_LOGISTICS"
            explanation = "Chi phí nhiên liệu dầu DO, săm lốp, ca xe ben phục vụ dịch vụ vận tải logistics (Trụ Cột 2)."
        elif has_construction or (not has_machinery and not has_transport_fleet):
            pillar = PILLAR_1_CONSTRUCTION
            pillar_code = "pillar_1"
            if any("máy" in it or "ca" in it for it in item_names):
                debit_acc = "623"
            elif any("nhân công" in it or "lắp dựng" in it or "gia công" in it for it in item_names):
                debit_acc = "622"
            elif any("sửa chữa" in it or "bảo dưỡng" in it or "tư vấn" in it for it in item_names):
                debit_acc = "627"
            else:
                debit_acc = "621"
            explanation = "Vật tư xây dựng / chi phí thầu phụ trực tiếp công trình Xây lắp & Thủy lợi (Trụ Cột 1)."
        else:
            pillar = PILLAR_1_CONSTRUCTION
            pillar_code = "pillar_1"
            debit_acc = "621"
            explanation = "Chi phí sản xuất xây lắp công trình (Trụ Cột 1)."

        if total_amount >= 20_000_000:
            pay_req = "BAT_BUOC_CHUYEN_KHOAN_UNC"
        else:
            pay_req = "TIEN_MAT_HOAC_UNC"

        if items:
            items_summary = "; ".join(
                [f"{it.get('item_name')} ({it.get('quantity')} {it.get('unit')})" for it in items[:3]]
            )
            if len(items) > 3:
                items_summary += f" ... (+{len(items) - 3} mục khác)"
        else:
            items_summary = "Chưa có danh mục dòng hàng"

        return {
            "pillar": pillar,
            "pillar_code": pillar_code,
            "debit_account": debit_acc,
            "debit_vat_account": "1331",
            "credit_account": "331",
            "payment_requirement": pay_req,
            "cost_category_summary": items_summary,
            "explanation": explanation,
        }
