"""
PII (Personally Identifiable Information) 脱敏处理器

处理对象：姓名、手机号、身份证号、证书编号、邮箱等个人身份信息
"""

import re
from typing import Any, Optional
from .base_processor import BaseDesensitizer


class PIIDesensitizer(BaseDesensitizer):
    """PII 脱敏处理器"""

    def _compile_patterns(self):
        """编译 PII 相关正则表达式"""
        # 手机号：1[3-9]开头的11位数字
        self.patterns["phone"] = re.compile(r'\b1[3-9]\d{9}\b')

        # 身份证号：18位（15位已淘汰，暂不处理）
        self.patterns["id_card"] = re.compile(r'\b\d{17}[\dXx]\b')

        # 邮箱
        self.patterns["email"] = re.compile(
            r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
        )

        # 证书编号（特种作业资格证等）：省份简称+字母+数字
        # 如：京A202401001
        self.patterns["cert"] = re.compile(
            r'[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤川青藏琼宁][A-Z]\d{6,12}'
        )

        # 人名识别（中文姓名，2-4个字，位于特定上下文）
        # 如"项目经理张三"、"负责人：李四"
        self.patterns["person_with_role"] = re.compile(
            r'(项目经理|负责人|安全员|技术负责人|班组长|施工员|质检员)[：:\s]*([\u4e00-\u9fa5]{2,4})'
        )

        # 独立人名（更宽松，结合上下文判断）
        # 位于句首或特定连接词后
        self.patterns["person_standalone"] = re.compile(
            r'(?:^|[，。；\n])([\u4e00-\u9fa5]{2,3})(?:负责|主持|编制|审核|审批)'
        )

        # 审批签字行：姓名 + 日期
        self.patterns["signature"] = re.compile(
            r'([\u4e00-\u9fa5]{2,4})\s*20\d{2}[年./]\d{1,2}[月./]\d{1,2}[日]?'
        )

    def process(self, content: str, registry: Any, strict_mode: bool = False) -> str:
        """执行 PII 脱敏

        Args:
            content: 输入文本
            registry: 实体注册表，用于维护人名映射一致性
            strict_mode: 严格模式，确保所有匹配项都被处理
        """
        # 1. 手机号脱敏
        content = self.patterns["phone"].sub('[手机号脱敏]', content)

        # 2. 身份证号脱敏
        content = self.patterns["id_card"].sub('[证件号脱敏]', content)

        # 3. 证书编号脱敏
        content = self.patterns["cert"].sub('[证件号脱敏]', content)

        # 4. 邮箱脱敏
        content = self.patterns["email"].sub('[邮箱脱敏]', content)

        # 5. 带角色的人名脱敏（如"项目经理张三"）
        def replace_person_with_role(match):
            role = match.group(1)
            name = match.group(2)
            # 映射角色到标准占位符类型
            role_map = {
                '项目经理': '项目经理',
                '负责人': '负责人',
                '安全员': '安全员',
                '技术负责人': '技术负责人',
                '班组长': '班组长',
                '施工员': '施工员',
                '质检员': '质检员'
            }
            placeholder = registry.register_person(name, role_map.get(role, '人员'))
            return f"{role}：{placeholder}" if '：' in match.group(0) else f"{role}{placeholder}"

        content = self.patterns["person_with_role"].sub(replace_person_with_role, content)

        # 6. 审批签字脱敏
        def replace_signature(match):
            return '[已审核]'
        content = self.patterns["signature"].sub(replace_signature, content)

        # 7. 独立人名脱敏（严格模式下更激进）
        if strict_mode:
            def replace_standalone_person(match):
                name = match.group(1)
                placeholder = registry.register_person(name, "人员")
                return match.group(0).replace(name, placeholder)
            content = self.patterns["person_standalone"].sub(replace_standalone_person, content)

        return content

    def extract_persons(self, content: str) -> list:
        """提取文本中的所有人名（用于预分析）"""
        persons = []

        # 提取带角色的人名
        for match in self.patterns["person_with_role"].finditer(content):
            persons.append({
                "name": match.group(2),
                "role": match.group(1),
                "position": match.span()
            })

        return persons
