"""hook_scorer.py 단위 테스트"""
import importlib.util
import sys
from pathlib import Path

# hook_scorer를 직접 모듈로 로드 (상대 임포트 우회)
PIPELINE_DIR = Path(__file__).parent.parent
spec = importlib.util.spec_from_file_location("hook_scorer", PIPELINE_DIR / "hook_scorer.py")
assert spec is not None and spec.loader is not None
hook_scorer = importlib.util.module_from_spec(spec)
sys.modules["hook_scorer"] = hook_scorer
spec.loader.exec_module(hook_scorer)

detect_emotions = hook_scorer.detect_emotions
check_non_round_numbers = hook_scorer.check_non_round_numbers
check_round_numbers = hook_scorer.check_round_numbers
check_company_mentions = hook_scorer.check_company_mentions
score = hook_scorer.score


# ── 감정 감지 테스트 ───────────────────────────────────────────

class TestDetectEmotions:
    def test_detect_anger(self):
        """분노 키워드 포함 텍스트 → anger=True"""
        text = "이게 말이 됩니까? 도대체 왜 이러면 안 되는 건지"
        result = detect_emotions(text)
        assert result["anger"] is True

    def test_detect_surprise(self):
        """놀라움 키워드 포함 → surprise=True"""
        text = "진짜? 이게 실화냐 완전 충격이다"
        result = detect_emotions(text)
        assert result["surprise"] is True

    def test_detect_empathy(self):
        """공감 키워드 포함 → empathy=True"""
        text = "나도 겪어본 적 있어. 공감 백배"
        result = detect_emotions(text)
        assert result["empathy"] is True

    def test_detect_fear(self):
        """두려움 키워드 포함 → fear=True"""
        text = "안 하면 진짜 큰일 나고 모르면 손해다"
        result = detect_emotions(text)
        assert result["fear"] is True

    def test_detect_curiosity(self):
        """호기심 키워드 포함 → curiosity=True"""
        text = "아무도 안 알려주는 비밀이 있다"
        result = detect_emotions(text)
        assert result["curiosity"] is True

    def test_no_emotions(self):
        """감정 없는 평범한 텍스트 → 모두 False"""
        text = "오늘 날씨가 맑습니다. 기온은 20도입니다."
        result = detect_emotions(text)
        assert result["anger"] is False
        assert result["surprise"] is False
        assert result["empathy"] is False
        assert result["fear"] is False
        assert result["curiosity"] is False


# ── 최소 감정 개수 테스트 ──────────────────────────────────────

class TestMinEmotions:
    def test_min_two_emotions_pass(self):
        """2개 이상 감정 포함 → has_min_emotions=True"""
        # anger + fear
        text = "도대체 왜 이러면 안 되는 건지, 안 하면 진짜 큰일남"
        result = score(text)
        assert result.has_min_emotions is True
        assert result.emotion_count >= 2

    def test_min_two_emotions_fail(self):
        """1개만 감정 포함 → has_min_emotions=False"""
        # empathy 하나만 트리거
        text = "나도 그런 경험이 있었어. 정말 공감이 가는 이야기야."
        result = score(text)
        assert result.has_min_emotions is False
        assert result.emotion_count < 2


# ── 숫자 패턴 테스트 ──────────────────────────────────────────

class TestNumberPatterns:
    def test_non_round_number(self):
        """'47,382명' 같은 구체적 숫자 → has_non_round_numbers=True"""
        result = check_non_round_numbers("아직도 모르는 설계사가 47,382명이나 된다")
        assert result is True

    def test_round_number_warning(self):
        """'약 5만' 같은 라운드 숫자 → has_round_numbers=True"""
        result = check_round_numbers("약 5만 명이 영향을 받는다")
        assert result is True


# ── 회사 언급 테스트 ──────────────────────────────────────────

class TestCompanyMentions:
    def test_company_mention(self):
        """'삼성생명' 포함 → has_company_mention=True"""
        result = score("삼성생명 상품이 바뀌었다는데 진짜? 안 하면 큰일남")
        assert result.has_company_mention is True
        assert "삼성" in result.mentioned_companies

    def test_no_company_mention(self):
        """회사명 없음 → has_company_mention=False"""
        result = score("수수료 구조가 바뀌었다는데 진짜? 안 하면 큰일남")
        assert result.has_company_mention is False
        assert result.mentioned_companies == []


# ── 길이 제한 테스트 ──────────────────────────────────────────

class TestLengthCheck:
    def test_within_length(self):
        """500자 이내 → is_within_length=True"""
        text = "가" * 500
        result = score(text)
        assert result.is_within_length is True
        assert result.char_count == 500

    def test_over_length(self):
        """501자 이상 → is_within_length=False"""
        text = "가" * 501
        result = score(text)
        assert result.is_within_length is False
        assert result.char_count == 501


# ── 종합 판정 테스트 ──────────────────────────────────────────

class TestScoreResult:
    def test_score_pass(self):
        """2감정 이상, 회사 언급 없음, 500자 이내 → passed=True"""
        # anger(도대체) + fear(안 하면, 큰일) + surprise(진짜)
        text = "도대체 왜 이런 제도가 바뀌는지, 안 하면 진짜 큰일남. 아직 모르는 사람이 많다니."
        result = score(text)
        assert result.has_min_emotions is True
        assert result.has_company_mention is False
        assert result.is_within_length is True
        assert result.passed is True

    def test_score_fail_one_emotion(self):
        """1감정만 → passed=False"""
        text = "나도 공감이 가는 이야기야. 정말 그렇지."
        result = score(text)
        assert result.emotion_count < 2
        assert result.passed is False
