"""
redact.py — Xóa thông tin nhạy cảm khỏi hợp đồng VN
=======================================================
Redact các loại dữ liệu nhạy cảm:
  - Mã số thuế (10-13 chữ số)
  - Số tài khoản ngân hàng
  - Số điện thoại VN
  - Tên người đại diện (Ông/Bà + họ tên)
  - Địa chỉ cụ thể (sau từ khóa Địa chỉ:)
  - Số hợp đồng cụ thể
  - Email
"""

import re
from typing import Tuple

# ────────────────────────────────────────────────────────────
# Placeholder tokens
# ────────────────────────────────────────────────────────────
PH_TAX       = "[MÃ SỐ THUẾ]"
PH_BANK_ACC  = "[SỐ TÀI KHOẢN]"
PH_PHONE     = "[SỐ ĐIỆN THOẠI]"
PH_NAME      = "[TÊN ĐẠI DIỆN]"
PH_ADDRESS   = "[ĐỊA CHỈ]"
PH_CONTRACT_NO = "[SỐ HĐ]"
PH_EMAIL     = "[EMAIL]"
PH_DATE_PERSON = "[NGÀY THÁNG]"  # ngày ký cụ thể trong header
PH_BANK_NAME = "[TÊN NGÂN HÀNG]"


# ────────────────────────────────────────────────────────────
# Regex patterns
# ────────────────────────────────────────────────────────────

# Mã số thuế: 10 hoặc 13 chữ số (có thể có dấu -)
RE_TAX = re.compile(
    r"(?:(?:Mã\s*số\s*thuế|MST)\s*[:\-–]?\s*)(\d{10,13}(?:-\d{3})?)",
    re.IGNORECASE | re.UNICODE,
)

# Số tài khoản: dãy số >= 8 chữ số sau từ khóa
RE_BANK_ACC = re.compile(
    r"(?:(?:Số\s*[Tt]ài\s*[Kk]hoản|STK|Account\s*No\.?)\s*[:\-–]?\s*[:\-–]?\s*)(\d[\d\s]{7,})",
    re.IGNORECASE | re.UNICODE,
)

# Số điện thoại VN: 0xx / +84xx / (84) / (+84-x)
RE_PHONE = re.compile(
    r"(?<!\d)"
    r"(\(?\+?84[\s\-–]?[\d][\d\s\-–\(\)]{6,12}"
    r"|0[3-9]\d[\s\-–]?\d{3}[\s\-–]?\d{4}"
    r"|0\d{2}[\s\.]?\d{3,4}[\s\.]?\d{3,4})",
    re.UNICODE,
)

# Tên người: Ông/Bà + 2-4 từ viết hoa chữ cái đầu
RE_NAME = re.compile(
    r"(?:Ông|Bà|ông|bà)\s+"
    r"([A-ZĐÀÁẢÃẠĂẮẶẰẲẴÂẤẦẨẪẬÈÉẺẼẸÊẾỀỂỄỆÌÍỈĨỊÒÓỎÕỌÔỐỒỔỖỘƠỚỜỞỠỢÙÚỦŨỤƯỨỪỬỮỰỲÝỶỸỴ]"
    r"[a-zđàáảãạăắặằẳẵâấầẩẫậèéẻẽẹêếềểễệìíỉĩịòóỏõọôốồổỗộơớờởỡợùúủũụưứừửữựỳýỷỹỵA-Z]+"
    r"(?:\s+[A-ZĐÀÁẢÃẠĂẮẶẰẲẴÂẤẦẨẪẬÈÉẺẼẸÊẾỀỂỄỆÌÍỈĨỊÒÓỎÕỌÔỐỒỔỖỘƠỚỜỞỠỢÙÚỦŨỤƯỨỪỬỮỰỲÝỶỸỴ]"
    r"[a-zđàáảãạăắặằẳẵâấầẩẫậèéẻẽẹêếềểễệìíỉĩịòóỏõọôốồổỗộơớờởỡợùúủũụưứừửữựỳýỷỹỵA-Z]+){1,3})",
    re.UNICODE,
)

# Địa chỉ: sau "Địa chỉ ... :" đến hết dòng
RE_ADDRESS = re.compile(
    r"((?:Địa\s*chỉ|địa\s*chỉ)[^:：]*[:：]\s*)(.+?)(?=\n|$)",
    re.UNICODE,
)

# Số hợp đồng / số phụ lục cụ thể (Số: xx/yyyy/...)
RE_CONTRACT_NO = re.compile(
    r"(?:Số|số)\s*[:\-–]?\s*"
    r"([\w\d]{1,10}[/\-\.]\d{4}[/\-\.][\w\d/\-\.]+)",
    re.UNICODE,
)

# Email
RE_EMAIL = re.compile(
    r"[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}",
    re.UNICODE,
)

# Ngày cụ thể trong header hợp đồng (Hôm nay, ngày XX tháng XX năm XXXX)
RE_DATE_SIGN = re.compile(
    r"((?:Hôm nay|hôm nay),?\s*ngày\s+)\d+(\s+tháng\s+)\d+(\s+năm\s+)\d{4}",
    re.UNICODE,
)

# Tên ngân hàng cụ thể sau "Tại :"
RE_BANK_NAME = re.compile(
    r"(?:(?:Tại|tại)\s*[:\-–]\s*)(Ngân\s+hàng[^,\n]{5,60})",
    re.UNICODE,
)


# ────────────────────────────────────────────────────────────
# Main redact function
# ────────────────────────────────────────────────────────────

def redact(text: str) -> Tuple[str, dict]:
    """
    Redact sensitive info from contract text.

    Returns:
        (redacted_text, stats) where stats = {field: count_replaced}
    """
    stats = {}

    def sub(pattern, placeholder, t, group=None):
        count = 0
        if group is not None:
            def replacer(m):
                nonlocal count
                count += 1
                return m.group(0).replace(m.group(group), placeholder)
            t = pattern.sub(replacer, t)
        else:
            def replacer(m):
                nonlocal count
                count += 1
                return placeholder
            t = pattern.sub(replacer, t)
        return t, count

    # 1. Mã số thuế
    text, n = sub(RE_TAX, PH_TAX, text, group=1)
    if n: stats["mst"] = n

    # 2. Số tài khoản
    text, n = sub(RE_BANK_ACC, PH_BANK_ACC, text, group=1)
    if n: stats["bank_acc"] = n

    # 3. Tên ngân hàng cụ thể
    text, n = sub(RE_BANK_NAME, PH_BANK_NAME, text, group=1)
    if n: stats["bank_name"] = n

    # 4. Số điện thoại
    text, n = sub(RE_PHONE, PH_PHONE, text)
    if n: stats["phone"] = n

    # 5. Tên người đại diện
    text, n = sub(RE_NAME, f"Ông/Bà {PH_NAME}", text)
    if n: stats["name"] = n

    # 6. Địa chỉ cụ thể
    text, n = sub(RE_ADDRESS, PH_ADDRESS, text, group=2)
    if n: stats["address"] = n

    # 7. Email
    text, n = sub(RE_EMAIL, PH_EMAIL, text)
    if n: stats["email"] = n

    # 8. Số hợp đồng cụ thể
    text, n = sub(RE_CONTRACT_NO, PH_CONTRACT_NO, text, group=1)
    if n: stats["contract_no"] = n

    # 9. Ngày ký cụ thể
    def replace_date(m):
        return f"{m.group(1)}[NGÀY]{m.group(2)}[THÁNG]{m.group(3)}[NĂM]"
    orig = text
    text = RE_DATE_SIGN.sub(replace_date, text)
    if text != orig: stats["sign_date"] = 1

    return text, stats


def redact_markdown(md: str) -> Tuple[str, dict]:
    """Redact trong markdown, bỏ qua heading markers."""
    return redact(md)
