# tests/test_sync.py
from unittest.mock import patch, MagicMock


SAMPLE_FM = {
    "title_field": "Salary", "job_title": "Job Title", "company": "Company Name",
    "url": "Role Link", "source": "Job Source", "status": "Status of Application",
    "status_new": "Application Submitted", "date_found": "Date Found",
    "remote": "Remote", "match_score": "Match Score",
    "keyword_gaps": "Keyword Gaps", "notes": "Notes", "job_description": "Job Description",
}

SAMPLE_NOTION_CFG = {"token": "secret_test", "database_id": "fake-db-id", "field_map": SAMPLE_FM}


def test_sync_pushes_approved_jobs(tmp_path):
    """sync_to_notion pushes approved jobs and marks them synced."""
    from scripts.sync import sync_to_notion
    from scripts.db import init_db, insert_job, get_jobs_by_status, update_job_status

    db_path = tmp_path / "test.db"
    init_db(db_path)
    row_id = insert_job(db_path, {
        "title": "CSM", "company": "Acme", "url": "https://example.com/1",
        "source": "linkedin", "location": "Remote", "is_remote": True,
        "salary": "$100k", "description": "Good role", "date_found": "2026-02-20",
    })
    update_job_status(db_path, [row_id], "approved")

    mock_notion = MagicMock()
    mock_notion.pages.create.return_value = {"id": "notion-page-abc"}

    with patch("scripts.sync.load_notion_config", return_value=SAMPLE_NOTION_CFG), \
         patch("scripts.sync.Client", return_value=mock_notion):
        count = sync_to_notion(db_path=db_path)

    assert count == 1
    mock_notion.pages.create.assert_called_once()
    synced = get_jobs_by_status(db_path, "synced")
    assert len(synced) == 1


def test_sync_falls_back_to_core_fields_on_validation_error(tmp_path):
    """When Notion returns a validation_error (missing column), sync retries without optional fields."""
    from scripts.sync import sync_to_notion
    from scripts.db import init_db, insert_job, get_jobs_by_status, update_job_status

    db_path = tmp_path / "test.db"
    init_db(db_path)
    row_id = insert_job(db_path, {
        "title": "CSM", "company": "Acme", "url": "https://example.com/2",
        "source": "linkedin", "location": "Remote", "is_remote": True,
        "salary": "", "description": "", "date_found": "2026-02-20",
    })
    update_job_status(db_path, [row_id], "approved")

    mock_notion = MagicMock()
    # First call raises validation_error; second call (fallback) succeeds
    mock_notion.pages.create.side_effect = [
        Exception("validation_error: Could not find property with name: Match Score"),
        {"id": "notion-page-fallback"},
    ]

    with patch("scripts.sync.load_notion_config", return_value=SAMPLE_NOTION_CFG), \
         patch("scripts.sync.Client", return_value=mock_notion):
        count = sync_to_notion(db_path=db_path)

    assert count == 1
    assert mock_notion.pages.create.call_count == 2
    synced = get_jobs_by_status(db_path, "synced")
    assert len(synced) == 1


def test_sync_returns_zero_when_nothing_approved(tmp_path):
    """sync_to_notion returns 0 when there are no approved jobs."""
    from scripts.sync import sync_to_notion
    from scripts.db import init_db

    db_path = tmp_path / "test.db"
    init_db(db_path)

    with patch("scripts.sync.load_notion_config", return_value=SAMPLE_NOTION_CFG), \
         patch("scripts.sync.Client"):
        count = sync_to_notion(db_path=db_path)

    assert count == 0
