from __future__ import annotations

from collections.abc import Iterable

EXPENSE_TYPE_KEYWORD_GROUPS: tuple[tuple[str, str, tuple[str, ...]], ...] = (
    (
        "travel",
        "差旅费",
        (
            "差旅费",
            "差旅",
            "出差",
            "外地出差",
            "跨城交通",
            "往返车票",
            "机票",
            "飞机票",
            "航班",
            "登机牌",
            "行程单",
            "火车票",
            "高铁票",
            "动车票",
            "铁路客票",
            "客票",
        ),
    ),
    (
        "hotel",
        "住宿费",
        (
            "住宿费",
            "住宿",
            "酒店发票",
            "酒店",
            "宾馆",
            "民宿",
            "房费",
            "客房",
            "住店",
            "入住",
            "离店",
            "住宿清单",
        ),
    ),
    (
        "transport",
        "交通费",
        (
            "交通费",
            "交通",
            "市内交通",
            "打车",
            "网约车",
            "出租车票",
            "出租车",
            "的士票",
            "的士",
            "滴滴",
            "曹操出行",
            "T3出行",
            "出行",
            "乘车费",
            "乘车",
            "用车",
            "叫车",
            "车费",
            "车资",
            "公交",
            "地铁",
            "停车费",
            "停车",
            "过路费",
            "通行费",
            "高速费",
            "燃油费",
            "油费",
        ),
    ),
    (
        "meal",
        "业务招待费",
        (
            "业务招待费",
            "业务招待",
            "招待费",
            "招待",
            "客户招待",
            "客户接待",
            "商务接待",
            "商务宴请",
            "宴请",
            "请客",
            "请客户",
            "客户用餐",
            "客户餐",
            "客户吃饭",
            "陪同用餐",
            "接待餐",
            "餐费",
            "伙食费",
            "伙食",
            "工作餐",
            "餐饮",
            "用餐",
            "早餐",
            "午餐",
            "晚餐",
            "夜宵",
            "盒饭",
            "茶歇",
            "餐票",
            "饭票",
        ),
    ),
    (
        "meeting",
        "会务费",
        (
            "会务费",
            "会务",
            "会议费",
            "会议",
            "参会",
            "会场",
            "场地费",
            "论坛",
            "展会",
            "研讨会",
            "峰会",
            "布展",
        ),
    ),
    (
        "marketing",
        "市场推广费",
        (
            "市场推广费",
            "市场推广",
            "推广费",
            "广告费",
            "广告投放",
            "投放费",
            "品牌宣传",
            "宣传费",
            "营销物料",
            "推广物料",
        ),
    ),
    (
        "office",
        "办公用品费",
        (
            "办公用品费",
            "办公费",
            "办公用品",
            "办公耗材",
            "办公设备",
            "采购",
            "集中采购",
            "物资采购",
            "办公采购",
            "办公",
            "文具",
            "耗材",
            "打印纸",
            "打印",
            "纸张",
            "硒鼓",
            "墨盒",
            "键盘",
            "鼠标",
            "白板",
            "电脑配件",
        ),
    ),
    (
        "training",
        "培训费",
        (
            "培训费",
            "培训",
            "讲师费",
            "讲师",
            "课时费",
            "课程费",
            "课程",
            "教材",
            "学费",
            "考试费",
            "认证费",
            "认证",
        ),
    ),
    (
        "software",
        "软件服务费",
        (
            "软件服务费",
            "软件费",
            "软件订阅",
            "SaaS",
            "SAAS",
            "saas",
            "SaaS订阅",
            "系统服务费",
            "云服务费",
            "云资源",
            "平台服务费",
            "技术服务费",
        ),
    ),
    (
        "communication",
        "通讯费",
        (
            "通讯费",
            "通讯",
            "话费",
            "电话费",
            "手机费",
            "流量费",
            "流量",
            "宽带费",
            "宽带",
            "网络费",
        ),
    ),
    (
        "welfare",
        "福利费",
        (
            "福利费",
            "福利",
            "团建",
            "慰问",
            "节日福利",
            "体检费",
            "体检",
            "员工关怀",
        ),
    ),
)


EXPENSE_TYPE_LABEL_BY_CODE = {
    code: label for code, label, _keywords in EXPENSE_TYPE_KEYWORD_GROUPS
}
EXPENSE_TYPE_LABEL_BY_CODE.setdefault("entertainment", "业务招待费")


def build_expense_type_keyword_map() -> dict[str, str]:
    mapping: dict[str, str] = {}
    for code, _label, keywords in EXPENSE_TYPE_KEYWORD_GROUPS:
        for keyword in keywords:
            mapping.setdefault(keyword, code)
    return mapping


def iter_expense_keywords(*codes: str) -> Iterable[str]:
    allowed_codes = {str(code or "").strip() for code in codes if str(code or "").strip()}
    for code, _label, keywords in EXPENSE_TYPE_KEYWORD_GROUPS:
        if allowed_codes and code not in allowed_codes:
            continue
        yield from keywords


def resolve_expense_type_code_from_text(value: str) -> str | None:
    compact = str(value or "").replace(" ", "")
    if not compact:
        return None
    for code, _label, keywords in EXPENSE_TYPE_KEYWORD_GROUPS:
        if any(keyword in compact for keyword in keywords):
            return code
    return None


def resolve_expense_type_label_from_text(value: str) -> tuple[str, str] | None:
    code = resolve_expense_type_code_from_text(value)
    if not code:
        return None
    return code, EXPENSE_TYPE_LABEL_BY_CODE.get(code, str(value or "").strip())
