"""Tests for all agents with mocked Gemini calls.

Since agents use deferred `from google import genai` inside method bodies,
we mock the `google.genai` entry in sys.modules so the deferred import
picks up our mock.
"""
from __future__ import annotations

import sys
from unittest.mock import MagicMock, patch

import pytest

from job_search_agent.models import (
    InterviewQuestion,
    JobDescription,
    PortfolioSuggestion,
    TailoredCoverLetter,
    TailoredResume,
)


@pytest.fixture
def mock_genai_env():
    """Fixture that patches GEMINI_API_KEY and google.genai in sys.modules."""
    mock_genai_module = MagicMock()
    mock_client = MagicMock()
    mock_genai_module.Client.return_value = mock_client

    # Also ensure `google` parent module exists in sys.modules
    mock_google = MagicMock()
    mock_google.genai = mock_genai_module

    with patch.dict("os.environ", {"GEMINI_API_KEY": "test-key"}):
        with patch.dict("sys.modules", {"google": mock_google, "google.genai": mock_genai_module}):
            yield mock_genai_module, mock_client


class TestJobDescriptionParserAgent:
    def test_parse_returns_job_description(self, mock_genai_env):
        mock_genai, mock_client = mock_genai_env

        mock_job = JobDescription(
            raw_text="placeholder", title="Backend Engineer",
            company="Acme", required_skills=["Python", "Django"],
        )
        mock_response = MagicMock()
        mock_response.parsed = mock_job
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.jd_parser import JobDescriptionParserAgent
        agent = JobDescriptionParserAgent()
        result = agent.parse("We are hiring a Backend Engineer at Acme...")

        assert result.title == "Backend Engineer"
        assert result.raw_text == "We are hiring a Backend Engineer at Acme..."
        mock_client.models.generate_content.assert_called_once()

    def test_parse_with_title_override(self, mock_genai_env):
        mock_genai, mock_client = mock_genai_env

        mock_job = JobDescription(raw_text="placeholder", title="SomeTitle")
        mock_response = MagicMock()
        mock_response.parsed = mock_job
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.jd_parser import JobDescriptionParserAgent
        agent = JobDescriptionParserAgent()
        result = agent.parse("raw text", title_override="My Custom Title")

        assert result.title == "My Custom Title"


class TestResumeTailorAgent:
    def test_tailor_resume(self, mock_genai_env, sample_candidate, sample_job):
        mock_genai, mock_client = mock_genai_env

        mock_resume = TailoredResume(
            summary="Expert dev", highlighted_skills=["Python", "Django"],
            bullet_points=["Led team", "Cut latency"],
        )
        mock_response = MagicMock()
        mock_response.parsed = mock_resume
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.resume_tailor import ResumeTailorAgent
        agent = ResumeTailorAgent()
        result = agent.tailor_resume(sample_candidate, sample_job)

        assert result.summary == "Expert dev"
        assert len(result.highlighted_skills) == 2

    def test_tailor_cover_letter(self, mock_genai_env, sample_candidate, sample_job):
        mock_genai, mock_client = mock_genai_env

        mock_cover = TailoredCoverLetter(
            intro="Dear Hiring Manager", body="I bring experience...", closing="Best regards,",
        )
        mock_response = MagicMock()
        mock_response.parsed = mock_cover
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.resume_tailor import ResumeTailorAgent
        agent = ResumeTailorAgent()
        result = agent.tailor_cover_letter(sample_candidate, sample_job)

        assert "Dear" in result.intro


class TestPortfolioCoachAgent:
    def test_suggest(self, mock_genai_env, sample_candidate, sample_job):
        mock_genai, mock_client = mock_genai_env

        from job_search_agent.agents.portfolio_coach import PortfolioSuggestionsResponse
        mock_suggestions = PortfolioSuggestionsResponse(
            suggestions=[PortfolioSuggestion(title="Build X", description="A project", priority="high")]
        )
        mock_response = MagicMock()
        mock_response.parsed = mock_suggestions
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.portfolio_coach import PortfolioCoachAgent
        agent = PortfolioCoachAgent()
        results = agent.suggest(sample_candidate, sample_job)

        assert len(results) == 1
        assert results[0].priority == "high"


class TestInterviewCoachAgent:
    def test_create_session(self, mock_genai_env, sample_candidate, sample_job):
        mock_genai, mock_client = mock_genai_env

        from job_search_agent.agents.interview_coach import QuestionListResponse
        mock_questions = QuestionListResponse(
            questions=[
                InterviewQuestion(question="Tell me about yourself", category="behavioral", focus_areas=["communication"]),
                InterviewQuestion(question="Design a system", category="system_design", focus_areas=["scalability"]),
            ]
        )
        mock_response = MagicMock()
        mock_response.parsed = mock_questions
        mock_client.models.generate_content.return_value = mock_response

        from job_search_agent.agents.interview_coach import InterviewCoachAgent
        agent = InterviewCoachAgent()
        session = agent.create_session(sample_candidate, sample_job)

        assert len(session.turns) == 2
        assert session.turns[0].question.category == "behavioral"
