"""Project list metadata uses real DB state for activity and pending review counts."""

from __future__ import annotations

import uuid
from collections.abc import AsyncIterator
from datetime import UTC, datetime, timedelta

import pytest
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from ww_core.domain.project_repo import SqlProjectRepo
from ww_db import get_sessionmaker
from ww_db.models import Chapter, ChapterReview, Project, User


@pytest.fixture
async def sm() -> AsyncIterator[async_sessionmaker[AsyncSession]]:
    get_sessionmaker.cache_clear()
    maker = get_sessionmaker()
    try:
        async with maker() as probe:
            await probe.execute(select(1))
    except Exception:
        pytest.skip("postgres not reachable")
    yield maker
    await maker.kw["bind"].dispose()
    get_sessionmaker.cache_clear()


async def _cleanup(
    sm: async_sessionmaker[AsyncSession], owner_id: uuid.UUID, project_id: uuid.UUID
) -> None:
    async with sm() as session:
        await session.execute(delete(ChapterReview).where(ChapterReview.project_id == project_id))
        await session.execute(delete(Chapter).where(Chapter.project_id == project_id))
        await session.execute(delete(Project).where(Project.id == project_id))
        await session.execute(delete(User).where(User.id == owner_id))
        await session.commit()


async def _project_view(
    sm: async_sessionmaker[AsyncSession], owner_id: uuid.UUID, project_id: uuid.UUID
):
    async with sm() as session:
        view = await SqlProjectRepo(session).get(owner_id, project_id)
        assert view is not None
        listed = await SqlProjectRepo(session).list_for_owner(owner_id)
        listed_view = next((item for item in listed if item.id == project_id), None)
        assert listed_view is not None
        assert listed_view.pending_review_count == view.pending_review_count
        assert listed_view.updated_at == view.updated_at
        return view


async def test_project_metadata_tracks_review_and_acceptance_state(
    sm: async_sessionmaker[AsyncSession],
) -> None:
    owner_id = uuid.uuid4()
    project_id = uuid.uuid4()
    base = datetime(2026, 6, 1, tzinfo=UTC)

    await _cleanup(sm, owner_id, project_id)
    try:
        async with sm() as session:
            session.add(
                User(
                    id=owner_id,
                    email=f"{owner_id}@example.test",
                    display_name="metadata test",
                )
            )
            await session.commit()

        async with sm() as session:
            session.add(
                Project(
                    id=project_id,
                    owner_id=owner_id,
                    title="元数据测试",
                    created_at=base,
                    updated_at=base,
                )
            )
            await session.commit()

        async with sm() as session:
            session.add(
                Chapter(
                    project_id=project_id,
                    volume=1,
                    chapter_no=1,
                    content="草稿一",
                    status="draft",
                    version=1,
                    created_at=base + timedelta(hours=1),
                    updated_at=base + timedelta(hours=1),
                )
            )
            await session.commit()

        view = await _project_view(sm, owner_id, project_id)
        assert view.pending_review_count == 1
        assert view.updated_at == base + timedelta(hours=1)

        async with sm() as session:
            session.add(
                ChapterReview(
                    project_id=project_id,
                    chapter_no=1,
                    chapter_version=1,
                    conflicts=[],
                    foreshadow_sug=[],
                    created_at=base + timedelta(hours=2),
                )
            )
            await session.commit()

        view = await _project_view(sm, owner_id, project_id)
        assert view.pending_review_count == 0
        assert view.updated_at == base + timedelta(hours=2)

        async with sm() as session:
            session.add(
                Chapter(
                    project_id=project_id,
                    volume=1,
                    chapter_no=1,
                    content="终稿一",
                    status="accepted",
                    version=2,
                    created_at=base + timedelta(hours=3),
                    updated_at=base + timedelta(hours=3),
                )
            )
            await session.commit()

        view = await _project_view(sm, owner_id, project_id)
        assert view.pending_review_count == 0
        assert view.updated_at == base + timedelta(hours=3)

        async with sm() as session:
            draft = (
                await session.execute(
                    select(Chapter).where(
                        Chapter.project_id == project_id,
                        Chapter.chapter_no == 1,
                        Chapter.version == 1,
                    )
                )
            ).scalar_one()
            draft.content = "验收后再改草稿"
            draft.updated_at = base + timedelta(hours=4)
            await session.commit()

        view = await _project_view(sm, owner_id, project_id)
        assert view.pending_review_count == 1
        assert view.updated_at == base + timedelta(hours=4)
    finally:
        await _cleanup(sm, owner_id, project_id)
