"""资产去重业务逻辑：LLM 合并重复资产并更新分镜引用。"""
import logging
from typing import Any, List, Optional

from pydantic import TypeAdapter
from src.models.schemas import (
    CharacterAsset,
    SceneAsset,
    PropAsset,
    OtherAsset,
    ProjectData,
)
from src.services.project_service import project_manager
from src.services.script import script_service

logger = logging.getLogger(__name__)


async def deduplicate_project_assets(project_id: str, user_id: Optional[str] = None) -> ProjectData:
    """
    对项目内资产做去重（LLM），并更新分镜中对该资产的引用。
    返回更新后的项目。

    Args:
        user_id: User ID for retrieving user's API key (纯用户密钥模式)
    """
    project = project_manager.get_project(project_id)
    if not project:
        raise ValueError("Project not found")

    assets_dicts = [a.model_dump() for a in project.assets]
    result = await script_service.deduplicate_assets(assets_dicts, user_id=user_id)
    merged_dicts = result.get("assets", [])
    id_mapping = result.get("id_mapping", {})

    new_assets: List[Any] = []
    for asset_data in merged_dicts:
        try:
            if "type" not in asset_data:
                asset_data["type"] = "other"
            if asset_data["type"] == "character":
                new_assets.append(TypeAdapter(CharacterAsset).validate_python(asset_data))
            elif asset_data["type"] == "scene":
                new_assets.append(TypeAdapter(SceneAsset).validate_python(asset_data))
            elif asset_data["type"] == "prop":
                new_assets.append(TypeAdapter(PropAsset).validate_python(asset_data))
            else:
                new_assets.append(TypeAdapter(OtherAsset).validate_python(asset_data))
        except Exception as e:
            logger.warning("Skipping invalid asset during deduplication: %s", e)

    current_project = project_manager.get_project(project_id)
    if not current_project:
        raise ValueError("Project not found during update")
    updated_storyboards = current_project.storyboards

    if id_mapping:
        logger.info(
            "Applying %s asset merges to storyboards in project %s",
            len(id_mapping),
            project_id,
        )
        modified_storyboards = []
        for sb in current_project.storyboards:
            changed = False
            if sb.scene_id and sb.scene_id in id_mapping:
                sb.scene_id = id_mapping[sb.scene_id]
                changed = True
            if sb.character_ids:
                new_char_ids = []
                ids_changed = False
                for cid in sb.character_ids:
                    if cid in id_mapping:
                        new_char_ids.append(id_mapping[cid])
                        ids_changed = True
                    else:
                        new_char_ids.append(cid)
                if ids_changed:
                    sb.character_ids = list(set(new_char_ids))
                    changed = True
            if sb.prop_ids:
                new_prop_ids = []
                ids_changed = False
                for pid in sb.prop_ids:
                    if pid in id_mapping:
                        new_prop_ids.append(id_mapping[pid])
                        ids_changed = True
                    else:
                        new_prop_ids.append(pid)
                if ids_changed:
                    sb.prop_ids = list(set(new_prop_ids))
                    changed = True
            modified_storyboards.append(sb)
        updated_storyboards = modified_storyboards

    updated_project = project_manager.update_project(
        project_id,
        {"assets": new_assets, "storyboards": updated_storyboards},
    )
    if not updated_project:
        raise ValueError("Project not found after update")
    return updated_project
