from email_enrichment.naming import parse_name
from email_enrichment.patterns import (
    _is_role_account_local,
    infer_domain_pattern,
    infer_pattern_from_local_parts,
    match_pattern,
    render,
)


def test_render_first_last():
    name = parse_name("Jon Mitchell")
    assert render("{first}.{last}", name) == "jon.mitchell"
    assert render("{first}", name) == "jon"
    assert render("{f}{last}", name) == "jmitchell"
    assert render("{first}{l}", name) == "jonm"


def test_render_missing_name_returns_none():
    name = parse_name("Cher")
    assert name.first and not name.last
    assert render("{first}.{last}", name) is None
    assert render("{first}", name) == "cher"


def test_match_pattern_known_cases():
    # Mejuri: majed@mejuri.com → {first}
    assert match_pattern("majed", parse_name("Majed Masad")) == "{first}"
    # noura_sakkijha@hotmail.com (personal) → {first}_{last}
    assert match_pattern("noura_sakkijha", parse_name("Noura Sakkijha")) == "{first}_{last}"
    # jmitchell@dasaninc.com → {f}{last}
    assert match_pattern("jmitchell", parse_name("Jon Mitchell")) == "{f}{last}"


def test_infer_pattern_mejuri_like():
    # Multiple employees at mejuri.com: majed@, noura@, nicole@, ailey@
    # → pattern {first}
    hits = [
        ("majed@mejuri.com", parse_name("Majed Masad")),
        ("noura@mejuri.com", parse_name("Noura Sakkijha")),
        ("nicole@mejuri.com", parse_name("Nicole Bautista")),
        ("ailey@mejuri.com", parse_name("Ailey Joung")),
    ]
    assert infer_domain_pattern(hits) == "{first}"


def test_infer_pattern_f_last():
    # jmitchell@dasaninc.com fits {f}{last}
    hits = [
        ("jmitchell@dasaninc.com", parse_name("Jon Mitchell")),
    ]
    assert infer_domain_pattern(hits) == "{f}{last}"


def test_infer_pattern_no_match_returns_none():
    # Name doesn't match email local-part at all.
    hits = [
        ("info@example.com", parse_name("Charlie Chaplin")),
    ]
    assert infer_domain_pattern(hits) is None


def test_infer_pattern_rowan_first_only():
    # d'arcy@heyrowan.com, lynda@heyrowan.com, amanda@heyrowan.com
    # Only the first-name parts are in the email → {first}
    hits = [
        ("lynda@heyrowan.com", parse_name("Lynda Johnson")),
        ("amanda@heyrowan.com", parse_name("Amanda Miller")),
    ]
    assert infer_domain_pattern(hits) == "{first}"


def test_role_account_detection():
    for local in ("info", "contact", "sales", "helpme", "corpfin",
                  "euprivacy", "investorrelations", "noreply", "do-not-reply"):
        assert _is_role_account_local(local), local
    for local in ("jmitchell", "natalie.wiley", "john", "j.doe"):
        assert not _is_role_account_local(local), local


def test_shape_infer_first_dot_last():
    # Harvested from GitHub on brilliantearth.com — real data.
    locals_ = [
        "natalie.wiley", "mickey.avila",
        "info", "corpfin", "investorrelations",  # role accounts ignored
    ]
    assert infer_pattern_from_local_parts(locals_) == "{first}.{last}"


def test_shape_infer_first_only():
    locals_ = ["majed", "noura", "nicole", "ailey", "info"]
    assert infer_pattern_from_local_parts(locals_) == "{first}"


def test_shape_infer_ambiguous_single_tokens_default_to_first():
    # Single-token local-parts are ambiguous (jmith could be {f}{last} or
    # {first}). We default to {first} — callers can still fall back to the
    # profile's default_patterns for {f}{last}.
    locals_ = ["jmith", "bhart", "info"]
    assert infer_pattern_from_local_parts(locals_) == "{first}"


def test_shape_infer_none_without_enough_signal():
    assert infer_pattern_from_local_parts([]) is None
    assert infer_pattern_from_local_parts(["info", "sales"]) is None  # all role
    assert infer_pattern_from_local_parts(["jane.doe"]) is None  # single sample


def test_shape_infer_underscore_pattern():
    locals_ = ["jane_doe", "john_smith", "info"]
    assert infer_pattern_from_local_parts(locals_) == "{first}_{last}"
