import re
from typing import Iterable, List, Optional


_NEGATIVE_FINANCE_STRONG = [
    "broke",
    "no money",
    "can't afford",
    "cannot afford",
    "out of money",
    "zero budget",
]
_NEGATIVE_FINANCE_SOFT = [
    "tight",
    "tight on money",
    "tight on cash",
    "strapped",
    "cash strapped",
    "low on cash",
    "low on money",
    "budget is tight",
    "price sensitive",
    "need to save",
]
_POSITIVE_FINANCE = [
    "no budget limit",
    "budget is flexible",
    "money is no object",
    "not price sensitive",
    "comfortable budget",
    "healthy budget",
]

_BUDGET_RE = re.compile(
    r"(?i)(?:\$\s*|usd\s*)?([0-9]{1,3}(?:[,0-9]{3})+|[0-9]+(?:\.[0-9]+)?)\s*(k|grand)?"
)


def detect_financial_sentiment(text: str) -> Optional[str]:
    if not text:
        return None
    t = text.lower()
    if any(term in t for term in _NEGATIVE_FINANCE_STRONG):
        return "broke"
    if any(term in t for term in _NEGATIVE_FINANCE_SOFT):
        return "tight"
    if any(term in t for term in _POSITIVE_FINANCE):
        return "comfortable"
    return None


def extract_budget_amounts(text: str) -> List[int]:
    if not text:
        return []
    amounts: List[int] = []
    for match in _BUDGET_RE.finditer(text):
        raw = match.group(1)
        suffix = (match.group(2) or "").lower()
        try:
            value = float(raw.replace(",", ""))
        except ValueError:
            continue
        if suffix in ("k", "grand"):
            value *= 1000
        if value < 100:
            continue
        amounts.append(int(round(value)))
    return amounts


def max_budget_amount(texts: Iterable[str]) -> Optional[int]:
    amounts: List[int] = []
    for t in texts:
        amounts.extend(extract_budget_amounts(t))
    return max(amounts) if amounts else None


def infer_os_preference(text: str) -> Optional[str]:
    if not text:
        return None
    t = text.lower()
    has_macos = any(k in t for k in ["macos", "mac", "macbook", "apple"])
    has_windows = any(k in t for k in ["windows", "pc", "surface", "thinkpad", "dell", "lenovo"])
    has_linux = "linux" in t or "ubuntu" in t
    picks = [p for p, ok in [("macos", has_macos), ("windows", has_windows), ("linux", has_linux)] if ok]
    if len(picks) == 1:
        return picks[0]
    return None


def is_dev_laptop_context(text: str) -> bool:
    if not text:
        return False
    t = text.lower()
    return any(
        k in t
        for k in [
            "laptop",
            "notebook",
            "macbook",
            "developer",
            "development",
            "dev laptop",
            "software engineer",
            "coding",
            "programming",
        ]
    )


_SENSITIVE_DOMAIN_KEYWORDS = {
    "finance": [
        "investment",
        "investing",
        "stock",
        "stocks",
        "equity",
        "crypto",
        "bitcoin",
        "portfolio",
        "roi",
        "returns",
        "yield",
        "bond",
        "forex",
        "trading",
        "private equity",
    ],
    "medical": [
        "diagnosis",
        "diagnose",
        "symptom",
        "symptoms",
        "treatment",
        "medication",
        "prescription",
        "doctor",
        "medical",
        "health",
        "therapy",
        "disease",
        "surgery",
    ],
    "legal": [
        "lawsuit",
        "legal",
        "attorney",
        "lawyer",
        "contract",
        "compliance",
        "regulation",
        "liability",
        "sue",
        "court",
        "trademark",
        "patent",
    ],
}


def detect_sensitive_domains(texts: Iterable[str]) -> List[str]:
    combined = " ".join([t for t in texts if t])
    if not combined:
        return []
    t = combined.lower()
    hits: List[str] = []
    for domain, keywords in _SENSITIVE_DOMAIN_KEYWORDS.items():
        if any(k in t for k in keywords):
            hits.append(domain)
    return hits
