"""TikTok: Jam feiert Creator mit 100+ Likes – schwebende Herzen & Einblendungen."""

from __future__ import annotations

import math
import random
import time
import webbrowser
from dataclasses import dataclass
from urllib.parse import quote_plus

from PyQt6.QtCore import QPoint, QRect, Qt, QTimer
from PyQt6.QtGui import QColor, QFont, QPainter, QPen
from PyQt6.QtWidgets import QApplication, QWidget

from jam.brain import JamBrain, JamState
from jam.owner import owner_name

MIN_LIKES = 100
TIKTOK_VIRAL_URL = "https://www.tiktok.com/search?q=" + quote_plus(
    "viral deutsch 100 likes creator"
)

# Jam „blendet ein“ – Namen + Like-Zahl (simuliert, da kein TikTok-API-Zugriff)
SPOTLIGHT_CREATORS: tuple[tuple[str, int], ...] = (
    ("LunaCreates", 2840),
    ("MaxGamingDE", 512),
    ("SunnyDance", 1203),
    ("ArtMonster", 156),
    ("JamFanClub", 999),
    ("KreativKopf", 340),
    ("ZockQueen", 2100),
    ("MusikMaus", 445),
    ("ComedyJam", 890),
    ("StyleStar", 167),
    ("PixelFriend", 523),
    ("HappyVibes", 1105),
)

CELEBRATE_SPEECH: tuple[str, ...] = (
    "TikTok-Alarm! Jeder mit mehr als hundert Likes bekommt von mir Herzen! "
    "Ich blende euch ein – ihr seid toll!",
    "Juhu! Über hundert Likes? Dann feiert Jam euch! "
    "Schwebende Herzen für alle Creator – ich bin Fan!",
    "Boah, TikTok! Wer mehr als {min_likes} Likes hat, wird von mir eingeblendet – "
    "mit ganz vielen Herzen! Ihr rockt!",
    "{owner}, ich such auf TikTok und feier alle mit hundert plus Likes! "
    "Herzen überall!",
    "Einblendung an! Mehr als hundert Likes = Jam-Herz-Regen! "
    "Ihr seid die Besten auf TikTok!",
)

HEART_WORDS = (
    "herz",
    "herzen",
    "heart",
    "hearts",
    "like",
    "likes",
    "liebe",
    "feier",
    "einblend",
    "highlight",
    "hundert",
    "100",
)


@dataclass
class _Heart:
    x: float
    y: float
    vx: float
    vy: float
    life: float
    max_life: float
    size: float
    color: QColor
    wobble: float
    glyph: str


@dataclass
class _Spotlight:
    name: str
    likes: int
    x: float
    y: float
    life: float
    max_life: float
    rise: float


class TikTokHeartsShow(QWidget):
    """Viele schwebende Herzen + Einblend-Karten für 100+ Likes."""

    def __init__(self, center_global: QPoint, *, radius: int = 340) -> None:
        super().__init__()
        self._hearts: list[_Heart] = []
        self._spotlights: list[_Spotlight] = []
        self._tick_n = 0
        self._max_ticks = 280
        screen = QApplication.primaryScreen()
        if screen is None:
            self._invalid = True
            return
        geo = screen.availableGeometry()
        half = radius
        rect = QRect(
            center_global.x() - half,
            center_global.y() - half,
            half * 2,
            half * 2,
        )
        rect = rect.intersected(geo)
        if rect.width() < 100:
            self._invalid = True
            return
        self.setGeometry(rect)
        self._invalid = False
        self.setWindowFlags(
            Qt.WindowType.FramelessWindowHint
            | Qt.WindowType.WindowStaysOnTopHint
            | Qt.WindowType.Tool
            | Qt.WindowType.NoDropShadowWindowHint
        )
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground, True)
        self.setAttribute(Qt.WidgetAttribute.WA_ShowWithoutActivating, True)
        self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        self._w = rect.width()
        self._h = rect.height()
        self._timer = QTimer(self)
        self._timer.timeout.connect(self._on_tick)
        self._timer.start(33)
        self._seed_hearts(95)
        self._seed_spotlights()

    def _heart_color(self) -> QColor:
        palette = (
            QColor(255, 70, 110),
            QColor(255, 120, 150),
            QColor(255, 50, 90),
            QColor(255, 180, 200),
            QColor(255, 90, 130),
        )
        c = random.choice(palette)
        c.setAlpha(random.randint(160, 240))
        return c

    def _seed_hearts(self, count: int) -> None:
        for _ in range(count):
            self._hearts.append(
                _Heart(
                    x=random.uniform(0, self._w),
                    y=random.uniform(0, self._h),
                    vx=random.uniform(-0.6, 0.6),
                    vy=random.uniform(-2.8, -0.8),
                    life=random.uniform(0.5, 1.2),
                    max_life=1.2,
                    size=random.uniform(10, 26),
                    color=self._heart_color(),
                    wobble=random.uniform(0, math.tau),
                    glyph=random.choice(("♥", "❤", "💕")),
                )
            )

    def _spawn_heart(self) -> None:
        self._hearts.append(
            _Heart(
                x=random.uniform(self._w * 0.1, self._w * 0.9),
                y=self._h + 8,
                vx=random.uniform(-0.5, 0.5),
                vy=random.uniform(-3.2, -1.2),
                life=1.0,
                max_life=1.0,
                size=random.uniform(12, 28),
                color=self._heart_color(),
                wobble=random.uniform(0, math.tau),
                glyph=random.choice(("♥", "❤", "💕")),
            )
        )

    def _seed_spotlights(self) -> None:
        picks = random.sample(
            list(SPOTLIGHT_CREATORS),
            min(8, len(SPOTLIGHT_CREATORS)),
        )
        for name, likes in picks:
            if likes < MIN_LIKES:
                likes = random.randint(MIN_LIKES, 2500)
            self._spotlights.append(
                _Spotlight(
                    name=name,
                    likes=likes,
                    x=random.uniform(self._w * 0.08, self._w * 0.72),
                    y=random.uniform(self._h * 0.15, self._h * 0.75),
                    life=random.uniform(0.7, 1.0),
                    max_life=1.0,
                    rise=random.uniform(-0.35, -0.15),
                )
            )

    def _on_tick(self) -> None:
        self._tick_n += 1
        if self._tick_n % 4 == 0:
            self._spawn_heart()
        alive_h: list[_Heart] = []
        for h in self._hearts:
            h.life -= 0.018
            if h.life <= 0:
                continue
            h.wobble += 0.12
            h.x += h.vx + math.sin(h.wobble) * 0.35
            h.y += h.vy
            alive_h.append(h)
        self._hearts = alive_h
        if len(self._hearts) < 70 and self._tick_n < self._max_ticks - 20:
            self._seed_hearts(12)

        alive_s: list[_Spotlight] = []
        for s in self._spotlights:
            s.life -= 0.012
            if s.life <= 0:
                continue
            s.y += s.rise
            s.x += math.sin(self._tick_n * 0.05 + hash(s.name) % 7) * 0.2
            alive_s.append(s)
        self._spotlights = alive_s
        if self._tick_n % 45 == 0 and len(self._spotlights) < 10:
            name, likes = random.choice(SPOTLIGHT_CREATORS)
            self._spotlights.append(
                _Spotlight(
                    name=name,
                    likes=max(likes, MIN_LIKES + random.randint(0, 500)),
                    x=random.uniform(self._w * 0.05, self._w * 0.7),
                    y=self._h * 0.85,
                    life=1.0,
                    max_life=1.0,
                    rise=random.uniform(-0.4, -0.2),
                )
            )

        self.update()
        if self._tick_n >= self._max_ticks and len(self._hearts) < 25:
            self._timer.stop()
            self.close()

    def paintEvent(self, _event) -> None:
        p = QPainter(self)
        p.setRenderHint(QPainter.RenderHint.Antialiasing)
        p.fillRect(self.rect(), Qt.GlobalColor.transparent)
        font = QFont("Segoe UI", 9, QFont.Weight.Bold)

        for s in self._spotlights:
            alpha = max(0, min(255, int(220 * (s.life / s.max_life))))
            bg = QColor(30, 10, 40, alpha)
            fg = QColor(255, 220, 240, alpha)
            accent = QColor(255, 80, 120, alpha)
            label = f"✨ @{s.name}"
            sub = f"❤ {s.likes:,} Likes".replace(",", ".")
            p.setPen(Qt.PenStyle.NoPen)
            p.setBrush(bg)
            p.drawRoundedRect(int(s.x), int(s.y), 168, 44, 10, 10)
            p.setPen(QPen(accent, 2))
            p.drawRoundedRect(int(s.x), int(s.y), 168, 44, 10, 10)
            p.setFont(font)
            p.setPen(fg)
            p.drawText(int(s.x) + 10, int(s.y) + 18, label)
            p.setFont(QFont("Segoe UI", 8))
            p.drawText(int(s.x) + 10, int(s.y) + 34, sub)

        for h in self._hearts:
            alpha = max(0, min(255, int(255 * (h.life / h.max_life))))
            c = QColor(h.color)
            c.setAlpha(min(alpha, c.alpha()))
            p.setPen(Qt.PenStyle.NoPen)
            p.setBrush(c)
            p.setFont(QFont("Segoe UI Emoji", int(h.size)))
            p.drawText(int(h.x), int(h.y), h.glyph)

        p.end()


def launch_hearts_show(jam_window: QWidget) -> TikTokHeartsShow | None:
    center = jam_window.frameGeometry().center()
    show = TikTokHeartsShow(center)
    if getattr(show, "_invalid", False):
        show.deleteLater()
        return None
    show.show()
    show.raise_()
    return show


def hears_tiktok_hearts(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    has_tiktok = "tiktok" in h or "ticktock" in h
    has_heart = any(w in h for w in HEART_WORDS)
    if not has_tiktok and not (has_heart and ("100" in h or "hundert" in h)):
        return False
    if has_tiktok and has_heart:
        return True
    if has_tiktok and any(w in h for w in ("einblend", "feier", "highlight", "zeig")):
        if "like" in h or "herz" in h:
            return True
    if ("100" in h or "hundert" in h) and has_heart and has_tiktok:
        return True
    if "mehr als" in h and "like" in h:
        return True
    return False


def pick_celebrate_speech(state: JamState) -> str:
    owner = owner_name(state)
    line = random.choice(CELEBRATE_SPEECH)
    return line.format(owner=owner, min_likes=MIN_LIKES)


def format_hearts_bubble() -> str:
    return (
        "📱 TikTok ♥\n"
        f"Einblendung: alle mit {MIN_LIKES}+ Likes!\n"
        "Schwebende Herzen für euch!"
    )


def celebrate_hundred_likes(brain: JamBrain, *, user_asked: bool = True) -> str:
    """TikTok öffnen + Festtext für die Herz-Show."""
    from jam import tiktok
    from jam.tiktok_account import get_linked_account, live_url

    ok, msg = tiktok.can_open_tiktok(brain.state, user_asked=user_asked)
    if not ok:
        return msg
    try:
        url = live_url(get_linked_account(brain.state))
        if not getattr(brain.state, "tiktok_connected", False):
            webbrowser.open(TIKTOK_VIRAL_URL, new=2)
        else:
            webbrowser.open(url, new=2)
        brain.state.last_tiktok_open = time.time()
        brain.state.tiktok_like_celebrations = (
            getattr(brain.state, "tiktok_like_celebrations", 0) + 1
        )
        brain.state.last_action = "tiktok_hearts"
        brain.state.remember(f"TikTok: {MIN_LIKES}+ Likes mit Herzen gefeiert")
        brain.state.happiness = min(1.0, brain.state.happiness + 0.12)
        brain.add_xp(8)
        brain.save()
        return pick_celebrate_speech(brain.state)
    except OSError as e:
        return f"TikTok-Herzen klappen nicht: {e}"
