"""Tests for the people page routes and action handlers."""

from datetime import date
from uuid import uuid4

import pytest

from transcription.db import session_scope
from transcription.db.models import Document, DocumentPerson, DocumentPersonRole, Person


@pytest.mark.integration
class TestPeoplePageRendering:
    """Verify people routes render expected CRUD read states."""

    def test_people_page_renders_empty_state(self, app_client):
        _, client = app_client

        response = client.get("/ui/people")

        assert response.status_code == 200
        assert "People" in response.text
        assert "Create new person" in response.text
        assert "No person records found in repository." in response.text

    @pytest.mark.asyncio
    async def test_people_page_lists_seeded_people(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            session.add(Person(full_name="Ada Lovelace", display_name="Ada"))
            await session.commit()

        response = client.get("/ui/people")

        assert response.status_code == 200
        assert "Ada Lovelace" in response.text
        assert "Ada" in response.text

    def test_person_create_page_renders_fields(self, app_client):
        _, client = app_client

        response = client.get("/ui/people/new")

        assert response.status_code == 200
        assert "Create Person Record" in response.text
        assert "Full name is required." in response.text
        assert "Birth date (YYYY-MM-DD)" in response.text
        assert "Death date (YYYY-MM-DD)" in response.text
        assert "Biography" in response.text
        assert "Save person" in response.text

    @pytest.mark.asyncio
    async def test_person_detail_page_renders_metadata_and_empty_links(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            person = Person(
                full_name="Grace Hopper",
                display_name="Grace",
                maiden_name="Murray",
                birth_date=date(1906, 12, 9),
                birth_date_raw="1906",
                birth_place="New York",
                death_date=date(1992, 1, 1),
                death_date_raw="1992",
                death_place="Arlington",
                biography="Computer pioneer",
                portrait_path="/images/grace.jpg",
            )
            session.add(person)
            await session.commit()
            person_id = str(person.id)

        response = client.get(f"/ui/people/{person_id}")

        assert response.status_code == 200
        assert "Grace Hopper" in response.text
        assert "Full Name:" in response.text
        assert "Display Name:" in response.text
        assert "Maiden Name:" in response.text
        assert "Birth Date:" in response.text
        assert "1906-12-09" in response.text
        assert "Death Date:" in response.text
        assert "1992-01-01" in response.text
        assert "biography" in response.text.lower()
        assert "Computer pioneer" in response.text
        assert "Created:" in response.text
        assert "Updated:" in response.text
        assert "No linked documents yet." in response.text

    @pytest.mark.asyncio
    async def test_person_detail_page_resolves_relative_portrait_path(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            person = Person(
                full_name="Portrait Person",
                portrait_path="portraits/person/seeded.png",
            )
            session.add(person)
            await session.commit()
            person_id = str(person.id)

        response = client.get(f"/ui/people/{person_id}")

        assert response.status_code == 200
        assert "/uploads/portraits/person/seeded.png" in response.text

    @pytest.mark.asyncio
    async def test_person_detail_page_renders_linked_documents(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            person = Person(full_name="Linked Person")
            document = Document(name="Linked Document", document_type="letter")
            session.add_all([person, document])
            await session.flush()

            session.add(
                DocumentPerson(
                    document_id=document.id,
                    person_id=person.id,
                    role=DocumentPersonRole.AUTHOR,
                )
            )
            await session.commit()
            person_id = str(person.id)

        response = client.get(f"/ui/people/{person_id}")

        assert response.status_code == 200
        assert "Linked Document" in response.text
        assert "Role: author" in response.text

    def test_person_detail_page_handles_invalid_id(self, app_client):
        _, client = app_client

        response = client.get("/ui/people/not-a-uuid")

        assert response.status_code == 200
        assert "Invalid person id" in response.text

    def test_person_detail_page_handles_missing_person(self, app_client):
        _, client = app_client

        response = client.get(f"/ui/people/{uuid4()}")

        assert response.status_code == 200
        assert "Person not found" in response.text

    @pytest.mark.asyncio
    async def test_person_edit_page_renders_expected_fields(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            person = Person(full_name="Editable Person", display_name="EP")
            session.add(person)
            await session.commit()
            person_id = str(person.id)

        response = client.get(f"/ui/people/{person_id}/edit")

        assert response.status_code == 200
        assert "Edit Person Record" in response.text
        assert "Full name is required." in response.text
        assert "Editable Person" in response.text
        assert "Save changes" in response.text

    @pytest.mark.asyncio
    async def test_person_delete_page_shows_confirmation_when_unlinked(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            person = Person(full_name="Safe Delete")
            session.add(person)
            await session.commit()
            person_id = str(person.id)

        response = client.get(f"/ui/people/{person_id}/delete")

        assert response.status_code == 200
        assert "Delete Person Record" in response.text
        assert "This action permanently deletes the person record." in response.text
        assert "Delete person permanently" in response.text