from autoshorts.ideas.candidate import VideoCandidate
from autoshorts.scripting.quality import ScriptQualityScore
from autoshorts.strategy.series import (
    DEFAULT_CONTENT_SERIES,
    ContentSeries,
    find_series,
    validate_candidate_series_fit,
    validate_content_series_registry,
)


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 text, reveal the pressure, and tell viewers to open the app themselves.",
        "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.",
        "hashtags": ("#ScamAwareness", "#CyberSafety", "#DigitalRedFlags"),
        "quality_score": ScriptQualityScore(9, 8, 9, 8, 2, "low"),
        "policy_notes": ("series:one_screen_one_red_flag",),
        "hypothesis": "One visible red flag and one safer move can earn saves and family shares.",
    }
    values.update(overrides)
    return VideoCandidate(**values)


def test_default_series_registry_contains_public_safe_scam_self_defense_series_only():
    result = validate_content_series_registry(DEFAULT_CONTENT_SERIES)

    assert result.is_valid is True
    series_ids = {series.series_id for series in DEFAULT_CONTENT_SERIES}
    assert {
        "one_screen_one_red_flag",
        "send_this_to_your_parents",
        "before_you_click",
        "money_move_red_flags",
        "account_trap",
    }.issubset(series_ids)
    assert {
        "prompt_vs_system",
        "ai_system_autopsy",
        "one_rule_one_example",
        "ai_hype_court",
    }.issubset(series_ids)  # legacy secondary series retained for existing pipeline/tests
    assert "jarvis_build_log" not in series_ids


def test_series_registry_rejects_duplicate_ids_and_forbidden_public_topics():
    unsafe = ContentSeries(
        series_id="jarvis_build_log",
        name="The JARVIS Build Log",
        promise="Publicly discuss JARVIS and the user's collaboration.",
        audience="AI builders",
        allowed_hook_types=("build_log",),
        format_rules=("Mention JARVIS and the user's workflow.",),
        visual_grammar=("private build log",),
        no_go_patterns=("politics",),
        follow_reason="Watch the private collaboration evolve.",
    )

    result = validate_content_series_registry((unsafe, unsafe))

    assert result.is_valid is False
    assert "duplicate series_id: jarvis_build_log" in result.errors
    assert "series jarvis_build_log uses forbidden public topic: jarvis" in result.errors
    assert "series jarvis_build_log uses forbidden public topic: collaboration" in result.errors


def test_candidate_series_fit_accepts_matching_public_safe_candidate():
    candidate = _candidate()

    result = validate_candidate_series_fit(candidate, "one_screen_one_red_flag")

    assert result.is_valid is True


def test_candidate_series_fit_accepts_before_you_click_candidate():
    candidate = _candidate(
        hook="Before you tap the tracking link, check this.",
        script_outline="Show the SMS link and safer move: open the app yourself.",
        visual_concept="Phone text screen with link and app icon path.",
    )

    result = validate_candidate_series_fit(candidate, "before_you_click")

    assert result.is_valid is True


def test_candidate_series_fit_rejects_public_content_about_jarvis_or_user_collaboration():
    candidate = _candidate(
        title="How JARVIS and my user built a content machine",
        hook="This is how our collaboration works behind the scenes.",
        script_outline="Explain JARVIS, the user, and private approval workflow details.",
        visual_concept="Private chat screenshots and build log.",
        caption="Our JARVIS collaboration is the secret.",
        cta="Follow to watch us build it live.",
    )

    result = validate_candidate_series_fit(candidate, "one_screen_one_red_flag")

    assert result.is_valid is False
    assert "candidate uses forbidden public topic: jarvis" in result.errors
    assert "candidate uses forbidden public topic: collaboration" in result.errors
    assert "candidate uses forbidden public topic: private" in result.errors


def test_candidate_series_fit_rejects_politics_and_legal_or_moral_risk():
    candidate = _candidate(
        title="Political scam system",
        hook="This legal loophole lets you scrape private data for campaigns.",
        script_outline="Explain how to bypass platform rules and influence voters.",
        visual_concept="Campaign dashboard and private data map.",
        caption="Use this loophole before it is banned.",
        cta="Try this campaign hack.",
    )

    result = validate_candidate_series_fit(candidate, "one_screen_one_red_flag")

    assert result.is_valid is False
    assert "candidate uses forbidden public topic: politics" in result.errors
    assert "candidate uses forbidden public topic: legal loophole" in result.errors
    assert "candidate uses forbidden public topic: private data" in result.errors
    assert "candidate uses forbidden public topic: bypass" in result.errors


def test_candidate_series_fit_rejects_unknown_series():
    result = validate_candidate_series_fit(_candidate(), "missing_series")

    assert result.is_valid is False
    assert "unknown series: missing_series" in result.errors
