from pathlib import Path

from email_enrichment.config import ProfileConfig
from email_enrichment.ingest import (
    collect_domain_known_pairs,
    normalize_domain,
    read_prospects,
)

FIXTURE = Path(__file__).resolve().parent / "fixtures" / "advmfr_sample.csv"
PROFILES_DIR = Path(__file__).resolve().parents[1] / "profiles"


def load_cfg():
    return ProfileConfig.load(PROFILES_DIR / "advmfr.yml")


def test_normalize_domain():
    assert normalize_domain("http://dasaninc.com/") == "dasaninc.com"
    assert normalize_domain("https://www.heyrowan.com/") == "heyrowan.com"
    assert normalize_domain("heyrowan.com") == "heyrowan.com"
    assert normalize_domain("") is None
    assert normalize_domain(None) is None


def test_read_prospects_count_and_fields():
    cfg = load_cfg()
    rows = read_prospects(FIXTURE, cfg)
    assert len(rows) == 5
    by_company = {r.company: r for r in rows}
    assert by_company["Dasan"].domain == "dasaninc.com"
    assert by_company["Sonara Jewelry"].domain == "sonarajewelry.com"
    assert by_company["Mejuri"].tier == "A"
    assert by_company["SHR Jewelry Group"].domain is None  # no website column value


def test_multi_contact_expansion_mejuri():
    cfg = load_cfg()
    rows = read_prospects(FIXTURE, cfg)
    mejuri = next(r for r in rows if r.company == "Mejuri")
    names = [(c.first, c.last) for c in mejuri.contacts]
    assert ("Majed", "Masad") in names
    assert ("Noura", "Sakkijha") in names
    assert ("Nicole", "Bautista") in names

    # Emails correctly attributed via first-name matching in the cell.
    majed = next(c for c in mejuri.contacts if c.first == "Majed")
    assert "majed@mejuri.com" in majed.known_emails

    noura = next(c for c in mejuri.contacts if c.first == "Noura")
    # Noura has two emails in the source — one corporate, one hotmail.
    # Corporate-only policy: hotmail is dropped at ingest, the corporate
    # address stays.
    assert "noura@mejuri.com" in noura.known_emails
    assert "noura_sakkijha@hotmail.com" not in noura.known_emails


def test_contact_with_zero_email():
    cfg = load_cfg()
    rows = read_prospects(FIXTURE, cfg)
    sonara = next(r for r in rows if r.company == "Sonara Jewelry")
    # No contact name in the cell → one anonymous Contact carrying the email.
    assert len(sonara.contacts) == 1
    assert sonara.contacts[0].full_name is None
    assert "sales@sonarajewelry.com" in sonara.contacts[0].known_emails


def test_linkedin_company_url_read_from_csv(tmp_path):
    """Optional LinkedIn Company URL column propagates to ProspectRow."""
    cfg = load_cfg()
    csv_path = tmp_path / "sample.csv"
    csv_path.write_text(
        "Company/Brand Name,Country,Note,Type of Product/Design,Contact Name,Email,Website,Tier,LinkedIn Company URL,Notes\n"
        "Dasan,New York,,,Jon Mitchell,jmitchell@dasaninc.com,http://dasaninc.com/,A,"
        "https://www.linkedin.com/company/dasan-inc/,\n"
        "Sonara,Los Angeles,,,,sales@sonarajewelry.com,https://sonarajewelry.com/,B,,\n",
        encoding="utf-8",
    )
    rows = read_prospects(csv_path, cfg)
    dasan = next(r for r in rows if r.company == "Dasan")
    assert dasan.linkedin_company_url == "https://www.linkedin.com/company/dasan-inc/"
    sonara = next(r for r in rows if r.company == "Sonara")
    assert sonara.linkedin_company_url is None


def test_collect_domain_pairs_excludes_personal():
    cfg = load_cfg()
    rows = read_prospects(FIXTURE, cfg)
    pairs = collect_domain_known_pairs(rows, set(cfg.personal_email_domains))
    assert "mejuri.com" in pairs
    emails = [e for e, _ in pairs["mejuri.com"]]
    assert "majed@mejuri.com" in emails
    # Personal hotmail.com should be excluded from pattern inference input.
    assert "hotmail.com" not in pairs


def test_unattributed_emails_do_not_pollute_named_contacts(tmp_path):
    """
    When the CSV cell has multiple contacts and multiple emails but no clear
    name-to-email mapping, unattributed emails MUST stay on extra_emails and
    NOT bleed into every named contact's known_emails. This was the real bug
    hit on Bauble Bar in the ADVMFR run.
    """
    cfg = load_cfg()
    csv_path = tmp_path / "sample.csv"
    csv_path.write_text(
        "Company/Brand Name,Country,Note,Type of Product/Design,Contact Name,Email,Website,Tier,Notes\n"
        'Bauble Bar Inc.,,,,"Ana C- Manager\n'
        'NicciCaton\n'
        'ErinSouder","jameschu1987@gmail.com\n'
        'nicci.caton@baublebar.com\n'
        'millerel0110@gmail.com",http://baublebar.com,A,\n',
        encoding="utf-8",
    )
    rows = read_prospects(csv_path, cfg)
    bauble = next(r for r in rows if r.company == "Bauble Bar Inc.")

    # nicci.caton@baublebar.com must be attributed to NicciCaton via
    # {first}.{last} pattern match, not to everyone.
    nicci = next(c for c in bauble.contacts if c.first == "Nicci")
    assert "nicci.caton@baublebar.com" in nicci.known_emails

    # Gmail emails are dropped at ingest under the corporate-only policy.
    # They're not in known_emails and not in extra_emails.
    ana = next(c for c in bauble.contacts if c.first == "Ana")
    assert ana.known_emails == []
    erin = next(c for c in bauble.contacts if c.first == "Erin")
    assert erin.known_emails == []
    assert "jameschu1987@gmail.com" not in bauble.extra_emails
    assert "millerel0110@gmail.com" not in bauble.extra_emails
    # Corporate-domain emails with no name-to-contact match stay in extra_emails.
    # (In this fixture, all corporate emails match a contact, so extra is empty.)
    assert bauble.extra_emails == []
