"""
Tests for the pyderekovecs package.
"""
import unittest
import pandas as pd
from unittest import mock

from pyderekovecs import (
    syntagmatic_neighbours,
    countbased_collocates,
    word_frequency,
    corpus_size,
    paradigmatic_neighbours,
    word_embedding,
    frequency_rank,
    cosine_similarity,
    collocation_scores,
    derekovecs_api_call
)
from pyderekovecs.utils import is_word


class MockResponse:
    """Mock response class for testing."""
    
    def __init__(self, json_data, status_code=200):
        self.json_data = json_data
        self.status_code = status_code
        
    def json(self):
        return self.json_data
    
    def raise_for_status(self):
        if self.status_code != 200:
            raise Exception(f"HTTP Error: {self.status_code}")


class TestDerekovecs(unittest.TestCase):
    """Test cases for the pyderekovecs package."""

    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_paradigmatic_neighbours(self, mock_get):
        """Test that paradigmatic_neighbours works."""
        mock_response = {
            "list": [
                [{"word": "Test", "similarity": 1.0}, {"word": "Experiment", "similarity": 0.8}]
            ]
        }
        mock_get.return_value = MockResponse(mock_response)
        
        result = paradigmatic_neighbours("Test")
        self.assertEqual(result.iloc[0]['word'], "Test")
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_syntagmatic_neighbours(self, mock_get):
        """Test that syntagmatic_neighbours works."""
        mock_response = {
            "collocators": [
                {"word": "durchführen", "rank": 1, "average": 0.8}
            ]
        }
        mock_get.return_value = MockResponse(mock_response)
        
        result = syntagmatic_neighbours("Test")
        self.assertTrue(is_word(result.iloc[0]['word']))
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_countbased_collocates(self, mock_get):
        """Test that countbased_collocates works."""
        mock_response = {
            "collocates": [
                {"word": "durchführen", "f": 100, "pmi": 0.8}
            ]
        }
        mock_get.return_value = MockResponse(mock_response)
        
        result = countbased_collocates("Test")
        self.assertTrue(is_word(result.iloc[0]['word']))
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_collocation_scores(self, mock_get):
        """Test that collocation_scores works."""
        mock_response = {
            "collocates": [
                {"word": "putzen", "f2": 500, "pmi": 0.8}
            ]
        }
        mock_get.return_value = MockResponse(mock_response)
        
        result = collocation_scores("Zähne", "putzen")
        self.assertTrue(result.iloc[0]['f2'] > 0)
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_cosine_similarity(self, mock_get):
        """Test that cosine_similarity works."""
        # Test for same word
        mock_get.return_value = MockResponse(1.0)
        
        result = cosine_similarity("Test", "Test")
        self.assertEqual(result, 1.0)
        
        # Test for different words
        mock_get.return_value = MockResponse(0.7)
        
        result = cosine_similarity("Test", "testen")
        self.assertTrue(0 <= result <= 1.0)
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_word_embedding(self, mock_get):
        """Test that word_embedding works."""
        # Create a mock vector of length 200
        mock_vector = [0.1] * 200
        mock_response = {
            "list": [
                [{"vector": mock_vector}]
            ]
        }
        mock_get.return_value = MockResponse(mock_response)
        
        result = word_embedding("Test")
        self.assertEqual(len(result), 200)
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_frequency_rank(self, mock_get):
        """Test that frequency_rank works."""
        mock_get.return_value = MockResponse({"frequencyRank": 500})
        
        result = frequency_rank("Test")
        self.assertTrue(isinstance(result, int) and result > 0)
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_word_frequency(self, mock_get):
        """Test that word_frequency works."""
        mock_get.return_value = MockResponse({"f1": 1000})
        
        result = word_frequency("Test")
        self.assertTrue(isinstance(result, int) and result > 0)
        
    @mock.patch('pyderekovecs.derekovecs.requests.get')
    def test_corpus_size(self, mock_get):
        """Test that corpus_size works."""
        mock_get.return_value = MockResponse({"N": 1000000})
        
        result = corpus_size()
        self.assertTrue(isinstance(result, int) and result > 1000)


if __name__ == '__main__':
    unittest.main()