import hashlib
import pytest
from pathlib import Path
from transduck.storage import TranslationStore


@pytest.fixture
def store(tmp_path):
    db_path = tmp_path / "test.db"
    s = TranslationStore(db_path)
    s.initialize()
    yield s
    s.close()


def _hash(text: str) -> str:
    return hashlib.sha256(text.encode()).hexdigest()


def test_initialize_starts_empty(store):
    st = store.stats()
    assert st["total_translations"] == 0


def test_insert_and_lookup(store):
    store.insert(
        source_text="Hello",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
        translated_text="Hallo",
        model="gpt-4.1-mini",
        status="translated",
        string_context="",
    )
    result = store.lookup(
        source_text="Hello",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
    )
    assert result == "Hallo"


def test_lookup_miss_returns_none(store):
    result = store.lookup(
        source_text="Missing",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
    )
    assert result is None


def test_lookup_skips_failed(store):
    store.insert(
        source_text="Bad",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
        translated_text="bad translation",
        model="gpt-4.1-mini",
        status="failed",
        string_context="",
    )
    result = store.lookup(
        source_text="Bad",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
    )
    assert result is None


def test_duplicate_insert_does_not_error(store):
    kwargs = dict(
        source_text="Hello",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
        translated_text="Hallo",
        model="gpt-4.1-mini",
        status="translated",
        string_context="",
    )
    store.insert(**kwargs)
    store.insert(**kwargs)  # should not raise
    result = store.lookup(
        source_text="Hello",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
    )
    assert result == "Hallo"


def test_insert_and_lookup_with_empty_plural_category(store):
    """Regular ait() rows use empty string plural_category."""
    store.insert(
        source_text="Hello", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
        translated_text="Hallo", model="gpt-4.1-mini",
        string_context="",
    )
    result = store.lookup(
        source_text="Hello", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
    )
    assert result == "Hallo"


def test_insert_plural_and_lookup_plural(store):
    categories = {"one": "1 Nachricht", "other": "{count} Nachrichten"}
    source_key = "{count} message\x00{count} messages"
    for cat, text in categories.items():
        store.insert_plural(
            source_text=source_key, source_lang="EN", target_lang="DE",
            project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
            plural_category=cat, translated_text=text, model="gpt-4.1-mini",
            string_context="",
        )
    result = store.lookup_plural(
        source_text=source_key, source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
    )
    assert result == {"one": "1 Nachricht", "other": "{count} Nachrichten"}


def test_lookup_plural_returns_empty_dict_on_miss(store):
    result = store.lookup_plural(
        source_text="missing", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
    )
    assert result == {}


def test_lookup_plural_skips_failed(store):
    store.insert_plural(
        source_text="key", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
        plural_category="one", translated_text="bad", model="gpt-4.1-mini",
        status="failed", string_context="",
    )
    result = store.lookup_plural(
        source_text="key", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
    )
    assert result == {}


def test_stats(store):
    store.insert(
        source_text="Hello",
        source_lang="EN",
        target_lang="DE",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
        translated_text="Hallo",
        model="gpt-4.1-mini",
        status="translated",
        string_context="",
    )
    store.insert(
        source_text="Hello",
        source_lang="EN",
        target_lang="ES",
        project_context_hash=_hash("ctx"),
        string_context_hash=_hash(""),
        translated_text="Hola",
        model="gpt-4.1-mini",
        status="translated",
        string_context="",
    )
    stats = store.stats()
    assert stats["total_translations"] == 2
    assert stats["by_language"]["DE"] == 1
    assert stats["by_language"]["ES"] == 1
    assert stats["total_failed"] == 0


def test_count_and_delete(store):
    store.insert(
        source_text="Hello", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
        translated_text="Hallo", model="gpt-4.1-mini", status="translated",
        string_context="",
    )
    store.insert(
        source_text="Bad", source_lang="EN", target_lang="DE",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
        translated_text="schlecht", model="gpt-4.1-mini", status="failed",
        string_context="",
    )
    store.insert(
        source_text="Hello", source_lang="EN", target_lang="ES",
        project_context_hash=_hash("ctx"), string_context_hash=_hash(""),
        translated_text="Hola", model="gpt-4.1-mini", status="translated",
        string_context="",
    )

    assert store.count() == 3
    assert store.count(target_lang="DE") == 2
    assert store.count(failed_only=True) == 1
    assert store.count(target_lang="DE", failed_only=True) == 1

    deleted = store.delete(target_lang="DE", failed_only=True)
    assert deleted == 1
    assert store.count() == 2
