"""Shared prohibited-content boundary for nutrition model output."""

from __future__ import annotations

import re
from typing import Final, Iterable
import unicodedata


_PROHIBITED_PHRASES: Final = (
    "처방약",
    "약물",
    "호르몬",
    "탈수",
    "진단",
    "의료진 지시를 무시",
    "응급실에 가지",
)
_MEDICATION_ACTION: Final = re.compile(
    r"(?:복용\s*중인\s*약|처방약|처방\s*받(?:은|고|았)|"
    r"약물|호르몬제?|인슐린|"
    r"혈압약|당뇨약|약(?!속))"
    r"(?:은|는|을|를)?"
    r".{0,24}(?:중단|끊|먹지|드시지|복용하지|피하|투여|주사|"
    r"증량|감량|늘리|줄이|두\s*배|용량.{0,8}(?:변경|조절))"
)
_STARVATION_ACTION: Final = re.compile(
    r"(?:굶|식사.{0,12}(?:전부\s*)?(?:끊|중단)|"
    r"아무것도.{0,12}(?:먹지|드시지)|"
    r"(?:물|수분).{0,12}(?:마시지|입에.{0,4}대지|"
    r"섭취.{0,8}(?:하지|말)|끊|중단))"
)
_EMERGENCY_CARE_BYPASS: Final = re.compile(
    r"(?:응급|긴급|위급|구급대|119).{0,48}(?:"
    r"(?:신고|연락|119|도움|의료진|구급대).{0,16}(?:하지|말|피하)|"
    r"(?:병원|응급실|의료기관).{0,16}"
    r"(?:가지\s*마|방문하지|연락하지|피하))"
)
_ENGLISH_MEDICATION_ACTION: Final = re.compile(
    r"(?:stop|discontinue|quit|avoid|skip|do\s*not)\b.{0,32}"
    r"(?:medication|medicine|prescription|insulin|hormone|"
    r"blood\s*pressure\s*(?:medication|medicine)|diabetes\s*(?:medication|medicine))"
)
_ENGLISH_DEHYDRATION_ACTION: Final = re.compile(
    r"(?:drink\s*no\s*water|do\s*not\s*drink\s*(?:any\s*)?(?:water|fluids?)|"
    r"avoid\s*(?:all\s*)?(?:water|fluids?))"
)
_ENGLISH_EMERGENCY_BYPASS: Final = re.compile(
    r"(?:do\s*not|never|avoid).{0,24}"
    r"(?:contact|call|seek|visit|go\s*to).{0,24}"
    r"(?:emergency|ambulance|hospital|doctor|medical\s*care|911)"
)
_SPACED_ASCII_SEQUENCE: Final = re.compile(
    r"(?<![a-z])(?:[a-z]\s+){2,}[a-z](?![a-z])"
)
_CREDENTIAL_ACTION: Final = re.compile(
    r"(?:계정\s*)?(?:비밀번호|인증번호|보안\s*코드|"
    r"주민등록번호|접근\s*토큰).{0,32}"
    r"(?:보내|공유|알려|입력|제출)"
)
_CUSTOMER_IDENTITY: Final = re.compile(
    r"(?<![가-힣A-Za-z])"
    r"(?P<name>[가-힣]{2,4}|[A-Za-z][A-Za-z .'-]{1,40})"
    r"\s*고객님"
)
_SENSITIVE_FACT_TERMS: Final = (
    "알레르기",
    "임신",
    "당뇨",
    "고혈압",
    "갑상선",
    "신장 질환",
    "간 질환",
    "심장 질환",
    "질환",
)


def contains_prohibited_nutrition_guidance(value: object) -> bool:
    """Return whether model-authored text crosses the nutrition safety boundary."""
    if type(value) is not str:
        return False
    normalized = "".join(
        character
        for character in unicodedata.normalize("NFKC", value).casefold()
        if unicodedata.category(character) != "Cf"
    )
    normalized = _SPACED_ASCII_SEQUENCE.sub(
        lambda match: re.sub(r"\s+", "", match.group()),
        normalized,
    )
    compact = re.sub(r"\s+", "", normalized)
    return any(term in normalized for term in _PROHIBITED_PHRASES) or bool(
        any(
            pattern.search(candidate)
            for candidate in (normalized, compact)
            for pattern in (
                _MEDICATION_ACTION,
                _STARVATION_ACTION,
                _EMERGENCY_CARE_BYPASS,
                _CREDENTIAL_ACTION,
            )
        )
        or _ENGLISH_MEDICATION_ACTION.search(normalized)
        or _ENGLISH_DEHYDRATION_ACTION.search(normalized)
        or _ENGLISH_EMERGENCY_BYPASS.search(normalized)
    )


def contains_unsupported_sensitive_fact(
    value: object,
    sources: Iterable[str],
) -> bool:
    """Reject sensitive factual domains absent from validated source copy."""
    if type(value) is not str:
        return False
    source_text = tuple(sources)
    if any(
        term in value
        and not any(term in source for source in source_text)
        for term in _SENSITIVE_FACT_TERMS
    ):
        return True
    return any(
        not any(match.group(0) in source for source in source_text)
        for match in _CUSTOMER_IDENTITY.finditer(value)
    )
