"""High priority people API tests."""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest
from fastapi.testclient import TestClient

if TYPE_CHECKING:
    from sqlalchemy.orm import Session
    from backend.db.models import Person, Face, User


class TestPeopleListing:
    """Test people listing endpoints."""

    def test_list_people_success(
        self,
        test_client: TestClient,
        test_person: "Person",
    ):
        """Verify people list retrieval."""
        response = test_client.get("/api/v1/people")
        
        assert response.status_code == 200
        data = response.json()
        assert "items" in data
        assert "total" in data
        assert len(data["items"]) > 0

    def test_list_people_with_last_name_filter(
        self,
        test_client: TestClient,
        test_person: "Person",
    ):
        """Verify last name filtering."""
        response = test_client.get(
            "/api/v1/people",
            params={"last_name": "Doe"},
        )
        
        assert response.status_code == 200
        data = response.json()
        assert "items" in data
        # All items should have last_name containing "Doe"
        for item in data["items"]:
            assert "Doe" in item["last_name"]

    def test_list_people_with_faces_success(
        self,
        test_client: TestClient,
        test_person: "Person",
        test_face: "Face",
        test_db_session: "Session",
    ):
        """Verify people with face counts."""
        test_face.person_id = test_person.id
        test_db_session.commit()
        
        response = test_client.get("/api/v1/people/with-faces")
        
        assert response.status_code == 200
        data = response.json()
        assert "items" in data
        # Find our person
        person_item = next(
            (item for item in data["items"] if item["id"] == test_person.id),
            None
        )
        if person_item:
            assert person_item["face_count"] >= 1


class TestPeopleCRUD:
    """Test people CRUD endpoints."""

    def test_create_person_success(
        self,
        test_client: TestClient,
    ):
        """Verify person creation."""
        response = test_client.post(
            "/api/v1/people",
            json={
                "first_name": "Jane",
                "last_name": "Smith",
            },
        )
        
        assert response.status_code == 201
        data = response.json()
        assert data["first_name"] == "Jane"
        assert data["last_name"] == "Smith"
        assert "id" in data

    def test_create_person_with_middle_name(
        self,
        test_client: TestClient,
    ):
        """Verify optional middle_name."""
        response = test_client.post(
            "/api/v1/people",
            json={
                "first_name": "Jane",
                "last_name": "Smith",
                "middle_name": "Middle",
            },
        )
        
        assert response.status_code == 201
        data = response.json()
        assert data["middle_name"] == "Middle"

    def test_create_person_strips_whitespace(
        self,
        test_client: TestClient,
    ):
        """Verify name trimming."""
        response = test_client.post(
            "/api/v1/people",
            json={
                "first_name": "  Jane  ",
                "last_name": "  Smith  ",
            },
        )
        
        assert response.status_code == 201
        data = response.json()
        assert data["first_name"] == "Jane"
        assert data["last_name"] == "Smith"

    def test_get_person_by_id_success(
        self,
        test_client: TestClient,
        test_person: "Person",
    ):
        """Verify person retrieval."""
        response = test_client.get(f"/api/v1/people/{test_person.id}")
        
        assert response.status_code == 200
        data = response.json()
        assert data["id"] == test_person.id
        assert data["first_name"] == test_person.first_name

    def test_get_person_by_id_not_found(
        self,
        test_client: TestClient,
    ):
        """Verify 404 for non-existent person."""
        response = test_client.get("/api/v1/people/99999")
        
        assert response.status_code == 404

    def test_update_person_success(
        self,
        test_client: TestClient,
        test_person: "Person",
    ):
        """Verify person update."""
        response = test_client.put(
            f"/api/v1/people/{test_person.id}",
            json={
                "first_name": "Updated",
                "last_name": "Name",
            },
        )
        
        assert response.status_code == 200
        data = response.json()
        assert data["first_name"] == "Updated"
        assert data["last_name"] == "Name"

    def test_update_person_not_found(
        self,
        test_client: TestClient,
    ):
        """Verify 404 when updating non-existent person."""
        response = test_client.put(
            "/api/v1/people/99999",
            json={
                "first_name": "Updated",
                "last_name": "Name",
            },
        )
        
        assert response.status_code == 404

    def test_delete_person_success(
        self,
        test_client: TestClient,
        test_db_session: "Session",
    ):
        """Verify person deletion."""
        from backend.db.models import Person
        from datetime import datetime
        
        # Create a person to delete
        person = Person(
            first_name="Delete",
            last_name="Me",
            created_date=datetime.utcnow(),
        )
        test_db_session.add(person)
        test_db_session.commit()
        test_db_session.refresh(person)
        
        response = test_client.delete(f"/api/v1/people/{person.id}")
        
        # DELETE operations return 204 No Content (standard REST convention)
        assert response.status_code == 204

    def test_delete_person_not_found(
        self,
        test_client: TestClient,
    ):
        """Verify 404 for non-existent person."""
        response = test_client.delete("/api/v1/people/99999")
        
        assert response.status_code == 404


class TestPeopleFaces:
    """Test people faces endpoints."""

    def test_get_person_faces_success(
        self,
        test_client: TestClient,
        test_person: "Person",
        test_face: "Face",
        test_db_session: "Session",
    ):
        """Verify faces retrieval for person."""
        test_face.person_id = test_person.id
        test_db_session.commit()
        
        response = test_client.get(f"/api/v1/people/{test_person.id}/faces")
        
        assert response.status_code == 200
        data = response.json()
        assert "items" in data
        assert len(data["items"]) > 0

    def test_get_person_faces_no_faces(
        self,
        test_client: TestClient,
        test_person: "Person",
    ):
        """Verify empty list when no faces."""
        response = test_client.get(f"/api/v1/people/{test_person.id}/faces")
        
        assert response.status_code == 200
        data = response.json()
        assert "items" in data
        # May be empty or have faces depending on test setup

    def test_get_person_faces_person_not_found(
        self,
        test_client: TestClient,
    ):
        """Verify 404 for non-existent person."""
        response = test_client.get("/api/v1/people/99999/faces")
        
        assert response.status_code == 404

