import pytest

from ankipan import Reader

@pytest.mark.parametrize(
    "lang,input_text,expected",
    [
        ('de', 'Woher genau\\h', 'Woher genau'),
        ('de', 'Woher\ngenau\n\n', 'Woher\ngenau\n\n'),
        ('de', 'Heute Abend gehen wir, weil es "Alles kann passieren"- Donnerstag ist.', 'Heute Abend gehen wir, weil es "Alles kann passieren"- Donnerstag ist.'),
        ('de', '''Spielen wir Halo, gucken wir Battlestar,
schmeißen wir ein paar Mentos in Diätcola?''', '''Spielen wir Halo, gucken wir Battlestar,
schmeißen wir ein paar Mentos in Diätcola?'''),
    ]
)
def test_clean_string(lang, input_text, expected):
    r = Reader(lang)
    res = r.clean_string(input_text, r.sub_filter_expressions)
    assert res == expected

@pytest.mark.parametrize(
    "lang,input_text,expected",
    [
        ('de', '''Heute Abend gehen wir, weil es
"Alles kann passieren"- Donnerstag ist, Sheldon. Martin ist auch dabei''',
'''Heute Abend gehen wir, weil es "Alles kann passieren"- Donnerstag ist, Sheldon. Martin ist auch dabei''')]
)
def test_parse_sub(lang, input_text, expected):
    r = Reader(lang)
    assert r.parse_subs(f'1\n00:01:10,960 --> 00:01:12,299\n{input_text}')[0] == expected


def test_reader_jp_basic(monkeypatch):
    from ankipan.reader import File

    class DummyParser:
        def iter_lemmas(self, text: str):
            """Dummy parser that yields (surface, lemma_lower, pos) tuples."""
            yield "貢献", "貢献", None

    monkeypatch.setattr("ankipan.reader.load_lemmatizer", lambda lang, project_root=None: DummyParser())

    r = Reader("jp")
    f = File("jp", "貢献した")
    r.process_files([f], save_sentence_mapping=True, silent=True)

    assert f.lemma_counts == {"貢献": 1}
    assert f.lemma_word_index_mapping.get("貢献")


def test_dict_validator_german_basic():
    """Test DictValidator with basic German text lemmatization."""
    from ankipan.lemma_parsers import load_lemmatizer

    # Load the German dict validator
    validator = load_lemmatizer("de")
    assert validator is not None, "Failed to load German DictValidator"

    # Test simple German sentence
    text = "Das Haus ist groß"
    results = list(validator.iter_lemmas(text))

    print("\n=== German lemmatization results ===")
    print(f"Input: {text}")
    print(f"Tokens: {len(results)}")
    for surface, lemma_lower, pos in results:
        print(f"  {surface:12} -> {lemma_lower:12} (POS: {pos})")

    # Should have extracted some lemmas
    assert len(results) > 0, "No lemmas extracted"
    assert all(isinstance(surface, str) for surface, _, _ in results), "Surface should be string"
    assert all(isinstance(lemma, str) for _, lemma, _ in results), "Lemma should be string"


def test_dict_validator_german_complex():
    """Test DictValidator with more complex German text."""
    from ankipan.lemma_parsers import load_lemmatizer

    validator = load_lemmatizer("de")
    assert validator is not None

    # Test sentence with multiple words
    text = "Los geht's! Ich habe ein Buch gelesen und es war interessant."
    results = list(validator.iter_lemmas(text))

    print("\n=== German complex lemmatization ===")
    print(f"Input: {text}")
    print(f"Extracted tokens: {len(results)}")
    for surface, headword, pos in results:
        print(f"  {surface:15} -> {headword:15} (POS: {pos})")

    # Verify we get valid outputs
    assert len(results) > 0
    # Verify capitalization is applied correctly based on POS
    # NOUN/PROPN should be capitalized, others lowercase
    for surface, headword, pos in results:
        if pos in {"NOUN", "PROPN"}:
            assert headword[0].isupper(), f"Expected {headword} to be capitalized (POS: {pos})"
        elif pos in {"VERB", "ADJ", "ADV"}:
            # Most non-nouns should be lowercase, but some adjectives might be capitalized
            pass


def test_file_extract_lemmas_german():
    """Test File.extract_lemmas with German DictValidator."""
    from ankipan.reader import File
    from ankipan.lemma_parsers import load_lemmatizer

    validator = load_lemmatizer("de")
    assert validator is not None

    # Create a file with German text
    text = "Heute Abend gehen wir, weil es 'Alles kann passieren'- Donnerstag ist, Sheldon. Martin ist auch dabei"
    f = File("de", text)

    # Extract lemmas with position and sentence mapping
    f.extract_lemmas(validator, save_pos_data=True, save_sentence_mapping=True)

    print("\n=== File lemma extraction (German) ===")
    print(f"Input text: {text}")
    print(f"Segments: {len(f.segments)}")
    for i, segment in enumerate(f.segments):
        print(f"  Segment {i}: {segment[:50]}...")

    print(f"\nLemma counts: {dict(f.lemma_counts)}")
    print(f"Processed words (sample): {list(f.processed_words.items())[:5]}")
    print(f"Lemma word index mapping (sample): {dict(list(f.lemma_word_index_mapping.items())[:3])}")

    # Verify results
    assert len(f.segments) > 0, "Should have segments"
    assert len(f.lemma_counts) > 0, "Should have lemma counts"
    assert len(f.processed_words) > 0, "Should have processed words"
    assert len(f.lemma_word_index_mapping) > 0, "Should have lemma word index mapping"


def test_file_extract_lemmas_with_pos():
    """Test that POS data is properly captured."""
    from ankipan.reader import File
    from ankipan.lemma_parsers import load_lemmatizer

    validator = load_lemmatizer("de")
    assert validator is not None

    text = "Ich bin müde"
    f = File("de", text)
    f.extract_lemmas(validator, save_pos_data=True, save_sentence_mapping=False)

    print("\n=== POS data verification ===")
    print(f"Input: {text}")
    print(f"Text segment components: {f.text_segment_components}")

    if f.text_segment_components and len(f.text_segment_components) > 0:
        print(f"Sample token with POS: {f.text_segment_components[0]}")
        # Verify structure of token metadata
        for tokens_in_segment in f.text_segment_components:
            for token in tokens_in_segment:
                assert "word" in token, "Token should have 'word'"
                assert "lemma" in token, "Token should have 'lemma'"
                assert "pos" in token, "Token should have 'pos'"
                print(f"  Token: {token}")


def test_reader_process_files_german():
    """Test Reader.process_files with German text."""
    from ankipan.reader import File

    reader = Reader("de")

    # Create multiple files
    file1 = File("de", "Das Haus ist groß.\n\nDie Tür ist klein.")
    file2 = File("de", "Der Mann geht zur Arbeit.")

    # Process files (use n_threads=1 to avoid multiprocessing issues in tests)
    reader.process_files([file1, file2], save_pos_data=True, save_sentence_mapping=True, n_threads=1, silent=True)

    print("\n=== Reader process_files (German) ===")
    print(f"File 1 lemma count: {len(file1.lemma_counts)}")
    print(f"File 1 lemmas: {dict(file1.lemma_counts)}")
    print(f"File 2 lemma count: {len(file2.lemma_counts)}")
    print(f"File 2 lemmas: {dict(file2.lemma_counts)}")

    # Verify both files were processed
    assert len(file1.lemma_counts) > 0
    assert len(file2.lemma_counts) > 0
