import pytest

from autoshorts.ideas.candidate import VideoCandidate
from autoshorts.scripting.quality import ScriptQualityScore
from autoshorts.strategy.score import (
    ContentStrategyScore,
    StrategySignal,
    build_candidate_strategy_review,
    should_advance_strategy,
    validate_content_strategy_score,
)


def _candidate(**overrides):
    values = {
        "candidate_id": "delivery-sms-trap-35s",
        "pillar": "text_delivery_scams",
        "title": "Delivery SMS Trap",
        "platforms": ("youtube", "tiktok", "instagram"),
        "duration_seconds": 35,
        "hook": "This delivery text is designed to make you panic.",
        "script_outline": "Show a fake delivery SMS, reveal the pressure, then show the safer move: do not tap the link; open the app yourself.",
        "visual_concept": "Phone SMS screen with tiny fee, short deadline, suspicious link, and SAVE THIS checklist.",
        "caption": "If it makes you hurry, slow down.",
        "cta": "Follow for one red flag before you click. Send this to family.",
        "hashtags": ("#ScamAwareness", "#CyberSafety", "#DigitalRedFlags"),
        "quality_score": ScriptQualityScore(
            hook_strength=9,
            novelty=8,
            clarity=9,
            retention=8,
            ai_slop_risk=2,
            policy_risk="low",
        ),
        "policy_notes": ("duration_class:growth_short", "series:One Screen. One Red Flag."),
        "hypothesis": "A familiar delivery SMS red flag earns saves and family shares.",
    }
    values.update(overrides)
    return VideoCandidate(**values)


def test_content_strategy_score_validates_complete_beginner_safety_score():
    score = ContentStrategyScore(
        hook=StrategySignal(9, "Names a visible scam screen immediately."),
        curiosity=StrategySignal(8, "Viewer wants to know the one red flag."),
        identity=StrategySignal(9, "For normal smartphone users."),
        emotion=StrategySignal(8, "Warned but in control."),
        trust=StrategySignal(9, "Gives one safer move."),
        follow_reason=StrategySignal(9, "Repeatable one-screen red flag promise."),
        originality=StrategySignal(8, "Specific screen, not generic advice."),
        variety=StrategySignal(8, "Fresh enough."),
        target_emotion="warned but in control",
        viewer_identity="normal smartphone/internet users",
        future_value_promise="one red flag before you click, pay, scan, or log in",
        format_family="One Screen. One Red Flag.",
        variation_axis="screen + red flag + safer move",
    )

    result = validate_content_strategy_score(score)

    assert result.is_valid is True
    assert score.average_score == pytest.approx(8.5)
    assert should_advance_strategy(score) is True


def test_content_strategy_score_rejects_low_follow_reason_even_with_good_hook():
    score = ContentStrategyScore(
        hook=StrategySignal(9, "Strong visible problem."),
        curiosity=StrategySignal(8, "Specific open loop."),
        identity=StrategySignal(7, "Somewhat targeted."),
        emotion=StrategySignal(8, "Useful concern."),
        trust=StrategySignal(8, "Specific example."),
        follow_reason=StrategySignal(4, "Could belong to any tips account."),
        originality=StrategySignal(8, "Specific."),
        variety=StrategySignal(8, "Fresh enough."),
        target_emotion="warned",
        viewer_identity="normal users",
        future_value_promise="more tips",
        format_family="One Screen. One Red Flag.",
        variation_axis="generic tip",
    )

    result = validate_content_strategy_score(score)

    assert result.is_valid is False
    assert "follow_reason must be at least 7" in result.errors
    assert should_advance_strategy(score) is False


def test_build_candidate_strategy_review_blocks_generic_ai_slop_language():
    candidate = _candidate(
        title="5 AI tools you need right now",
        hook="In this video I will show you the best AI tools to unlock your potential.",
        script_outline="Here are 5 amazing AI tools everyone should use.",
        visual_concept="Generic AI stock footage and floating robot icons.",
        caption="Unlock your full potential with these AI tools.",
        cta="Follow for more AI tips.",
        policy_notes=("duration_class:growth_short",),
    )

    review = build_candidate_strategy_review(candidate)

    assert review.render_allowed is False
    assert "generic AI-slop language detected" in review.reject_reasons
    assert "pretty-empty visual blocker: first screen/red flag is not clear" in review.reject_reasons


def test_build_candidate_strategy_review_blocks_forbidden_public_topics():
    candidate = _candidate(
        title="How JARVIS and the user built this approval workflow",
        hook="This is the private collaboration behind the content machine.",
        script_outline="Show our JARVIS build log and personal workflow.",
        visual_concept="Private screenshots and internal chat timeline.",
        caption="Our collaboration is the moat.",
        cta="Follow for the next JARVIS build log.",
        policy_notes=("series:jarvis_build_log",),
    )

    review = build_candidate_strategy_review(candidate)

    assert review.render_allowed is False
    assert "candidate uses forbidden public topic: jarvis" in review.reject_reasons
    assert "candidate uses forbidden public topic: collaboration" in review.reject_reasons
    assert "candidate uses forbidden public topic: private" in review.reject_reasons


def test_build_candidate_strategy_review_allows_specific_scam_self_defense_candidate():
    candidate = _candidate()

    review = build_candidate_strategy_review(
        candidate,
        recent_format_families=("Account Trap", "Money Move Red Flags"),
    )

    assert review.render_allowed is True
    assert review.strategy_score.format_family == "Before You Click"
    assert review.strategy_score.viewer_identity == "normal smartphone/internet users"
    assert review.reject_reasons == ()
    assert review.improvement_suggestions == ()


def test_build_candidate_strategy_review_blocks_jargon_and_missing_safe_move():
    candidate = _candidate(
        hook="This phishing attempt leverages urgency-based social engineering.",
        script_outline="Explain the attack vector and credential harvesting risk.",
        visual_concept="Abstract hacker background without a phone, message, or app screen.",
        caption="Validate the authenticity of the communication channel.",
        cta="Stay secure.",
    )

    review = build_candidate_strategy_review(candidate)

    assert review.render_allowed is False
    assert "language is too technical for normal users" in review.reject_reasons
    assert "safe move clarity is missing" in review.reject_reasons
