"""Tests for target lists CRUD."""
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.team import Team
from app.models.user import User
from sqlalchemy import select


@pytest.fixture
async def auth_headers(client: AsyncClient, test_db: AsyncSession, test_user: dict):
    """Override auth_headers to ensure the test user has a team_id assigned."""
    # Fetch the user from DB and assign a team
    result = await test_db.execute(select(User).where(User.email == test_user["email"]))
    user = result.scalar_one()

    # Create a team and assign the user to it
    team = Team(name="Test Team")
    test_db.add(team)
    await test_db.flush()

    user.team_id = team.id
    await test_db.commit()

    # Re-login to get a fresh token
    login_data = {
        "email": test_user["email"],
        "password": test_user["password"],
    }
    resp = await client.post("/api/v1/auth/login/json", json=login_data)
    assert resp.status_code == 200
    token_data = resp.json()
    return {"Authorization": f"Bearer {token_data['access_token']}"}


@pytest.mark.asyncio
async def test_create_target_list(client: AsyncClient, auth_headers: dict):
    resp = await client.post(
        "/api/v1/target-lists/",
        json={
            "name": "RDS Farm A",
            "description": "Production RDS servers",
            "targets": [
                {"label": "RDS-01", "notes": "192.168.1.10"},
                {"label": "RDS-02", "notes": "192.168.1.11"},
            ],
        },
        headers=auth_headers,
    )
    assert resp.status_code == 201, resp.text
    data = resp.json()
    assert data["name"] == "RDS Farm A"
    assert len(data["targets"]) == 2


@pytest.mark.asyncio
async def test_list_target_lists(client: AsyncClient, auth_headers: dict):
    resp = await client.get("/api/v1/target-lists/", headers=auth_headers)
    assert resp.status_code == 200
    assert isinstance(resp.json(), list)


@pytest.mark.asyncio
async def test_get_target_list(client: AsyncClient, auth_headers: dict):
    create = await client.post(
        "/api/v1/target-lists/",
        json={"name": "Get Test", "targets": [{"label": "SRV-01"}]},
        headers=auth_headers,
    )
    list_id = create.json()["id"]
    resp = await client.get(f"/api/v1/target-lists/{list_id}", headers=auth_headers)
    assert resp.status_code == 200
    assert resp.json()["name"] == "Get Test"


@pytest.mark.asyncio
async def test_update_target_list(client: AsyncClient, auth_headers: dict):
    create = await client.post(
        "/api/v1/target-lists/",
        json={"name": "Old Name", "targets": [{"label": "SRV-01"}]},
        headers=auth_headers,
    )
    list_id = create.json()["id"]
    resp = await client.put(
        f"/api/v1/target-lists/{list_id}",
        json={"name": "New Name", "targets": [{"label": "SRV-01"}, {"label": "SRV-02"}]},
        headers=auth_headers,
    )
    assert resp.status_code == 200
    assert resp.json()["name"] == "New Name"
    assert len(resp.json()["targets"]) == 2


@pytest.mark.asyncio
async def test_delete_target_list(client: AsyncClient, auth_headers: dict):
    create = await client.post(
        "/api/v1/target-lists/",
        json={"name": "To Delete", "targets": [{"label": "X"}]},
        headers=auth_headers,
    )
    list_id = create.json()["id"]
    resp = await client.delete(f"/api/v1/target-lists/{list_id}", headers=auth_headers)
    assert resp.status_code == 204

    get = await client.get(f"/api/v1/target-lists/{list_id}", headers=auth_headers)
    assert get.status_code == 404

@pytest.mark.asyncio
async def test_cannot_access_other_teams_list(client: AsyncClient, auth_headers: dict, test_db):
    """User from team B cannot access team A's list."""
    import uuid
    from app.models.team import Team
    from app.models.user import User
    from app.core.security import get_password_hash

    # Create team A list using existing auth_headers
    create = await client.post(
        "/api/v1/target-lists/",
        json={"name": "Team A List", "targets": [{"label": "SRV-A"}]},
        headers=auth_headers,
    )
    assert create.status_code == 201
    list_id = create.json()["id"]

    # Create a separate team B with its own user
    team_b = Team(name=f"Team B {uuid.uuid4()}")
    test_db.add(team_b)
    await test_db.flush()

    user_b = User(
        email=f"userb_{uuid.uuid4()}@test.com",
        password_hash=get_password_hash("password123"),
        name="User B",
        is_active=True,
        team_id=team_b.id,
        role="engineer",
    )
    test_db.add(user_b)
    await test_db.flush()

    # Get auth token for user B
    login = await client.post(
        "/api/v1/auth/login/json",
        json={"email": user_b.email, "password": "password123"},
    )
    assert login.status_code == 200
    token_b = login.json()["access_token"]
    headers_b = {"Authorization": f"Bearer {token_b}"}

    # Team B cannot access Team A's list
    resp = await client.get(f"/api/v1/target-lists/{list_id}", headers=headers_b)
    assert resp.status_code == 404
