"""组织管理API测试 - 验证 /api/v1/organization/* 端点"""
import uuid

import pytest
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession, create_async_engine
from sqlalchemy.pool import StaticPool

from app.database import Base
from app.main import app
from app.models.user import User
from app.models.organization import Organization, OrgMember
from app.api.deps import get_current_user, get_db


@pytest_asyncio.fixture
async def async_engine():
    engine = create_async_engine(
        "sqlite+aiosqlite:///:memory:",
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield engine
    await engine.dispose()


@pytest_asyncio.fixture
async def async_session(async_engine):
    async_session_maker = async_sessionmaker(
        async_engine,
        class_=AsyncSession,
        expire_on_commit=False,
        autoflush=False,
        autocommit=False,
    )
    async with async_session_maker() as session:
        yield session


@pytest_asyncio.fixture
async def test_user(async_session):
    user = User(
        id=uuid.uuid4(),
        email="test@example.com",
        password_hash="hashed_password",
        name="Test User",
        plan="free",
        max_queries=5,
        is_active=True,
        email_verified=True,
    )
    async_session.add(user)
    await async_session.commit()
    await async_session.refresh(user)
    return user


@pytest_asyncio.fixture
async def test_organization(async_session, test_user):
    org = Organization(
        id=uuid.uuid4(),
        name="Test Organization",
        slug="test-org",
        plan="free",
    )
    async_session.add(org)
    await async_session.flush()

    test_user.organization_id = org.id
    async_session.add(test_user)

    membership = OrgMember(
        id=uuid.uuid4(),
        organization_id=org.id,
        user_id=test_user.id,
        role="owner",
    )
    async_session.add(membership)
    await async_session.commit()
    await async_session.refresh(org)
    return org


@pytest_asyncio.fixture
async def async_client(async_session, test_user):
    async def override_get_db():
        yield async_session

    async def override_get_current_user():
        return test_user

    app.dependency_overrides[get_db] = override_get_db
    app.dependency_overrides[get_current_user] = override_get_current_user

    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        yield client

    app.dependency_overrides.clear()


class TestOrganizationRoutes:
    """组织管理API端点测试"""

    @pytest.mark.asyncio
    async def test_routes_are_registered(self):
        """验证组织管理路由已正确注册到app"""
        from app.main import app as main_app

        org_routes = [
            route.path for route in main_app.routes
            if hasattr(route, 'path') and route.path.startswith('/api/v1/organization')
        ]
        print(f"\n已注册的组织路由: {org_routes}")
        assert '/api/v1/organization/info' in org_routes, "路由未注册"
        assert '/api/v1/organization/members' in org_routes, "路由未注册"
        assert '/api/v1/organization/members/invite' in org_routes, "路由未注册"

    @pytest.mark.asyncio
    async def test_direct_endpoint_call(self, async_session, test_user, test_organization):
        """直接测试端点调用"""
        async def override_get_db():
            yield async_session

        async def override_get_current_user():
            return test_user

        from app.main import app as test_app
        test_app.dependency_overrides[get_db] = override_get_db
        test_app.dependency_overrides[get_current_user] = override_get_current_user

        transport = ASGITransport(app=test_app)
        async with AsyncClient(transport=transport, base_url="http://test") as client:
            # Check which routes are available
            available_routes = [r.path for r in test_app.routes if hasattr(r, 'path') and 'organization' in r.path]
            print(f"\n测试app中的组织路由: {available_routes}")

            response = await client.get("/api/v1/organization/info")
            print(f"Response status: {response.status_code}")
            print(f"Response: {response.text[:200]}")
            assert response.status_code == 200

        test_app.dependency_overrides.clear()

    @pytest.mark.asyncio
    async def test_organization_info_endpoint_exists(self, async_client, test_organization):
        """验证 /api/v1/organization/info 端点存在并返回200"""
        response = await async_client.get("/api/v1/organization/info")
        assert response.status_code == 200, f"期望返回200，实际返回 {response.status_code}"
        data = response.json()
        assert "id" in data
        assert "name" in data
        assert "slug" in data

    @pytest.mark.asyncio
    async def test_organization_members_endpoint_exists(self, async_client, test_organization):
        """验证 /api/v1/organization/members 端点存在并返回200"""
        response = await async_client.get("/api/v1/organization/members")
        assert response.status_code == 200, f"期望返回200，实际返回 {response.status_code}"
        data = response.json()
        assert isinstance(data, list)

    @pytest.mark.asyncio
    async def test_organization_members_invite_endpoint_exists(self, async_client, test_organization, async_session):
        """验证 /api/v1/organization/members/invite 端点存在"""
        invite_user = User(
            id=uuid.uuid4(),
            email="newuser@example.com",
            password_hash="hashed_password",
            name="New User",
            plan="free",
            max_queries=5,
            is_active=True,
            email_verified=True,
        )
        async_session.add(invite_user)
        await async_session.commit()

        response = await async_client.post(
            "/api/v1/organization/members/invite",
            json={"email": "newuser@example.com", "role": "viewer"}
        )
        assert response.status_code == 201, f"期望返回201，实际返回 {response.status_code}"

    @pytest.mark.asyncio
    async def test_organization_member_role_endpoint_exists(self, async_client, test_organization, async_session, test_user):
        """验证 /api/v1/organization/members/{id}/role 端点存在"""
        new_user = User(
            id=uuid.uuid4(),
            email="member@example.com",
            password_hash="hashed_password",
            name="Member User",
            plan="free",
            max_queries=5,
            is_active=True,
            email_verified=True,
        )
        async_session.add(new_user)
        await async_session.flush()

        membership = OrgMember(
            id=uuid.uuid4(),
            organization_id=test_organization.id,
            user_id=new_user.id,
            role="viewer",
        )
        async_session.add(membership)
        await async_session.commit()

        response = await async_client.put(
            f"/api/v1/organization/members/{new_user.id}/role",
            json={"role": "admin"}
        )
        assert response.status_code == 200, f"期望返回200，实际返回 {response.status_code}"

    @pytest.mark.asyncio
    async def test_organization_member_delete_endpoint_exists(self, async_client, test_organization, async_session):
        """验证 /api/v1/organization/members/{id} 端点存在"""
        new_user = User(
            id=uuid.uuid4(),
            email="todelete@example.com",
            password_hash="hashed_password",
            name="Delete User",
            plan="free",
            max_queries=5,
            is_active=True,
            email_verified=True,
        )
        async_session.add(new_user)
        await async_session.flush()

        membership = OrgMember(
            id=uuid.uuid4(),
            organization_id=test_organization.id,
            user_id=new_user.id,
            role="viewer",
        )
        async_session.add(membership)
        await async_session.commit()

        response = await async_client.delete(f"/api/v1/organization/members/{new_user.id}")
        assert response.status_code == 204, f"期望返回204，实际返回 {response.status_code}"

    @pytest.mark.asyncio
    async def test_user_without_organization_returns_404(self, async_client, test_user, async_session):
        """验证未加入组织的用户访问 /api/v1/organization/info 返回404"""
        response = await async_client.get("/api/v1/organization/info")
        assert response.status_code == 404, f"期望返回404，实际返回 {response.status_code}"

    @pytest.mark.asyncio
    async def test_unauthorized_access(self, async_session):
        """验证未授权访问返回401"""
        async def override_get_db():
            yield async_session

        app.dependency_overrides[get_db] = override_get_db
        app.dependency_overrides.pop(get_current_user, None)

        transport = ASGITransport(app=app)
        async with AsyncClient(transport=transport, base_url="http://test") as client:
            response = await client.get("/api/v1/organization/info")
            assert response.status_code == 401, f"期望返回401，实际返回 {response.status_code}"

        app.dependency_overrides.clear()
