"""
Test for Issue #396: time_expr natural language parsing fails for 'last week', '3 days ago'

This test reproduces the reported issue where time_expr parameter fails for certain
natural language expressions but works for others.
"""
import os
import pytest
import asyncio
from datetime import datetime, timedelta, date
from mcp_memory_service.storage.sqlite_vec import SqliteVecMemoryStorage
from mcp_memory_service.models import Memory
from mcp_memory_service.utils.hashing import generate_content_hash


@pytest.mark.asyncio
async def test_time_expr_parsing_issue_396(temp_db_path):
    """Test that time_expr correctly parses 'last week' and '3 days ago'."""

    # Create storage with temp database
    db_file = os.path.join(temp_db_path, "test_issue_396.db")
    storage = SqliteVecMemoryStorage(db_path=db_file)
    await storage.initialize()

    # Store test memories across different days
    today = datetime.now()

    # Memory from yesterday (should match "yesterday")
    content_yesterday = "Memory from yesterday"
    yesterday_timestamp = (today - timedelta(days=1)).timestamp()
    memory_yesterday = Memory(
        content=content_yesterday,
        content_hash=generate_content_hash(content_yesterday),
        tags=["test", "__test__"],
        created_at=yesterday_timestamp
    )
    await storage.store(memory_yesterday)

    # Memory from 3 days ago (should match "3 days ago")
    content_3_days = "Memory from 3 days ago"
    three_days_timestamp = (today - timedelta(days=3)).timestamp()
    memory_3_days = Memory(
        content=content_3_days,
        content_hash=generate_content_hash(content_3_days),
        tags=["test", "__test__"],
        created_at=three_days_timestamp
    )
    await storage.store(memory_3_days)

    # Memory from last week (should match "last week")
    content_last_week = "Memory from last week"
    last_week_timestamp = (today - timedelta(days=7)).timestamp()
    memory_last_week = Memory(
        content=content_last_week,
        content_hash=generate_content_hash(content_last_week),
        tags=["test", "__test__"],
        created_at=last_week_timestamp
    )
    await storage.store(memory_last_week)

    # Memory from 2 weeks ago (should NOT match "last week" but should match "3 days ago" range in some searches)
    content_2_weeks = "Memory from 2 weeks ago"
    two_weeks_timestamp = (today - timedelta(days=14)).timestamp()
    memory_2_weeks = Memory(
        content=content_2_weeks,
        content_hash=generate_content_hash(content_2_weeks),
        tags=["test", "__test__"],
        created_at=two_weeks_timestamp
    )
    await storage.store(memory_2_weeks)

    # Wait a bit for storage to process
    await asyncio.sleep(0.1)

    # Test 1: "yesterday" (reported as working)
    result = await storage.search_memories(
        time_expr="yesterday",
        limit=10
    )
    assert result['total'] >= 1, "Should find at least the yesterday memory"
    yesterday_contents = [m['content'] for m in result['memories']]
    assert any("yesterday" in c.lower() for c in yesterday_contents), "Should find yesterday memory"

    # Test 2: "3 days ago" (reported as failing)
    result = await storage.search_memories(
        time_expr="3 days ago",
        limit=10
    )
    assert result['total'] >= 1, "Should find at least the 3 days ago memory"
    three_days_contents = [m['content'] for m in result['memories']]
    assert any("3 days ago" in c.lower() for c in three_days_contents), "Should find 3 days ago memory"

    # Test 3: "last week" (reported as failing)
    result = await storage.search_memories(
        time_expr="last week",
        limit=10
    )
    assert result['total'] >= 1, "Should find at least the last week memory"
    last_week_contents = [m['content'] for m in result['memories']]
    # Last week should return memories from last Monday-Sunday (not including current week)
    # So it should find the memory from 7 days ago
    assert any("last week" in c.lower() for c in last_week_contents), "Should find last week memory"

    # Test 4: Verify workaround with explicit ISO dates works
    three_days_ago_date = (today - timedelta(days=3)).date()
    result = await storage.search_memories(
        after=three_days_ago_date.isoformat(),
        limit=10
    )
    assert result['total'] >= 2, "Should find yesterday and 3 days ago memories"


@pytest.mark.asyncio
async def test_time_expr_edge_cases(temp_db_path):
    """Test additional time_expr edge cases."""

    db_file = os.path.join(temp_db_path, "test_edge_cases.db")
    storage = SqliteVecMemoryStorage(db_path=db_file)
    await storage.initialize()

    today = datetime.now()

    # Store a test memory
    content = "Test memory for edge cases"
    five_days_timestamp = (today - timedelta(days=5)).timestamp()
    memory = Memory(
        content=content,
        content_hash=generate_content_hash(content),
        tags=["test", "__test__"],
        created_at=five_days_timestamp
    )
    await storage.store(memory)

    await asyncio.sleep(0.1)

    # Test various time expressions
    test_cases = [
        "5 days ago",
        "last 5 days",
        "1 week ago",
    ]

    for time_expr in test_cases:
        result = await storage.search_memories(
            time_expr=time_expr,
            limit=10
        )
        # Don't assert on results, just verify no errors
        assert "error" not in result, f"Should not error for time_expr='{time_expr}'"


if __name__ == "__main__":
    pytest.main([__file__, "-v", "-s"])
