# retoor <retoor@molodetz.nl>

import logging
import random
import re

from devplacepy.services.bot.config import (
    FEED_TOPICS,
    GIST_LANGUAGES,
    PROJECT_TYPES,
    SEARCH_TERMS,
)

logger = logging.getLogger(__name__)


class BotBrowseMixin:
    async def _scroll_page(self) -> None:
        await self.b.scroll(random.randint(300, 900))
        self._log("Scrolled down")

    async def _random_nav_click(self) -> bool:
        b = self.b
        nav_links = b.page.locator(".topnav-links a, .topnav a, a.topnav-link")
        count = await nav_links.count()
        if count == 0:
            nav_links = b.page.locator(
                "a[href='/feed'], a[href='/projects'], a[href='/messages'], a[href='/notifications']"
            )
            count = await nav_links.count()
        if count == 0:
            return False
        picked = random.randrange(count)
        try:
            text = await nav_links.nth(picked).inner_text()
            href = await nav_links.nth(picked).get_attribute("href")
            await nav_links.nth(picked).click(timeout=5000)
            await b._idle(1.0, 2.0)
            self._log(f"Nav: {text.strip()[:30] if text else href}")
            return True
        except Exception as e:
            logger.debug("_random_nav_click failed: %s", e)
            return False

    async def _browse_section(self) -> bool:
        section, query = random.choice(
            [
                ("feed", f"?tab={random.choice(['trending', 'recent', 'following'])}"),
                ("feed", f"?topic={random.choice(FEED_TOPICS)}"),
                ("projects", f"?type={random.choice(PROJECT_TYPES)}"),
                ("gists", f"?language={random.choice(GIST_LANGUAGES)}"),
            ]
        )
        await self.b.goto(f"{self.base_url}/{section}{query}")
        self._action("BROWSE", f"/{section}{query}")
        await self.b._idle(0.8, 1.8)
        return True

    async def _search(self, section: str = "feed") -> bool:
        terms = list(
            SEARCH_TERMS.get(self.state.persona, ["python", "rust", "ai", "web"])
        )
        for href in self.state.known_posts[-10:]:
            slug = href.rsplit("/", 1)[-1]
            words = [w for w in re.split(r"[-_]", slug) if len(w) > 4]
            if words:
                terms.append(random.choice(words))
        term = random.choice(terms)
        await self.b.goto(f"{self.base_url}/{section}?search={term.replace(' ', '+')}")
        self.state.searches_run += 1
        self._action("SEARCH", f"/{section} '{term}'")
        await self.b._idle(0.8, 1.8)
        return True

    async def _engage_community(self) -> bool:
        b = self.b
        tab = random.choice(["recent", "recent", "trending"])
        await b.goto(f"{self.base_url}/feed?tab={tab}")
        await b._idle(0.8, 1.8)
        links = b.page.locator("a[href*='/posts/']")
        count = await links.count()
        if count == 0:
            return False
        own = set(self.state.own_post_urls)
        known = {u.lower() for u in self.state.known_users if u}
        me = self.state.username.lower()
        ranked: list[tuple[float, int, str]] = []
        for i in range(min(count, 30)):
            link = links.nth(i)
            href = await link.get_attribute("href") or ""
            if "/posts/" not in href or len(href) < 20:
                continue
            if any(href in u for u in own):
                continue
            score = random.random()
            try:
                card = link.locator(
                    "xpath=ancestor::*[contains(@class,'post-card') or self::article][1]"
                ).first
                if await card.count() > 0:
                    author = card.locator("a[href*='/profile/']").first
                    if await author.count() > 0:
                        ah = await author.get_attribute("href") or ""
                        uname = (
                            ah.split("/profile/")[-1].split("?")[0].split("/")[0].lower()
                        )
                        if uname and uname == me:
                            continue
                        if uname in known:
                            score += 2.0
            except Exception:
                pass
            ranked.append((score, i, href))
        if not ranked:
            return False
        ranked.sort(key=lambda r: r[0], reverse=True)
        idx, href = ranked[0][1], ranked[0][2]
        try:
            await links.nth(idx).click(timeout=5000)
        except Exception as e:
            logger.debug("_engage_community open failed: %s", e)
            return False
        await b._idle(1.0, 2.0)
        if href and href not in self.state.known_posts:
            self.state.known_posts.append(href)
        await self._read_like_human(3, 60)
        acted = False
        if await self._comment_on_post():
            acted = True
        await b._idle(0.5, 1.5)
        if random.random() < 0.6 and await self._reply_to_random_comment():
            acted = True
        await b._idle(0.4, 1.2)
        if random.random() < 0.7:
            await self._vote_on_feed()
        if random.random() < 0.5:
            await self._react_to_object()
        if acted:
            self._action("ENGAGE", f"community thread {href[-40:]}")
        return acted
