"""Xiaohongshu formal acquisition adapter."""
from __future__ import annotations

from typing import Any, Iterable

from acquisition.content_mode import infer_content_mode
from acquisition.crawler import fetch_post_detail
from acquisition.platforms.base import PlatformCandidate, PlatformItem, PlatformSearchPage
from acquisition.search import search_xiaohongshu_page
from core.config import Settings


class XiaohongshuAdapter:
    platform = "xiaohongshu"

    def search(
        self,
        query: str,
        *,
        settings: Settings,
        limit: int,
        rate_limiter: Any,
    ) -> list[PlatformCandidate]:
        pages = self.search_pages(
            query,
            settings=settings,
            limit=limit,
            rate_limiter=rate_limiter,
            max_pages=1,
        )
        return [candidate for page in pages for candidate in page.candidates]

    def search_pages(
        self,
        query: str,
        *,
        settings: Settings,
        limit: int,
        rate_limiter: Any,
        max_pages: int = 2,
    ) -> Iterable[PlatformSearchPage]:
        cursor = ""
        rank = 1
        seen: set[str] = set()
        for page_index in range(1, max_pages + 1):
            page = search_xiaohongshu_page(
                query,
                cursor=cursor,
                content_type=None,
                limit=limit,
                settings=settings,
                rate_limiter=rate_limiter,
            )
            candidates: list[PlatformCandidate] = []
            for page_rank, row in enumerate(page.rows, start=1):
                source_id = row.get("id") or ""
                if not source_id or source_id in seen:
                    continue
                seen.add(source_id)
                raw = {
                    **row,
                    "page_index": page_index,
                    "page_rank": page_rank,
                    "source_cursor": page.cursor,
                    "request_payload": page.request_payload,
                }
                candidates.append(
                    PlatformCandidate(
                        rank=rank,
                        platform=self.platform,
                        source_id=source_id,
                        url=row.get("url") or "",
                        title=row.get("title") or "",
                        author=row.get("nick_name") or "",
                        cover_url=row.get("cover_url") or "",
                        raw=raw,
                    )
                )
                rank += 1
            yield PlatformSearchPage(
                page_index=page_index,
                candidates=candidates,
                raw_count=page.raw_count,
                cursor=page.cursor,
                next_cursor=page.next_cursor,
                has_more=page.has_more,
                provider=page.provider,
                request_payload=page.request_payload,
            )
            if not page.has_more or not page.next_cursor or page.next_cursor == cursor:
                break
            cursor = page.next_cursor

    def fetch_detail(
        self,
        candidate: PlatformCandidate,
        *,
        settings: Settings,
        rate_limiter: Any,
    ) -> PlatformItem:
        post = fetch_post_detail(
            candidate.source_id or candidate.url,
            settings=settings,
            rate_limiter=rate_limiter,
        )
        image_urls = post.image_urls or ([candidate.cover_url] if candidate.cover_url else [])
        content_mode = infer_content_mode(
            platform=self.platform,
            content_type=post.content_type,
            body_text=post.body_text,
            image_urls=image_urls,
            video_urls=post.video_urls,
            raw={**candidate.raw, "detail_content_type": post.content_type},
        )
        return PlatformItem(
            platform=self.platform,
            source_id=post.content_id or candidate.source_id,
            url=post.url or candidate.url,
            content_type=post.content_type or "",
            content_mode=content_mode,
            title=post.title or candidate.title,
            author=post.author_name or candidate.author,
            body_text=post.body_text or "",
            image_urls=image_urls,
            video_urls=post.video_urls,
            raw=post.raw if isinstance(post.raw, dict) else {},
        )
