from __future__ import annotations

import re
from typing import Any

EXPENSE_RULE_CODE_BLOCK_PATTERN = re.compile(r"```expense-rule\s*(\{.*?\})\s*```", re.DOTALL)

DOCUMENT_TYPE_LABELS = {
    "flight_itinerary": "机票/航班行程单",
    "train_ticket": "火车/高铁票",
    "ship_ticket": "轮船票",
    "hotel_invoice": "酒店住宿票据",
    "taxi_receipt": "出租车/网约车票据",
    "parking_toll_receipt": "停车/通行费票据",
    "meal_receipt": "餐饮票据",
    "office_invoice": "办公用品票据",
    "meeting_invoice": "会议/会务票据",
    "training_invoice": "培训票据",
    "vat_invoice": "增值税发票",
    "receipt": "一般收据/凭证",
    "other": "其他单据",
}

SCENE_LABELS = {
    "travel": "差旅",
    "hotel": "住宿",
    "transport": "交通",
    "meal": "业务招待",
    "entertainment": "业务招待",
    "office": "办公用品",
    "meeting": "会务",
    "training": "培训",
    "communication": "通讯",
    "welfare": "福利",
    "other": "其他",
}

DEFAULT_SCENE_RULE_ASSET_CODE = "rule.expense.scene_submission_standard"
DEFAULT_TRAVEL_RULE_ASSET_CODE = "rule.expense.travel_risk_control_standard"

DEFAULT_SCENE_MATRIX_CONFIG: dict[str, Any] = {
    "kind": "scene_matrix",
    "version": 1,
    "scenes": {
        "travel": {
            "label": "差旅费",
            "location_required": True,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["travel"],
            "allowed_document_types": ["flight_itinerary", "train_ticket"],
            "attachment_mismatch_severity": "high",
        },
        "hotel": {
            "label": "住宿费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["hotel"],
            "allowed_document_types": ["hotel_invoice", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
        },
        "transport": {
            "label": "交通费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["transport"],
            "allowed_document_types": [
                "taxi_receipt",
                "parking_toll_receipt",
                "vat_invoice",
                "receipt",
            ],
            "attachment_mismatch_severity": "high",
            "item_amount_limit": {
                "scope": "item_amount",
                "warn_amount": "300.00",
                "block_amount": "800.00",
                "exception_keywords": [
                    "跨城",
                    "夜间",
                    "应急",
                    "无公共交通",
                    "机场",
                    "火车站",
                    "超标说明",
                ],
                "metric_label": "单笔交通金额",
            },
        },
        "meal": {
            "label": "业务招待费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["meal"],
            "allowed_document_types": ["meal_receipt", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "300.00",
                "block_amount": "800.00",
                "exception_keywords": ["客户接待", "团队活动", "加班", "展会", "超标说明"],
                "metric_label": "业务招待费合计",
            },
        },
        "entertainment": {
            "label": "业务招待费",
            "location_required": True,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["meal"],
            "allowed_document_types": ["meal_receipt", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "2000.00",
                "block_amount": "5000.00",
                "exception_keywords": ["重要客户", "商务宴请", "项目签约", "超标说明"],
                "metric_label": "招待费合计",
            },
        },
        "office": {
            "label": "办公用品费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["office"],
            "allowed_document_types": ["office_invoice", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "1500.00",
                "block_amount": "5000.00",
                "exception_keywords": ["批量采购", "固定资产", "部门集中采购", "超标说明"],
                "metric_label": "办公用品费合计",
            },
        },
        "meeting": {
            "label": "会务费",
            "location_required": True,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["meeting"],
            "allowed_document_types": ["meeting_invoice", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "5000.00",
                "block_amount": "30000.00",
                "exception_keywords": ["大型会议", "外部场地", "超标说明"],
                "metric_label": "会务费合计",
            },
        },
        "training": {
            "label": "培训费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["training"],
            "allowed_document_types": ["training_invoice", "vat_invoice", "receipt"],
            "attachment_mismatch_severity": "high",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "3000.00",
                "block_amount": "15000.00",
                "exception_keywords": ["认证考试", "外部培训", "超标说明"],
                "metric_label": "培训费合计",
            },
        },
        "communication": {
            "label": "通讯费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["other"],
            "allowed_document_types": ["vat_invoice", "receipt"],
            "attachment_mismatch_severity": "medium",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "300.00",
                "block_amount": "1000.00",
                "exception_keywords": ["国际漫游", "专项通信", "超标说明"],
                "metric_label": "通讯费合计",
            },
        },
        "welfare": {
            "label": "福利费",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["other"],
            "allowed_document_types": ["vat_invoice", "receipt"],
            "attachment_mismatch_severity": "medium",
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "1000.00",
                "block_amount": "5000.00",
                "exception_keywords": ["节日福利", "团队活动", "员工关怀", "超标说明"],
                "metric_label": "福利费合计",
            },
        },
        "other": {
            "label": "其他费用",
            "location_required": False,
            "min_attachment_count": 1,
            "allowed_scene_codes": ["other"],
            "allowed_document_types": ["vat_invoice", "receipt"],
            "attachment_mismatch_severity": "medium",
            "always_warn": True,
            "always_warn_message": (
                "其他费用默认进入人工重点复核，请补充清晰用途说明并由审批人重点确认。"
            ),
            "claim_amount_limit": {
                "scope": "claim_total",
                "warn_amount": "1000.00",
                "block_amount": "3000.00",
                "exception_keywords": ["特殊事项", "临时采购", "超标说明"],
                "metric_label": "其他费用合计",
            },
        },
    },
}

DEFAULT_TRAVEL_POLICY_CONFIG: dict[str, Any] = {
    "kind": "travel_policy",
    "version": 1,
    "relevant_expense_types": ["travel", "hotel", "transport"],
    "long_distance_document_types": ["flight_itinerary", "train_ticket"],
    "route_exception_keywords": [
        "中转",
        "转机",
        "经停",
        "改签",
        "多地出差",
        "多城市",
        "多站",
        "异地返程",
        "异地结束",
        "临时变更",
        "继续前往",
        "第二站",
    ],
    "standard_exception_keywords": [
        "超标说明",
        "无直达",
        "展会高峰",
        "会议高峰",
        "协议酒店满房",
        "客户指定",
        "临时改签",
        "行程变更",
        "红眼航班",
        "晚到店",
    ],
    "band_labels": {
        "P0": "P0 实习/见习",
        "P1": "P1 基础员工",
        "P2": "P2 初级员工",
        "P3": "P3 普通员工",
        "P4": "P4 资深员工/主管",
        "P5": "P5 基层经理",
        "P6": "P6 中层经理",
        "P7": "P7 高层经理",
        "P8": "P8 董事会",
    },
    "city_tiers": {
        "北京": "tier_1",
        "上海": "tier_1",
        "广州": "tier_1",
        "深圳": "tier_1",
        "杭州": "tier_2",
        "南京": "tier_2",
        "苏州": "tier_2",
        "武汉": "tier_2",
        "成都": "tier_2",
        "重庆": "tier_2",
        "西安": "tier_2",
        "天津": "tier_2",
        "宁波": "tier_2",
        "厦门": "tier_2",
        "青岛": "tier_2",
        "长沙": "tier_2",
        "郑州": "tier_2",
        "合肥": "tier_2",
        "济南": "tier_2",
        "沈阳": "tier_2",
        "大连": "tier_2",
        "福州": "tier_2",
        "昆明": "tier_2",
        "海口": "tier_2",
        "三亚": "tier_2",
        "无锡": "tier_2",
        "东莞": "tier_2",
        "佛山": "tier_2",
    },
    "hotel_limits": {
        "P0": {"tier_1": "450.00", "tier_2": "380.00", "tier_3": "320.00"},
        "P1": {"tier_1": "450.00", "tier_2": "380.00", "tier_3": "320.00"},
        "P2": {"tier_1": "450.00", "tier_2": "380.00", "tier_3": "320.00"},
        "P3": {"tier_1": "450.00", "tier_2": "380.00", "tier_3": "320.00"},
        "P4": {"tier_1": "550.00", "tier_2": "480.00", "tier_3": "380.00"},
        "P5": {"tier_1": "550.00", "tier_2": "480.00", "tier_3": "380.00"},
        "P6": {"tier_1": "700.00", "tier_2": "620.00", "tier_3": "520.00"},
        "P7": {"tier_1": "900.00", "tier_2": "820.00", "tier_3": "720.00"},
        "P8": {"tier_1": "1200.00", "tier_2": "1000.00", "tier_3": "900.00"},
    },
    # 与内置《公司差旅费报销规则》模板保持一致；数据库尚未初始化规则资产时，
    # 计算器也必须得到同一套城市级标准，不能退回到更宽松的城市层级上限。
    "hotel_city_limits": {
        "北京": {
            "P0": "450.00",
            "P1": "450.00",
            "P2": "450.00",
            "P3": "450.00",
            "P4": "450.00",
            "P5": "450.00",
            "P6": "450.00",
            "P7": "500.00",
            "P8": "500.00",
        },
        "上海": {
            "P0": "450.00",
            "P1": "450.00",
            "P2": "450.00",
            "P3": "450.00",
            "P4": "450.00",
            "P5": "450.00",
            "P6": "450.00",
            "P7": "500.00",
            "P8": "500.00",
        },
        "广州": {
            "P0": "430.00",
            "P1": "430.00",
            "P2": "430.00",
            "P3": "430.00",
            "P4": "450.00",
            "P5": "450.00",
            "P6": "450.00",
            "P7": "500.00",
            "P8": "500.00",
        },
        "深圳": {
            "P0": "430.00",
            "P1": "430.00",
            "P2": "430.00",
            "P3": "430.00",
            "P4": "450.00",
            "P5": "450.00",
            "P6": "450.00",
            "P7": "500.00",
            "P8": "500.00",
        },
        "杭州": {
            "P0": "380.00",
            "P1": "380.00",
            "P2": "380.00",
            "P3": "380.00",
            "P4": "430.00",
            "P5": "430.00",
            "P6": "430.00",
            "P7": "480.00",
            "P8": "480.00",
        },
        "南京": {
            "P0": "380.00",
            "P1": "380.00",
            "P2": "380.00",
            "P3": "380.00",
            "P4": "430.00",
            "P5": "430.00",
            "P6": "430.00",
            "P7": "480.00",
            "P8": "480.00",
        },
        "成都": {
            "P0": "380.00",
            "P1": "380.00",
            "P2": "380.00",
            "P3": "380.00",
            "P4": "430.00",
            "P5": "430.00",
            "P6": "430.00",
            "P7": "480.00",
            "P8": "480.00",
        },
        "武汉": {
            "P0": "380.00",
            "P1": "380.00",
            "P2": "380.00",
            "P3": "380.00",
            "P4": "430.00",
            "P5": "430.00",
            "P6": "430.00",
            "P7": "480.00",
            "P8": "480.00",
        },
    },
    # 数据库规则资产尚未初始化时仍提供可审计的只读兜底；租户规则表加载后会覆盖这些值。
    "allowance_limits": {
        "meal": {
            "直辖市/特区": "65.00",
            "其他地区": "55.00",
            "新疆-乌鲁木齐": "75.00",
            "新疆-其他": "65.00",
            "西藏": "80.00",
            "港澳台": "120.00",
            "国外": "180.00",
        },
        "basic": {
            "直辖市/特区": "35.00",
            "其他地区": "35.00",
            "新疆-乌鲁木齐": "45.00",
            "新疆-其他": "40.00",
            "西藏": "50.00",
            "港澳台": "80.00",
            "国外": "120.00",
        },
        "total": {
            "直辖市/特区": "100.00",
            "其他地区": "90.00",
            "新疆-乌鲁木齐": "120.00",
            "新疆-其他": "105.00",
            "西藏": "130.00",
            "港澳台": "200.00",
            "国外": "300.00",
        },
    },
    "transport_limits": {
        "P0": {"flight": 1, "train": 1},
        "P1": {"flight": 1, "train": 1},
        "P2": {"flight": 1, "train": 1},
        "P3": {"flight": 1, "train": 1},
        "P4": {"flight": 1, "train": 1},
        "P5": {"flight": 1, "train": 1},
        "P6": {"flight": 2, "train": 2},
        "P7": {"flight": 3, "train": 3},
        "P8": {"flight": 4, "train": 3},
    },
    "flight_classes": [
        {"keyword": "头等舱", "level": 4},
        {"keyword": "公务舱", "level": 3},
        {"keyword": "商务舱", "level": 3},
        {"keyword": "超级经济舱", "level": 2},
        {"keyword": "高端经济舱", "level": 2},
        {"keyword": "明珠经济舱", "level": 2},
        {"keyword": "经济舱", "level": 1},
    ],
    "train_classes": [
        {"keyword": "商务座", "level": 3},
        {"keyword": "一等座", "level": 2},
        {"keyword": "软卧", "level": 2},
        {"keyword": "二等座", "level": 1},
        {"keyword": "二等卧", "level": 1},
        {"keyword": "硬卧", "level": 1},
    ],
}
