"""Unit tests for generate_carousel.py"""

import json
import os
import sys
import tempfile
from pathlib import Path

import pytest

# Add parent directory to path for module import
sys.path.insert(0, str(Path(__file__).parent.parent))

from generate_carousel import load_slide_data, load_env_keys


class TestLoadSlideData:
    """Test slide data loading functionality"""

    def test_load_slide_data(self):
        """Test that set_a.json loads correctly with 5 slides"""
        data = load_slide_data("상시A")

        assert data is not None
        assert "slides" in data
        assert len(data["slides"]) == 5
        assert data["setName"] == "상시A"

    def test_load_slide_data_unknown_set(self):
        """Test that unknown set raises ValueError"""
        with pytest.raises(ValueError, match="Unknown set"):
            load_slide_data("unknown_set")


class TestSlideDataAccuracy:
    """Test accuracy of numeric and text data in slides"""

    def test_slide_data_accuracy(self):
        """Test that numeric values match original source data"""
        data = load_slide_data("상시A")
        slides = data["slides"]

        # Slide 3 (신뢰 근거) - Check for specific numeric values
        slide_3 = next(s for s in slides if s["slideNumber"] == 3)

        # Check for 1,000만원 (10 million won)
        found_10m = False
        for bullet in slide_3.get("bulletPoints", []):
            if "1,000만원" in bullet:
                found_10m = True
                break
        assert found_10m, "신입 최대 1,000만원 should be present"

        # Check for 50%
        found_50pct = False
        for bullet in slide_3.get("bulletPoints", []):
            if "50%" in bullet:
                found_50pct = True
                break
        assert found_50pct, "경력직 최대 직전연봉 50% should be present"

        # Check for 4회/년 (4 times per year)
        found_4times = False
        for bullet in slide_3.get("bulletPoints", []):
            if "4회/년" in bullet:
                found_4times = True
                break
        assert found_4times, "해외여행 4회/년 should be present"

        # Check for 30개 (30 packages)
        found_30packs = False
        for bullet in slide_3.get("bulletPoints", []):
            if "30개" in bullet:
                found_30packs = True
                break
        assert found_30packs, "30개 지원 패키지 should be present"

        # Check for 잔여수수료
        found_remaining_fee = False
        for bullet in slide_3.get("bulletPoints", []):
            if "잔여수수료" in bullet:
                found_remaining_fee = True
                break
        assert found_remaining_fee, "잔여수수료 should be present in slide 3"


class TestNoForbiddenTerms:
    """Test that forbidden terms are not used"""

    def test_no_forbidden_terms(self):
        """Test that '잔존수당' term is not used in slides"""
        data = load_slide_data("상시A")

        # Convert entire data to string for searching
        data_str = json.dumps(data, ensure_ascii=False)

        # Check that forbidden term is NOT present
        assert "잔존수당" not in data_str, "'잔존수당' forbidden term should not be used"

        # Verify that 잔여수수료 is used instead
        assert "잔여수수료" in data_str, "'잔여수수료' should be used instead"


class TestSlideApproaches:
    """Test slide approach (B/C) mapping"""

    def test_slide_approaches(self):
        """Test that slide approaches are correctly mapped"""
        data = load_slide_data("상시A")
        slides = data["slides"]

        # Expected approach mapping
        expected_approaches = {
            1: "C",  # 고통 인식 - with AI background
            2: "B",  # 문제 심화 - HTML only
            3: "B",  # 신뢰 근거 - HTML only
            4: "B",  # 차별화 - HTML only
            5: "C",  # CTA - with AI background
        }

        for slide in slides:
            slide_num = slide["slideNumber"]
            actual_approach = slide["approach"]
            expected_approach = expected_approaches[slide_num]

            assert actual_approach == expected_approach, \
                f"Slide {slide_num}: expected approach {expected_approach}, got {actual_approach}"

    def test_approach_c_has_bg_prompt(self):
        """Test that Approach C slides have bgPrompt"""
        data = load_slide_data("상시A")
        slides = data["slides"]

        for slide in slides:
            if slide["approach"] == "C":
                assert "bgPrompt" in slide, \
                    f"Slide {slide['slideNumber']} has approach C but missing bgPrompt"
                assert slide["bgPrompt"], \
                    f"Slide {slide['slideNumber']} bgPrompt is empty"


class TestLoadEnvKeys:
    """Test environment variable loading from .env.keys file"""

    def test_load_env_keys(self):
        """Test that export prefix parsing is correct (using temporary file)"""
        # Create a temporary .env.keys file with various formats
        with tempfile.NamedTemporaryFile(
            mode='w',
            suffix='.keys',
            delete=False,
            encoding='utf-8'
        ) as tmp:
            tmp.write("# This is a comment\n")
            tmp.write("export OPENAI_API_KEY=sk-test-key-123\n")
            tmp.write("PLAIN_VAR=plain_value\n")
            tmp.write("export QUOTED_VAR='quoted_value'\n")
            tmp.write("DOUBLE_QUOTED=\"double_quoted_value\"\n")
            tmp.write("  SPACED_VAR  =  spaced_value  \n")
            tmp.write("EMPTY_VAR=\n")
            tmp.write("\n")  # Empty line
            tmp_path = tmp.name

        try:
            # Clear any existing test variables
            test_vars = [
                "OPENAI_API_KEY",
                "PLAIN_VAR",
                "QUOTED_VAR",
                "DOUBLE_QUOTED",
                "SPACED_VAR",
                "EMPTY_VAR"
            ]
            for var in test_vars:
                os.environ.pop(var, None)

            # Monkey-patch the env path for this test
            original_load_env_keys = None
            import generate_carousel
            original_env_path = generate_carousel.load_env_keys.__code__

            # Instead, we'll create a custom version that reads our temp file
            def load_env_keys_from_file(file_path):
                """Load API keys from file"""
                env_path = Path(file_path)
                if env_path.exists():
                    for line in env_path.read_text(encoding='utf-8').splitlines():
                        line = line.strip()
                        if line and not line.startswith("#") and "=" in line:
                            # Handle 'export VAR=VALUE' format
                            if line.startswith("export "):
                                line = line[7:]
                            key, _, value = line.partition("=")
                            # Remove quotes
                            value = value.strip().strip('"').strip("'")
                            os.environ.setdefault(key.strip(), value)

            # Load from our temporary file
            load_env_keys_from_file(tmp_path)

            # Verify parsing results
            assert os.environ.get("OPENAI_API_KEY") == "sk-test-key-123", \
                "export prefix should be stripped"
            assert os.environ.get("PLAIN_VAR") == "plain_value", \
                "plain var without export should work"
            assert os.environ.get("QUOTED_VAR") == "quoted_value", \
                "single quotes should be removed"
            assert os.environ.get("DOUBLE_QUOTED") == "double_quoted_value", \
                "double quotes should be removed"
            assert os.environ.get("SPACED_VAR") == "spaced_value", \
                "leading/trailing spaces should be stripped"
            assert os.environ.get("EMPTY_VAR") == "", \
                "empty values should be allowed"

        finally:
            # Clean up temporary file
            Path(tmp_path).unlink()

    def test_load_env_keys_handles_comments(self):
        """Test that comments are properly ignored"""
        with tempfile.NamedTemporaryFile(
            mode='w',
            suffix='.keys',
            delete=False,
            encoding='utf-8'
        ) as tmp:
            tmp.write("# Full line comment\n")
            tmp.write("VALID_VAR=valid_value\n")
            tmp_path = tmp.name

        try:
            os.environ.pop("VALID_VAR", None)

            def load_env_keys_from_file(file_path):
                env_path = Path(file_path)
                if env_path.exists():
                    for line in env_path.read_text(encoding='utf-8').splitlines():
                        line = line.strip()
                        if line and not line.startswith("#") and "=" in line:
                            if line.startswith("export "):
                                line = line[7:]
                            key, _, value = line.partition("=")
                            value = value.strip().strip('"').strip("'")
                            os.environ.setdefault(key.strip(), value)

            load_env_keys_from_file(tmp_path)

            assert os.environ.get("VALID_VAR") == "valid_value", \
                "valid var should be loaded"

        finally:
            Path(tmp_path).unlink()


class TestSlideStructure:
    """Test overall structure and required fields"""

    def test_all_slides_have_required_fields(self):
        """Test that all slides have required fields"""
        data = load_slide_data("상시A")
        slides = data["slides"]

        required_fields = ["slideNumber", "approach", "title", "headline"]

        for slide in slides:
            for field in required_fields:
                assert field in slide, \
                    f"Slide {slide.get('slideNumber')} missing required field: {field}"

    def test_slide_numbers_sequential(self):
        """Test that slide numbers are sequential from 1 to 5"""
        data = load_slide_data("상시A")
        slides = data["slides"]

        slide_numbers = [s["slideNumber"] for s in slides]
        assert slide_numbers == [1, 2, 3, 4, 5], \
            f"Slide numbers should be [1, 2, 3, 4, 5], got {slide_numbers}"
