import os
import pytest
from transduck.scanner import extract_strings, scan_directory


def test_extract_ait_double_quotes():
    code = 'ait("Our Events")'
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "Our Events"
    assert result[0].get("plural") is None


def test_extract_ait_single_quotes():
    code = "ait('Our Events')"
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "Our Events"


def test_extract_ait_with_context_keyword():
    code = 'ait("Book Now", context="Hotel booking")'
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "Book Now"
    assert result[0]["context"] == "Hotel booking"


def test_extract_ait_with_context_positional():
    """JS-style positional context."""
    code = 'ait("Book Now", "Hotel booking")'
    result = extract_strings(code, "test.js")
    assert len(result) == 1
    assert result[0]["text"] == "Book Now"
    assert result[0]["context"] == "Hotel booking"


def test_extract_ait_no_context():
    code = 'ait("Hello")'
    result = extract_strings(code, "test.py")
    assert result[0].get("context") is None


def test_extract_ait_with_vars_no_context():
    code = 'ait("Welcome {name}", vars={"name": user})'
    result = extract_strings(code, "test.py")
    assert result[0]["text"] == "Welcome {name}"
    assert result[0].get("context") is None


def test_extract_ait_plural_python():
    code = 'ait_plural("{count} message", "{count} messages", count=n)'
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} message"
    assert result[0]["other"] == "{count} messages"


def test_extract_ait_plural_js():
    code = "aitPlural('{count} night', '{count} nights', 5)"
    result = extract_strings(code, "test.ts")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} night"
    assert result[0]["other"] == "{count} nights"


def test_extract_django_template_tag():
    code = '{% ait "Our Events" %}'
    result = extract_strings(code, "test.html")
    assert len(result) == 1
    assert result[0]["text"] == "Our Events"


def test_extract_django_template_tag_with_context():
    code = '{% ait "Book Now" context="Hotel booking" %}'
    result = extract_strings(code, "test.html")
    assert result[0]["text"] == "Book Now"
    assert result[0]["context"] == "Hotel booking"


def test_extract_jinja_expression():
    code = '{{ ait("Our Events") }}'
    result = extract_strings(code, "test.html")
    assert len(result) == 1
    assert result[0]["text"] == "Our Events"


def test_extract_multiple_strings():
    code = '''
ait("Hello")
ait("World", context="greeting")
ait_plural("{count} item", "{count} items", count=n)
'''
    result = extract_strings(code, "test.py")
    assert len(result) == 3


def test_extract_no_matches():
    code = 'print("Hello")'
    result = extract_strings(code, "test.py")
    assert len(result) == 0


def test_extract_includes_line_numbers():
    code = 'line1\nait("Hello")\nline3'
    result = extract_strings(code, "test.py")
    assert result[0]["line"] == 2


def test_scan_directory(tmp_path):
    (tmp_path / "app.py").write_text('ait("Hello")\nait("World")')
    (tmp_path / "views.py").write_text('ait("Hello")')  # duplicate
    (tmp_path / "template.html").write_text('{% ait "Events" %}')
    result = scan_directory([tmp_path])
    # Hello should be deduped, so 3 unique strings
    texts = [e.get("text") for e in result if not e.get("plural")]
    assert "Hello" in texts
    assert "World" in texts
    assert "Events" in texts
    assert len(result) == 3


def test_scan_directory_dedup_with_files(tmp_path):
    (tmp_path / "a.py").write_text('ait("Hello")')
    (tmp_path / "b.py").write_text('ait("Hello")')
    result = scan_directory([tmp_path])
    assert len(result) == 1
    assert len(result[0]["files"]) == 2


def test_scan_directory_skips_node_modules(tmp_path):
    nm = tmp_path / "node_modules"
    nm.mkdir()
    (nm / "dep.js").write_text('ait("Hidden")')
    (tmp_path / "app.py").write_text('ait("Visible")')
    result = scan_directory([tmp_path])
    assert len(result) == 1
    assert result[0]["text"] == "Visible"


def test_scan_directory_skips_venv(tmp_path):
    venv = tmp_path / ".venv"
    venv.mkdir()
    (venv / "lib.py").write_text('ait("Hidden")')
    (tmp_path / "app.py").write_text('ait("Visible")')
    result = scan_directory([tmp_path])
    assert len(result) == 1


def test_scan_directory_filters_extensions(tmp_path):
    (tmp_path / "readme.md").write_text('ait("Not a code file")')
    (tmp_path / "app.py").write_text('ait("Code file")')
    result = scan_directory([tmp_path])
    assert len(result) == 1
    assert result[0]["text"] == "Code file"


def test_scan_directory_plural_dedup(tmp_path):
    (tmp_path / "a.py").write_text('ait_plural("{count} msg", "{count} msgs", count=n)')
    (tmp_path / "b.py").write_text('ait_plural("{count} msg", "{count} msgs", count=n)')
    result = scan_directory([tmp_path])
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert len(result[0]["files"]) == 2


def test_extract_t_from_transduck_react_import():
    code = "import { t } from 'transduck/react';\nt(\"Hello\")\nt(\"Book\", \"Hotel booking\")"
    result = extract_strings(code, "test.tsx")
    assert len(result) == 2
    assert result[0]["text"] == "Hello"
    assert result[1]["text"] == "Book"
    assert result[1]["context"] == "Hotel booking"


def test_no_extract_t_without_transduck_import():
    code = "import { t } from 'i18next';\nt(\"Hello\")"
    result = extract_strings(code, "test.tsx")
    assert len(result) == 0


def test_extract_tPlural_from_transduck_react_import():
    code = "import { tPlural } from 'transduck/react';\ntPlural(\"{count} item\", \"{count} items\", 5)"
    result = extract_strings(code, "test.tsx")
    assert len(result) == 1
    assert result[0]["plural"] is True


def test_extract_multiline_python_implicit_concat():
    code = '''ait(
    "This is a long "
    "paragraph that spans "
    "multiple lines"
)'''
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "This is a long paragraph that spans multiple lines"


def test_extract_multiline_with_context():
    code = '''ait(
    "This is a long "
    "paragraph",
    context="Some context"
)'''
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "This is a long paragraph"
    assert result[0]["context"] == "Some context"


def test_extract_multiline_js_plus_concat():
    code = """ait(
    "This is a long " +
    "paragraph that spans " +
    "multiple lines"
)"""
    result = extract_strings(code, "test.js")
    assert len(result) == 1
    assert result[0]["text"] == "This is a long paragraph that spans multiple lines"


def test_extract_multiline_plural():
    code = '''ait_plural(
    "{count} long item "
    "description here",
    "{count} long items "
    "description here",
    count=n
)'''
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} long item description here"
    assert result[0]["other"] == "{count} long items description here"


def test_extract_django_plural_tag():
    code = '{% ait_plural "{count} night" "{count} nights" %}'
    result = extract_strings(code, "test.html")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} night"
    assert result[0]["other"] == "{count} nights"
    assert result[0].get("context") is None


def test_extract_django_plural_tag_with_context():
    code = '{% ait_plural "{count} night" "{count} nights" context="Hotel stay duration" %}'
    result = extract_strings(code, "test.html")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} night"
    assert result[0]["other"] == "{count} nights"
    assert result[0]["context"] == "Hotel stay duration"


def test_extract_django_plural_tag_single_quotes():
    code = "{% ait_plural '{count} item' '{count} items' %}"
    result = extract_strings(code, "test.jinja2")
    assert len(result) == 1
    assert result[0]["plural"] is True
    assert result[0]["one"] == "{count} item"
    assert result[0]["other"] == "{count} items"


def test_extract_django_plural_not_in_py():
    """Django template tags should only match in template files."""
    code = '{% ait_plural "{count} night" "{count} nights" %}'
    result = extract_strings(code, "test.py")
    assert len(result) == 0


def test_extract_multiline_single_quotes():
    code = """ait(
    'This is a long '
    'paragraph'
)"""
    result = extract_strings(code, "test.py")
    assert len(result) == 1
    assert result[0]["text"] == "This is a long paragraph"
