"""Tests for Pydantic model creation, validation, and serialization."""
from __future__ import annotations

from datetime import datetime

from job_search_agent.models import (
    ApplicationLog,
    BotConfig,
    CandidateProfile,
    InterviewQuestion,
    InterviewSession,
    InterviewTurn,
    JobDescription,
    MatchScore,
    PortfolioSuggestion,
    TailoredCoverLetter,
    TailoredResume,
)


class TestJobDescription:
    def test_minimal_creation(self):
        jd = JobDescription(raw_text="Build APIs", title="Dev")
        assert jd.title == "Dev"
        assert jd.required_skills == []
        assert jd.url is None

    def test_full_creation(self, sample_job):
        assert sample_job.company == "Acme Corp"
        assert len(sample_job.required_skills) == 3

    def test_serialization(self, sample_job):
        data = sample_job.model_dump()
        assert data["title"] == "Senior Backend Engineer"
        restored = JobDescription(**data)
        assert restored == sample_job


class TestCandidateProfile:
    def test_creation(self, sample_candidate):
        assert sample_candidate.name == "Jordan Doe"
        assert len(sample_candidate.skills) == 5

    def test_defaults(self):
        c = CandidateProfile(
            name="A", email="a@b.c", headline="Dev", years_experience=1, skills=["Go"]
        )
        assert c.industries == []
        assert c.portfolio_links == []


class TestTailoredResume:
    def test_creation(self):
        tr = TailoredResume(
            summary="Expert dev", highlighted_skills=["Python"], bullet_points=["Led project"]
        )
        assert tr.warnings == []


class TestTailoredCoverLetter:
    def test_creation(self):
        tc = TailoredCoverLetter(intro="Dear...", body="I have...", closing="Best,")
        assert tc.warnings == []


class TestPortfolioSuggestion:
    def test_creation(self):
        ps = PortfolioSuggestion(title="Build X", description="A project", priority="high")
        assert ps.priority == "high"


class TestInterviewModels:
    def test_question(self):
        q = InterviewQuestion(question="Tell me...", category="behavioral")
        assert q.focus_areas == []

    def test_turn(self):
        q = InterviewQuestion(question="Q?", category="tech")
        t = InterviewTurn(question=q)
        assert t.candidate_answer is None
        assert t.score is None

    def test_session(self, sample_job, sample_candidate):
        s = InterviewSession(job=sample_job, candidate=sample_candidate)
        assert len(s.turns) == 0
        assert isinstance(s.started_at, datetime)


class TestMatchScore:
    def test_creation(self):
        ms = MatchScore(score=85, reasoning="Great fit", apply_recommendation=True)
        assert ms.score == 85
        assert ms.apply_recommendation is True


class TestApplicationLog:
    def test_creation(self):
        al = ApplicationLog(action="APPLIED", job_title="Dev", status="SUBMITTED")
        assert al.action == "APPLIED"
        assert isinstance(al.timestamp, datetime)

    def test_serialization(self):
        al = ApplicationLog(action="SCORED", job_title="SRE", score=72, status="OK")
        data = al.model_dump_json()
        assert "SCORED" in data


class TestBotConfig:
    def test_defaults(self):
        bc = BotConfig()
        assert bc.query == "software engineer"
        assert bc.min_score == 60
        assert "remoteok" in bc.sources

    def test_custom(self):
        bc = BotConfig(query="python", interval_minutes=5, min_score=80)
        assert bc.interval_minutes == 5
