"""
pytest 테스트: select_single_topic() 함수 테스트

작업: task-353.1 - 단일 토픽 선택 + used_count 정확성 검증
"""

import sys
import json
import tempfile
from pathlib import Path

sys.path.insert(0, "/home/jay/projects/ThreadAuto")

from content.topic_selector import (
    load_topics,
    save_topics,
    select_single_topic,
    select_from_pool,
    DAILY_MIX,
)


def test_select_single_topic_basic():
    """기본 테스트: 1개 토픽만 선택하고 used_count 갱신 여부 확인"""
    with tempfile.TemporaryDirectory() as tmpdir:
        topics_path = Path(tmpdir) / "test_topics.json"

        # 테스트용 topics 생성
        test_topics = [
            {"id": "1", "category": "고민공감", "title": "테스트1", "used_count": 0, "last_used": None},
            {"id": "2", "category": "고민공감", "title": "테스트2", "used_count": 0, "last_used": None},
            {"id": "3", "category": "정보제공", "title": "테스트3", "used_count": 0, "last_used": None},
        ]

        with open(topics_path, "w", encoding="utf-8") as f:
            json.dump(test_topics, f)

        # 임시 TOPICS_PATH 설정
        import content.topic_selector as ts
        original_path = ts.TOPICS_PATH
        ts.TOPICS_PATH = topics_path

        try:
            # select_single_topic() 호출
            selected = select_single_topic()

            # 1개만 선택되었는지 확인
            assert isinstance(selected, dict), "반환값은 dict여야 함"
            assert selected["id"] in ["1", "2", "3"], "유효한 ID여야 함"

            # topics 파일 다시 로드하여 used_count 확인
            loaded_topics = load_topics()
            topic1 = next((t for t in loaded_topics if t["id"] == "1"), None)
            topic2 = next((t for t in loaded_topics if t["id"] == "2"), None)
            topic3 = next((t for t in loaded_topics if t["id"] == "3"), None)

            # 선택된 토픽의 used_count만 1 증가했는지 확인
            if selected["id"] == "1":
                assert topic1["used_count"] == 1, f"토픽1의 used_count는 1이어야 함, 현재: {topic1['used_count']}"
                assert topic2["used_count"] == 0, f"토픽2의 used_count는 0이어야 함, 현재: {topic2['used_count']}"
                assert topic3["used_count"] == 0, f"토픽3의 used_count는 0이어야 함, 현재: {topic3['used_count']}"
            elif selected["id"] == "2":
                assert topic1["used_count"] == 0, f"토픽1의 used_count는 0이어야 함, 현재: {topic1['used_count']}"
                assert topic2["used_count"] == 1, f"토픽2의 used_count는 1이어야 함, 현재: {topic2['used_count']}"
                assert topic3["used_count"] == 0, f"토픽3의 used_count는 0이어야 함, 현재: {topic3['used_count']}"
            elif selected["id"] == "3":
                assert topic1["used_count"] == 0, f"토픽1의 used_count는 0이어야 함, 현재: {topic1['used_count']}"
                assert topic2["used_count"] == 0, f"토픽2의 used_count는 0이어야 함, 현재: {topic2['used_count']}"
                assert topic3["used_count"] == 1, f"토픽3의 used_count는 1이어야 함, 현재: {topic3['used_count']}"

            print("✓ 기본 테스트 통과: 1개 토픽 선택 및 used_count 정확한 갱신")

        finally:
            ts.TOPICS_PATH = original_path


def test_select_single_topic_with_category():
    """카테고리 지정 테스트: 지정된 카테고리에서만 선택되는지 확인"""
    with tempfile.TemporaryDirectory() as tmpdir:
        topics_path = Path(tmpdir) / "test_topics.json"

        # 테스트용 topics 생성
        test_topics = [
            {"id": "1", "category": "고민공감", "title": "고민1", "used_count": 0, "last_used": None},
            {"id": "2", "category": "고민공감", "title": "고민2", "used_count": 0, "last_used": None},
            {"id": "3", "category": "정보제공", "title": "정보1", "used_count": 0, "last_used": None},
        ]

        with open(topics_path, "w", encoding="utf-8") as f:
            json.dump(test_topics, f)

        import content.topic_selector as ts
        original_path = ts.TOPICS_PATH
        ts.TOPICS_PATH = topics_path

        try:
            # 고민공감 카테고리로 선택
            selected = select_single_topic(category="고민공감")

            # 선택된 카테고리 확인
            assert selected["category"] == "고민공감", f"카테고리는 고민공감이어야 함, 현재: {selected['category']}"

            # 토픽1, 2 중 하나만 선택되었는지 확인
            assert selected["id"] in ["1", "2"], f"ID는 1 또는 2여야 함, 현재: {selected['id']}"

            # used_count 확인
            loaded_topics = load_topics()
            topic1 = next((t for t in loaded_topics if t["id"] == "1"), None)
            topic2 = next((t for t in loaded_topics if t["id"] == "2"), None)
            topic3 = next((t for t in loaded_topics if t["id"] == "3"), None)

            if selected["id"] == "1":
                assert topic1["used_count"] == 1
                assert topic2["used_count"] == 0
                assert topic3["used_count"] == 0
            elif selected["id"] == "2":
                assert topic1["used_count"] == 0
                assert topic2["used_count"] == 1
                assert topic3["used_count"] == 0

            print("✓ 카테고리 지정 테스트 통과: 지정된 카테고리에서만 선택됨")

        finally:
            ts.TOPICS_PATH = original_path


def test_select_single_topic_no_category():
    """category=None 테스트: DAILY_MIX 비율에 따라 가중 랜덤 선택"""
    with tempfile.TemporaryDirectory() as tmpdir:
        topics_path = Path(tmpdir) / "test_topics.json"

        # 모든 카테고리에 테스트용 토픽 생성
        test_topics = [
            {"id": "1", "category": "고민공감", "title": "고민1", "used_count": 0, "last_used": None},
            {"id": "2", "category": "고민공감", "title": "고민2", "used_count": 0, "last_used": None},
            {"id": "3", "category": "정보제공", "title": "정보1", "used_count": 0, "last_used": None},
            {"id": "4", "category": "사회적증거", "title": "증거1", "used_count": 0, "last_used": None},
            {"id": "5", "category": "업계동향", "title": "동향1", "used_count": 0, "last_used": None},
        ]

        with open(topics_path, "w", encoding="utf-8") as f:
            json.dump(test_topics, f)

        import content.topic_selector as ts
        original_path = ts.TOPICS_PATH
        ts.TOPICS_PATH = topics_path

        try:
            # 여러 번 호출하여 각 카테고리가 선택될 가능성 확인
            selected_categories = set()
            for _ in range(10):  # 10번 실행하여 분포 확인
                selected = select_single_topic(category=None)
                selected_categories.add(selected["category"])

            # 최소 하나 이상의 카테고리가 선택되었는지 확인
            assert len(selected_categories) > 0, "최소 하나의 카테고리가 선택되어야 함"
            assert "업계동향" not in selected_categories or len(selected_categories) > 0, "업계동향 카테고리가 선택되었을 수 있음"

            print(f"✓ category=None 테스트 통과: 선택된 카테고리: {selected_categories}")

        finally:
            ts.TOPICS_PATH = original_path


def test_select_single_topic_return_type():
    """반환 타입 테스트: dict 형식 반환 여부"""
    with tempfile.TemporaryDirectory() as tmpdir:
        topics_path = Path(tmpdir) / "test_topics.json"

        test_topics = [
            {"id": "1", "category": "고민공감", "title": "테스트1", "used_count": 0, "last_used": None},
        ]

        with open(topics_path, "w", encoding="utf-8") as f:
            json.dump(test_topics, f)

        import content.topic_selector as ts
        original_path = ts.TOPICS_PATH
        ts.TOPICS_PATH = topics_path

        try:
            selected = select_single_topic()

            # 반환 타입 확인
            assert isinstance(selected, dict), f"반환값은 dict여야 함, 현재: {type(selected)}"
            assert "id" in selected, "반환값에 'id' 키가 있어야 함"
            assert "category" in selected, "반환값에 'category' 키가 있어야 함"
            assert "title" in selected, "반환값에 'title' 키가 있어야 함"

            print("✓ 반환 타입 테스트 통과: 올바른 dict 형식 반환")

        finally:
            ts.TOPICS_PATH = original_path


def test_select_single_topic_empty_pool():
    """빈 풀 테스트: 토픽이 없을 때 fallback 플레이스홀더 반환"""
    with tempfile.TemporaryDirectory() as tmpdir:
        topics_path = Path(tmpdir) / "test_topics.json"

        # 빈 리스트 저장
        with open(topics_path, "w", encoding="utf-8") as f:
            json.dump([], f)

        import content.topic_selector as ts
        original_path = ts.TOPICS_PATH
        ts.TOPICS_PATH = topics_path

        try:
            selected = select_single_topic(category="고민공감")

            # fallback 플레이스홀더 반환 확인
            assert selected["id"].startswith("eg-fallback-"), f"Fallback ID 형식이어야 함: {selected['id']}"
            assert selected["category"] == "고민공감", f"카테고리는 고민공감이어야 함, 현재: {selected['category']}"

            print("✓ 빈 풀 테스트 통과: fallback 플레이스홀더 정상 반환")

        finally:
            ts.TOPICS_PATH = original_path


if __name__ == "__main__":
    import pytest

    pytest.main([__file__, "-v", "-s"])
