"""
补充 demand_belong_category 与 multi_demand_pool_di 的匹配关系，
并回填词级 video_list（匹配池视频去重截断最多 10 个）。
"""
from __future__ import annotations

import json
import logging
from typing import Any

from supply_infra.db.repositories.demand_belong_category_repo import (
    DemandBelongCategoryRepository,
)
from supply_infra.db.repositories.demand_belong_pool_rel_repo import (
    DemandBelongPoolRelRepository,
)
from supply_infra.db.repositories.multi_demand_pool_di_repo import (
    MultiDemandPoolDiRepository,
)
from supply_infra.db.session import get_session

logger = logging.getLogger(__name__)

_VIDEO_LIST_LIMIT = 10


def _parse_video_ids(raw: str | None) -> list[str]:
    if not raw:
        return []
    try:
        parsed = json.loads(raw)
    except json.JSONDecodeError:
        return []
    if not isinstance(parsed, list):
        return []
    return [str(v).strip() for v in parsed if v is not None and str(v).strip()]


def _merge_video_ids(video_lists: list[str | None], limit: int = _VIDEO_LIST_LIMIT) -> str | None:
    """按出现顺序去重，截断到 limit。"""
    seen: set[str] = set()
    ordered: list[str] = []
    for raw in video_lists:
        for vid in _parse_video_ids(raw):
            if vid in seen:
                continue
            seen.add(vid)
            ordered.append(vid)
            if len(ordered) >= limit:
                return json.dumps(ordered, ensure_ascii=False)
    if not ordered:
        return None
    return json.dumps(ordered, ensure_ascii=False)


def sync_demand_belong_pool_rel() -> dict[str, Any]:
    """
    增量建立词 ↔ 需求池匹配边，并更新词级 video_list。

    - name 是 demand_name 子串则建边
    - 已有边跳过；只插缺失
    - video_list：匹配行视频按顺序去重，最多 10 个
    """
    logger.info("Starting demand_belong_pool_rel sync")

    with get_session() as session:
        words = DemandBelongCategoryRepository(session).list_active_id_name()
        pool_rows = MultiDemandPoolDiRepository(session).list_id_name_video_lists()

    logger.info("Loaded words=%d pool_rows=%d", len(words), len(pool_rows))

    if not words or not pool_rows:
        result = {
            "words": len(words),
            "pool_rows": len(pool_rows),
            "matched_edges": 0,
            "inserted": 0,
            "video_updated": 0,
        }
        logger.info("Nothing to sync: %s", result)
        return result

    candidate_pairs: list[tuple[int, int]] = []
    video_updates: dict[int, str | None] = {}
    matched_edges = 0

    for belong_id, name in words:
        matched_pool_ids: list[int] = []
        matched_video_lists: list[str | None] = []
        for pool_id, demand_name, video_list in pool_rows:
            if name in demand_name:
                matched_pool_ids.append(pool_id)
                matched_video_lists.append(video_list)

        if not matched_pool_ids:
            video_updates[belong_id] = None
            continue

        matched_edges += len(matched_pool_ids)
        for pool_id in matched_pool_ids:
            candidate_pairs.append((belong_id, pool_id))
        video_updates[belong_id] = _merge_video_ids(matched_video_lists)

    with get_session() as session:
        rel_repo = DemandBelongPoolRelRepository(session)
        existing = rel_repo.get_existing_pairs(candidate_pairs)
        insert_rows = [
            {
                "demand_belong_category_id": belong_id,
                "multi_demand_pool_di_id": pool_id,
            }
            for belong_id, pool_id in candidate_pairs
            if (belong_id, pool_id) not in existing
        ]
        inserted = rel_repo.bulk_insert_ignore(insert_rows)
        video_updated = DemandBelongCategoryRepository(session).update_video_lists(
            video_updates
        )

    result = {
        "words": len(words),
        "pool_rows": len(pool_rows),
        "matched_edges": matched_edges,
        "candidate_pairs": len(candidate_pairs),
        "existing_pairs": len(existing),
        "inserted": inserted,
        "video_updated": video_updated,
    }
    logger.info("demand_belong_pool_rel sync completed: %s", result)
    return result
