"""Tests for the two-phase email flow: review-required notice, then final report."""

import threading

import backend.jobs
from backend.email_sender import send_review_required


class _SyncThread:
    """Drop-in threading.Thread replacement that runs the target inline."""

    def __init__(self, target=None, args=(), **kwargs):
        self._target = target
        self._args = args

    def start(self):
        self._target(*self._args)


def test_review_required_email_skips_without_smtp(monkeypatch):
    monkeypatch.setattr("backend.email_sender._smtp_ready", lambda: False)
    assert send_review_required("user@example.com", {"source": "set.pdf", "summary": {}}, "http://localhost:8099/?job=abc") is False


def test_review_required_email_sends_with_smtp(monkeypatch):
    """With SMTP ready, the message goes out with recipient, review URL, and
    the required-item count (0 when the report has no review summary)."""
    sent = []
    monkeypatch.setattr("backend.email_sender._smtp_ready", lambda: True)
    monkeypatch.setattr("backend.email_sender._send",
                        lambda msg: sent.append(msg) or True)

    review_url = "http://localhost:8099/?job=abc"
    report = {"source": "set.pdf", "summary": {"review": {"required": 3}}}
    assert send_review_required("user@example.com", report, review_url) is True

    assert len(sent) == 1
    msg = sent[0]
    assert msg["To"] == "user@example.com"
    assert "review" in msg["Subject"].lower()
    body = msg.get_content()
    assert "review" in body.lower()
    assert review_url in body
    assert "3" in body

    # Missing review summary -> required count defaults to 0.
    sent.clear()
    assert send_review_required("user@example.com", {"source": "set.pdf", "summary": {}}, review_url) is True
    assert "0" in sent[0].get_content()


def test_agent_needs_review_sends_review_email_not_report(monkeypatch, tmp_path):
    """An agent job entering needs_review emails the review-required notice
    exactly once and never sends the final conflict report."""
    review_emails = []
    report_emails = []
    monkeypatch.setattr("backend.config.OUTPUT_DIR", str(tmp_path))
    monkeypatch.setattr("backend.jobs.run_agent_pipeline", lambda pdf_path, **kw: {
        "summary": {"agent_status": "needs_review"}, "conflicts": [],
    })
    monkeypatch.setattr("backend.jobs.send_review_required",
                        lambda *a, **kw: review_emails.append((a, kw)))
    monkeypatch.setattr("backend.jobs.send_conflict_report",
                        lambda *a, **kw: report_emails.append((a, kw)))
    monkeypatch.setattr(threading, "Thread", _SyncThread)

    pdf = tmp_path / "upload.pdf"
    pdf.write_bytes(b"%PDF-1.4 dummy")
    job_id = backend.jobs.create_job(str(pdf), source_filename="set.pdf",
                                     email="arch@example.com", pipeline_mode="agent")
    try:
        job = backend.jobs.get_job(job_id)
        assert job["status"] == "needs_review"
        assert len(review_emails) == 1
        args, _ = review_emails[0]
        assert args[0] == "arch@example.com"
        assert f"/?job={job_id}" in args[2]
        assert report_emails == []
    finally:
        backend.jobs._jobs.pop(job_id, None)


def test_classic_job_sends_only_conflict_report(monkeypatch, tmp_path):
    """Classic pipeline is untouched: only the final report email fires."""
    review_emails = []
    report_emails = []
    monkeypatch.setattr("backend.config.OUTPUT_DIR", str(tmp_path))
    monkeypatch.setattr("backend.jobs.run_pipeline", lambda pdf_path, **kw: {
        "summary": {}, "conflicts": [],
    })
    monkeypatch.setattr("backend.jobs.send_review_required",
                        lambda *a, **kw: review_emails.append((a, kw)))
    monkeypatch.setattr("backend.jobs.send_conflict_report",
                        lambda *a, **kw: report_emails.append((a, kw)))
    monkeypatch.setattr(threading, "Thread", _SyncThread)

    pdf = tmp_path / "upload.pdf"
    pdf.write_bytes(b"%PDF-1.4 dummy")
    job_id = backend.jobs.create_job(str(pdf), source_filename="set.pdf",
                                     email="arch@example.com", pipeline_mode="classic")
    try:
        assert backend.jobs.get_job(job_id)["status"] == "done"
        assert len(report_emails) == 1
        assert review_emails == []
    finally:
        backend.jobs._jobs.pop(job_id, None)
