import os
import tempfile

import pytest
from fastapi.testclient import TestClient


# We need to set up a temporary database for testing
# This ensures that our tests are isolated and don't affect the main database.
@pytest.fixture(scope="module")
def temp_db_path():
    """Create a temporary database for the test session."""
    # Create a temporary file
    fd, path = tempfile.mkstemp(suffix=".db")
    os.close(fd)  # Close the file descriptor
    yield path
    # Teardown: remove the file after the tests are done
    os.unlink(path)


@pytest.fixture(scope="module")
def client(temp_db_path):
    """Provide a TestClient for the FastAPI app, configured with a temporary DB."""
    # Set an environment variable to point to the temporary database
    # The CardCollection in api.py will pick this up when it initializes.
    os.environ["MCARD_DB_PATH"] = temp_db_path

    # Import the app *after* the environment variable is set
    from mcard.api import app

    with TestClient(app) as test_client:
        yield test_client

    # Clean up the environment variable
    del os.environ["MCARD_DB_PATH"]


def test_store_and_retrieve_card(client):
    """Test storing a new content card and then retrieving it."""
    # 1. Store a new card
    content = b"This is a test card for API testing."
    response = client.post(
        "/content/cards", files={"content": ("test.txt", content, "text/plain")}
    )
    assert response.status_code == 201
    data = response.json()
    assert "hash" in data
    assert data["content_type"] == "text/plain"
    card_hash = data["hash"]

    # 2. Retrieve the card by its hash
    response = client.get(f"/content/cards/{card_hash}")
    assert response.status_code == 200
    retrieved_data = response.json()
    assert retrieved_data["hash"] == card_hash
    assert retrieved_data["content_type"] == "text/plain"


def test_list_cards(client):
    """Test listing cards with pagination."""
    # First, ensure there's at least one card
    client.post(
        "/content/cards",
        files={"content": ("list_test.txt", b"Another test card.", "text/plain")},
    )

    # List all cards
    response = client.get("/content/cards")
    assert response.status_code == 200
    data = response.json()
    assert "items" in data
    assert data["total_items"] > 0
    assert len(data["items"]) > 0


def test_delete_card(client):
    """Test creating a card and then deleting it."""
    # 1. Create a card to be deleted
    content = b"This card will be deleted."
    response = client.post(
        "/content/cards", files={"content": ("delete_me.txt", content, "text/plain")}
    )
    assert response.status_code == 201
    card_hash = response.json()["hash"]

    # 2. Delete the card
    response = client.delete(f"/content/cards/{card_hash}")
    assert response.status_code == 204

    # 3. Verify the card is gone
    response = client.get(f"/content/cards/{card_hash}")
    assert response.status_code == 404


def test_get_nonexistent_card(client):
    """Test that retrieving a nonexistent card returns a 404 error."""
    non_existent_hash = "0" * 64  # A hash that is extremely unlikely to exist
    response = client.get(f"/content/cards/{non_existent_hash}")
    assert response.status_code == 404
