"""
DELETE /asset-libraries/{library_id} 单元测试

覆盖：
- 正常删除空素材库（204）
- 删除含素材的库（同时删除库内素材）
- 素材库不存在（404）
- 无权限访问（403）
"""

from __future__ import annotations

import os
import sys
from pathlib import Path

os.environ.setdefault("JWT_SECRET_KEY", "unit-test-secret-key-for-testing")
os.environ.setdefault("DATABASE_URL", "sqlite:///test.db")

sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "apps" / "api"))

from fastapi import FastAPI
from fastapi.testclient import TestClient

from packages.adapters.in_memory.asset_library_repository import InMemoryAssetLibraryRepository
from packages.adapters.in_memory.asset_repository import InMemoryAssetRepository
from packages.domain import Asset, AssetLibrary, AssetLibraryKind, AssetStatus

# ---------------------------------------------------------------------------
# Stub Project Repository
# ---------------------------------------------------------------------------


class StubProject:
    """最小化 Project stub，支持 can_access"""

    def __init__(self, project_id: str, owner_id: str):
        self.id = project_id
        self._owner_id = owner_id

    def can_access(self, user_id: str) -> bool:
        return user_id == self._owner_id


class StubProjectRepository:
    def __init__(self, projects: dict[str, StubProject] | None = None):
        self._projects = projects or {}

    def find_by_id(self, project_id: str):
        return self._projects.get(project_id)


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _make_auth_user(user_id: str = "user-001"):
    from app.auth import AuthenticatedUser

    from packages.domain.entities import User

    user = User(id=user_id, email="test@example.com", display_name="测试用户")
    return AuthenticatedUser(user=user)


def _create_test_app(
    library_repo: InMemoryAssetLibraryRepository,
    asset_repo: InMemoryAssetRepository,
    project_repo: StubProjectRepository,
    user_id: str = "user-001",
):
    from app.api.routes import asset_libraries as module
    from app.api.routes.asset_libraries import router

    app = FastAPI()
    app.include_router(router, prefix="/api/v1/asset-libraries")

    app.dependency_overrides[module.get_current_user] = lambda: _make_auth_user(user_id)
    app.dependency_overrides[module.get_asset_library_repository] = lambda: library_repo
    app.dependency_overrides[module.get_asset_repository] = lambda: asset_repo
    app.dependency_overrides[module.get_project_repository] = lambda: project_repo

    return app


# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------


class TestDeleteAssetLibrary:
    """DELETE /asset-libraries/{library_id} 测试"""

    def test_delete_empty_library(self):
        """删除空素材库 → 204"""
        from datetime import datetime, timezone

        lib_repo = InMemoryAssetLibraryRepository()
        asset_repo = InMemoryAssetRepository()
        proj_repo = StubProjectRepository({"proj-1": StubProject("proj-1", "user-001")})

        now = datetime.now(timezone.utc)
        library = AssetLibrary(
            id="lib-1",
            project_id="proj-1",
            name="视频素材库",
            kind=AssetLibraryKind.VIDEO,
            asset_count=0,
            total_size=0,
            created_at=now,
            updated_at=now,
        )
        lib_repo.create(library)

        app = _create_test_app(lib_repo, asset_repo, proj_repo)
        client = TestClient(app)

        response = client.delete("/api/v1/asset-libraries/lib-1")
        assert response.status_code == 204

        # 验证库已删除
        assert lib_repo.find_by_id("lib-1") is None

    def test_delete_library_with_assets(self):
        """删除含素材的库 → 库和素材都被删除"""
        from datetime import datetime, timezone

        lib_repo = InMemoryAssetLibraryRepository()
        asset_repo = InMemoryAssetRepository()
        proj_repo = StubProjectRepository({"proj-1": StubProject("proj-1", "user-001")})

        now = datetime.now(timezone.utc)
        library = AssetLibrary(
            id="lib-1",
            project_id="proj-1",
            name="视频素材库",
            kind=AssetLibraryKind.VIDEO,
            asset_count=3,
            total_size=1000,
            created_at=now,
            updated_at=now,
        )
        lib_repo.create(library)

        # 创建 3 个素材
        for i in range(3):
            asset = Asset.create(
                project_id="proj-1",
                library_id="lib-1",
                name=f"video_{i}.mp4",
                storage_key=f"uploads/video_{i}.mp4",
                mime_type="video/mp4",
                status=AssetStatus.READY,
            )
            asset_repo.create(asset)

        # 创建一个不属于该库的素材（不应被删除）
        other_asset = Asset.create(
            project_id="proj-1",
            library_id="lib-other",
            name="other.mp4",
            storage_key="uploads/other.mp4",
            mime_type="video/mp4",
            status=AssetStatus.READY,
        )
        asset_repo.create(other_asset)

        app = _create_test_app(lib_repo, asset_repo, proj_repo)
        client = TestClient(app)

        response = client.delete("/api/v1/asset-libraries/lib-1")
        assert response.status_code == 204

        # 库已删除
        assert lib_repo.find_by_id("lib-1") is None
        # 库内素材已删除
        assert asset_repo.find_by_library("lib-1") == []
        # 其他素材未受影响
        assert asset_repo.get(other_asset.id) is not None

    def test_delete_nonexistent_library(self):
        """删除不存在的素材库 → 404"""
        lib_repo = InMemoryAssetLibraryRepository()
        asset_repo = InMemoryAssetRepository()
        proj_repo = StubProjectRepository({"proj-1": StubProject("proj-1", "user-001")})

        app = _create_test_app(lib_repo, asset_repo, proj_repo)
        client = TestClient(app)

        response = client.delete("/api/v1/asset-libraries/nonexistent-id")
        assert response.status_code == 404
        assert "素材库不存在" in response.json()["detail"]

    def test_delete_library_access_denied(self):
        """无权限用户删除素材库 → 403"""
        from datetime import datetime, timezone

        lib_repo = InMemoryAssetLibraryRepository()
        asset_repo = InMemoryAssetRepository()
        # 项目属于 user-002，当前用户是 user-001
        proj_repo = StubProjectRepository({"proj-1": StubProject("proj-1", "user-002")})

        now = datetime.now(timezone.utc)
        library = AssetLibrary(
            id="lib-1",
            project_id="proj-1",
            name="视频素材库",
            kind=AssetLibraryKind.VIDEO,
            asset_count=0,
            total_size=0,
            created_at=now,
            updated_at=now,
        )
        lib_repo.create(library)

        app = _create_test_app(lib_repo, asset_repo, proj_repo, user_id="user-001")
        client = TestClient(app)

        response = client.delete("/api/v1/asset-libraries/lib-1")
        assert response.status_code == 403
        assert "无权访问该项目" in response.json()["detail"]

        # 库未被删除
        assert lib_repo.find_by_id("lib-1") is not None

    def test_delete_library_project_not_found(self):
        """素材库所属项目不存在 → 404"""
        from datetime import datetime, timezone

        lib_repo = InMemoryAssetLibraryRepository()
        asset_repo = InMemoryAssetRepository()
        # 空的项目仓库，找不到项目
        proj_repo = StubProjectRepository({})

        now = datetime.now(timezone.utc)
        library = AssetLibrary(
            id="lib-1",
            project_id="proj-missing",
            name="视频素材库",
            kind=AssetLibraryKind.VIDEO,
            asset_count=0,
            total_size=0,
            created_at=now,
            updated_at=now,
        )
        lib_repo.create(library)

        app = _create_test_app(lib_repo, asset_repo, proj_repo)
        client = TestClient(app)

        response = client.delete("/api/v1/asset-libraries/lib-1")
        assert response.status_code == 404
