"""Tests for keyword tracker."""

import json
import os
import tempfile
from unittest.mock import patch

from src.analysis.keyword_tracker import (
    extract_keyword_positions,
    load_previous_state,
    save_current_state,
    track_keywords,
)
from src.models.data_models import KeywordPosition


class TestExtractKeywordPositions:
    def test_found_keywords(self, sample_query_rows):
        keywords = ["nroom", "ブログ nroom"]
        positions = extract_keyword_positions(sample_query_rows, keywords)

        assert len(positions) == 2
        assert positions[0].keyword == "nroom"
        assert positions[0].current_position == 1.5
        assert positions[0].clicks == 50
        assert positions[1].keyword == "ブログ nroom"
        assert positions[1].current_position == 3.0

    def test_missing_keyword(self, sample_query_rows):
        keywords = ["nonexistent keyword"]
        positions = extract_keyword_positions(sample_query_rows, keywords)

        assert len(positions) == 1
        assert positions[0].current_position == 0.0

    def test_case_insensitive(self):
        rows = [{"keys": ["NRoom"], "clicks": 10, "impressions": 50, "ctr": 0.2, "position": 2.0}]
        keywords = ["nroom"]
        positions = extract_keyword_positions(rows, keywords)

        assert positions[0].current_position == 2.0

    def test_empty_rows(self):
        positions = extract_keyword_positions([], ["nroom"])
        assert len(positions) == 1
        assert positions[0].current_position == 0.0


class TestStateFileOperations:
    def test_save_and_load(self, tmp_path):
        state_file = tmp_path / "keyword_state.json"
        site_url = "https://test.example.com"

        positions = [
            KeywordPosition(keyword="test", current_position=3.0),
            KeywordPosition(keyword="example", current_position=5.0),
        ]

        with patch("src.analysis.keyword_tracker.STATE_FILE", state_file):
            save_current_state(site_url, positions)
            loaded = load_previous_state(site_url)

        assert loaded == {"test": 3.0, "example": 5.0}

    def test_load_nonexistent_file(self, tmp_path):
        state_file = tmp_path / "nonexistent.json"
        with patch("src.analysis.keyword_tracker.STATE_FILE", state_file):
            loaded = load_previous_state("https://test.example.com")
        assert loaded == {}

    def test_multiple_sites(self, tmp_path):
        state_file = tmp_path / "keyword_state.json"

        pos1 = [KeywordPosition(keyword="kw1", current_position=2.0)]
        pos2 = [KeywordPosition(keyword="kw2", current_position=4.0)]

        with patch("src.analysis.keyword_tracker.STATE_FILE", state_file):
            save_current_state("https://site1.com", pos1)
            save_current_state("https://site2.com", pos2)

            state1 = load_previous_state("https://site1.com")
            state2 = load_previous_state("https://site2.com")

        assert state1 == {"kw1": 2.0}
        assert state2 == {"kw2": 4.0}


class TestTrackKeywords:
    def test_with_alert(self, sample_query_rows, tmp_path):
        state_file = tmp_path / "keyword_state.json"

        # Pre-populate state with different positions
        state = {
            "https://test.com": {
                "nroom": 5.0,  # Was 5.0, now 1.5 => change -3.5 => alert
                "ブログ nroom": 3.0,  # Same => no alert
            }
        }
        with open(state_file, "w") as f:
            json.dump(state, f)

        keywords = ["nroom", "ブログ nroom"]

        with patch("src.analysis.keyword_tracker.STATE_FILE", state_file):
            positions = track_keywords(
                sample_query_rows, keywords, "https://test.com", alert_threshold=3,
            )

        assert len(positions) == 2
        nroom_pos = positions[0]
        assert nroom_pos.keyword == "nroom"
        assert nroom_pos.previous_position == 5.0
        assert nroom_pos.current_position == 1.5
        assert nroom_pos.change == -3.5
        assert nroom_pos.is_alert is True

        blog_pos = positions[1]
        assert blog_pos.is_alert is False

    def test_no_previous_state(self, sample_query_rows, tmp_path):
        state_file = tmp_path / "keyword_state.json"

        with patch("src.analysis.keyword_tracker.STATE_FILE", state_file):
            positions = track_keywords(
                sample_query_rows, ["nroom"], "https://test.com",
            )

        assert len(positions) == 1
        assert positions[0].previous_position == 0.0
        assert positions[0].is_alert is False
