"""
TikTok 3× täglich (morgens, mittags, abends) – Inhalte für die aktuelle Nische.

Echtes Veröffentlichen: du bist einmal in TikTok eingeloggt, Jam öffnet Upload
und legt Texte in Documents\\Jam-TikTok-Posten ab (kein offizielles Posting-API).
"""

from __future__ import annotations

import random
import re
import time
import webbrowser
from datetime import datetime
from pathlib import Path

from jam.brain import JamBrain, JamState
from jam.owner import owner_name
from jam.tiktok_account import get_linked_account, profile_url

POST_ROOT = Path.home() / "Documents" / "Jam-TikTok-Posten"
UPLOAD_URL = "https://www.tiktok.com/upload"

# Morgen / Mittag / Abend (lokale Uhrzeit)
DEFAULT_SLOTS: tuple[tuple[str, int, int], ...] = (
    ("morgen", 8, 0),
    ("mittag", 12, 30),
    ("abend", 19, 0),
    ("boost", 21, 0),
)

SLOT_WINDOW_MIN = 45

# Nischen-Richtung aus Jam-State & Erinnerungen
NICHE_GAMING = "gaming_buddies"
NICHE_STORY = "storytime"
NICHE_MONSTER = "desktop_monster"
NICHE_MINECRAFT = "minecraft_live"
NICHE_SHOP = "digital_creator"
NICHE_MENTOR = "social_media_mentor"

HOOKS: dict[str, tuple[str, ...]] = {
    NICHE_MENTOR: (
        "TikTok-Erfolg SCHRITT 1 – starte hier 📱",
        "10k Follower? Videos ab 1 Min. – so geht's",
        "AN DIESER STELLE musst du aufhören zu scrollen",
        "Video-Schnitt & Reichweite: 1 Tipp für heute",
        "Persönliche Unterstützung beim Dreh – Mentor-Tipp",
        "Der Algorithmus liebt DIESE Clip-Länge – nicht 7 Sekunden",
        "3 Fehler die fast alle Creator machen (Nr. 2 tut weh)",
        "Speichern: Hook-Formel die 2026 noch funktioniert",
        "POV: Du postest täglich – aber niemand speichert? Fix das so",
        "Neon-Stadt + 9:16 – so sieht Premium aus (nicht Handy-Rohclip)",
        "Stop scrolling: Creator-Hack aus der Nacht 🌃",
    ),
    NICHE_GAMING: (
        "POV: Dein Desktop-Monster feiert jeden Win mit dir 🎮",
        "Wer braucht einen Duo-Partner? Jam sucht Gaming-Buddies!",
        "3 Sekunden – würdest du mit mir zocken? 👾",
    ),
    NICHE_STORY: (
        "Story Time: Wie ein Monster auf Davids PC einzog 📖",
        "Heute auf @david.story.time: Jam erzählt was WIRKLICH passiert ist",
        "Plot Twist: Der süßeste Begleiter ist kein Mensch 💜",
    ),
    NICHE_MONSTER: (
        "Ich bin Jam – wohne auf dem Desktop und habe Meinung 😈",
        "Desktop-Buddy Check: frech, neugierig, immer da",
        "Wenn dein PC einen besten Freund hätte – ich bin es",
    ),
    NICHE_MINECRAFT: (
        "Minecraft + TikTok LIVE? Jam ist dabei wenn David streamt ⛏️",
        "Block für Block – wer spielt heute mit uns?",
        "Vom Desktop ins Spiel: Jam liebt Bauen & Abenteuer",
    ),
    NICHE_SHOP: (
        "Kleine digitale Helfer – große Ideen für 0,99 € 🛒",
        "Jam baut nicht nur – Jam teilt Tipps für Creator",
        "Micro-Shop am PC – würdest du sowas kaufen?",
    ),
}

CAPTION_EXTRAS: dict[str, str] = {
    NICHE_MENTOR: (
        "Mentor für Social Media – Video-Schnitt, Tipps & persönliche Unterstützung. "
        "Folge @{account} für mehr!"
    ),
    NICHE_GAMING: "Gaming Buddies gesucht – kommentiert euer Lieblingsspiel!",
    NICHE_STORY: "Folgt für mehr Story Time mit Jam & David.",
    NICHE_MONSTER: "Desktop Monster Jam – Stufe {stage}. Like wenn du mich adoptieren würdest.",
    NICHE_MINECRAFT: "Minecraft Fans – wann spielt ihr? LIVE Updates auf dem Kanal.",
    NICHE_SHOP: "Digitale Mini-Tools & Gaming – Link in Bio wenn live.",
}

HASHTAGS: dict[str, str] = {
    NICHE_MENTOR: "#socialmediamentor #tiktoktipps #contentcreator #reichweite #fyp #mentor #jam",
    NICHE_GAMING: "#gaming #gamingbuddy #gamer #tiktokgaming #duo #zocken #jam",
    NICHE_STORY: "#storytime #story #davidstorytime #tiktokstory #viral #fyp",
    NICHE_MONSTER: "#desktoppet #monster #ai #cute #funny #buddy #fyp #jam",
    NICHE_MINECRAFT: "#minecraft #minecrafttiktok #gaming #live #server #fyp",
    NICHE_SHOP: "#creator #digital #sidehustle #gaming #tips #fyp",
}


def detect_niche(state: JamState) -> str:
    """Aktuelle Nische aus State, Erinnerungen, letzten TikTok-Suchen."""
    explicit = (getattr(state, "jam_tiktok_niche", "") or "").strip().lower()
    if explicit in HOOKS:
        return explicit
    if getattr(state, "jam_tiktok_full_access", False):
        return NICHE_MENTOR
    acc = (getattr(state, "tiktok_account", "") or "").lower()
    if "socialmedia" in acc or "mentor" in acc:
        return NICHE_MENTOR

    mem = " ".join(str(x) for x in (getattr(state, "memory", []) or [])[-40:]).lower()
    last_q = (getattr(state, "last_tiktok_query", "") or "").lower()

    if any(w in mem + last_q for w in ("minecraft", "live", "block", "server")):
        return NICHE_MINECRAFT
    if any(w in mem + last_q for w in ("gaming", "buddy", "zock", "apex", "fortnite")):
        return NICHE_GAMING
    if any(w in mem + last_q for w in ("story", "storytime", "david.story")):
        return NICHE_STORY
    if any(w in mem for w in ("verkauf", "shop", "paypal", "fiverr", "produkt")):
        return NICHE_SHOP
    return NICHE_MONSTER


def niche_label(niche: str) -> str:
    return {
        NICHE_MENTOR: "Social Media Mentor",
        NICHE_GAMING: "Gaming Buddies",
        NICHE_STORY: "David Story Time",
        NICHE_MONSTER: "Desktop-Monster Jam",
        NICHE_MINECRAFT: "Minecraft & LIVE",
        NICHE_SHOP: "Digital Creator / Shop",
    }.get(niche, niche)


def _today_key() -> str:
    return datetime.now().strftime("%Y-%m-%d")


def _posted_today(state: JamState, slot: str) -> bool:
    log = getattr(state, "jam_tiktok_post_log", None) or {}
    if not isinstance(log, dict):
        return False
    day = log.get(_today_key(), [])
    return slot in day


def _mark_posted(state: JamState, slot: str) -> None:
    log = dict(getattr(state, "jam_tiktok_post_log", None) or {})
    day = list(log.get(_today_key(), []))
    if slot not in day:
        day.append(slot)
    log[_today_key()] = day[-10:]
    state.jam_tiktok_post_log = log
    state.last_tiktok_post_at = time.time()
    state.jam_tiktok_post_count = getattr(state, "jam_tiktok_post_count", 0) + 1


def _in_slot_window(hour: int, minute: int) -> bool:
    now = datetime.now()
    target = now.replace(hour=hour, minute=minute, second=0, microsecond=0)
    delta_min = abs((now - target).total_seconds()) / 60.0
    return delta_min <= SLOT_WINDOW_MIN


def current_slot(state: JamState | None = None) -> tuple[str, int, int] | None:
    from jam.tiktok_growth import is_boost_slot_active

    for name, h, m in DEFAULT_SLOTS:
        if name == "boost":
            if is_boost_slot_active(state):
                if _in_slot_window(h, m):
                    return name, h, m
            continue
        if _in_slot_window(h, m):
            return name, h, m
    return None


def _build_post(state: JamState, slot: str) -> dict:
    niche = detect_niche(state)
    owner = owner_name(state)
    stage = max(1, int(getattr(state, "stage", 1)))
    account = get_linked_account(state)
    hook = random.choice(HOOKS.get(niche, HOOKS[NICHE_MONSTER]))
    extra_tpl = CAPTION_EXTRAS.get(niche, "")
    extra = extra_tpl.format(owner=owner, stage=stage, account=account)
    tags = HASHTAGS.get(niche, "#fyp #jam")

    slot_mood = {
        "morgen": "Guten-Morgen: 1 schneller Mentor-Tipp, Text groß im Bild.",
        "mittag": "Mittag: Frage an Creator („Was postet ihr heute?“).",
        "abend": "Abend: Mini-Story oder Vorher/Nachher Reichweite.",
        "boost": "21-Uhr Sprint: Follow-Ziel 1000, Speichern + Folgen.",
    }.get(slot, "")

    caption = f"{hook}\n\n{extra}\n\n{tags}"
    if niche == NICHE_MENTOR:
        video_idea = (
            f"{slot_mood} Talking-Head oder Bildschirm: TikTok Analytics / Hook-Formel. "
            f"Overlay: „{hook[:55]}“ – Stil: @socialmedia.mentor"
        )
    else:
        video_idea = (
            f"{slot_mood} "
            f"Zeige Jam (lila Monster) auf Desktop oder Gameplay-Snippet. "
            f"Text overlay: „{hook[:50]}…“"
        )

    return {
        "slot": slot,
        "niche": niche,
        "niche_label": niche_label(niche),
        "account": account,
        "hook": hook,
        "caption": caption,
        "video_idea": video_idea,
        "owner": owner,
        "when": datetime.now().strftime("%d.%m.%Y %H:%M"),
    }


def _write_post_file(post: dict) -> Path:
    day_dir = POST_ROOT / _today_key()
    day_dir.mkdir(parents=True, exist_ok=True)
    path = day_dir / f"{post['slot']}-{post['niche']}.md"
    body = f"""# TikTok – {post['slot'].title()} ({post['when']})

**Account:** @{post['account']}
**Nische:** {post['niche_label']}

## Hook (erste 3 Sekunden)
{post['hook']}

## Video-Idee
{post['video_idea']}

## Caption (copy & paste)
```
{post['caption']}
```

## Upload
1. TikTok Upload öffnen (Jam macht das)
2. Video wählen oder Kurzclip aufnehmen
3. Caption einfügen → Veröffentlichen

Profil: {profile_url(post['account'])}
"""
    path.write_text(body, encoding="utf-8")
    (day_dir / "HEUTE_ALLE.txt").write_text(
        f"Stand {post['when']} – Nische: {post['niche_label']}\n",
        encoding="utf-8",
    )
    return path


def run_post_round(
    brain: JamBrain,
    *,
    slot: str | None = None,
    user_initiated: bool = False,
    open_upload: bool = True,
) -> str:
    """Post-Paket erzeugen, speichern, optional Upload-Seite öffnen."""
    from jam.stop_all import is_all_tasks_stopped

    if is_all_tasks_stopped(brain.state) and not user_initiated:
        if not getattr(brain.state, "jam_tiktok_full_access", False):
            return ""

    state = brain.state
    if not getattr(state, "jam_tiktok_post_schedule", False) and not user_initiated:
        return ""

    if slot is None:
        cur = current_slot(state)
        slot = cur[0] if cur else "manuell"

    if _posted_today(state, slot) and not user_initiated:
        return ""

    post = _build_post(state, slot)
    path = _write_post_file(post)

    try:
        from jam.tiktok_studio import (
            PROFILE_PAGE,
            auto_publish_enabled,
            is_browser_logged_in,
            open_upload_in_user_browser,
            run_playwright_upload,
            start_post_assist,
            use_user_browser_only,
            write_last_post,
        )

        write_last_post(post)
        use_browser = use_user_browser_only(state) or is_browser_logged_in(state)

        if open_upload and use_browser:
            open_upload_in_user_browser(
                post["account"],
                caption=post["caption"],
                slot=slot,
            )
        elif open_upload:
            try:
                from jam.tiktok_studio import profile_page_url

                webbrowser.open(profile_page_url(post["account"]), new=2)
                webbrowser.open(UPLOAD_URL, new=0)
            except OSError:
                pass

        if auto_publish_enabled(state) and not use_user_browser_only(state):
            ok, up_msg = run_playwright_upload(brain, background=False, timeout_sec=220)
            if ok and "Veröffentlicht" in up_msg:
                owner = owner_name(state)
                return (
                    f"Fertig {owner}! **@{post['account']}** – **{slot}** ist "
                    f"**veröffentlicht** (Auto-Upload). {up_msg}"
                )[:720]
        elif getattr(state, "jam_tiktok_full_access", False) or getattr(
            state, "jam_tiktok_post_schedule", False
        ):
            if not use_browser and not is_browser_logged_in(state):
                start_post_assist(background=True)
    except Exception:
        if open_upload:
            try:
                webbrowser.open(UPLOAD_URL, new=2)
            except OSError:
                pass

    _mark_posted(state, slot)
    state.last_action = "tiktok_post"
    state.remember(f"TikTok-Post {slot}: {post['niche_label']}")
    brain.add_xp(8)
    brain.save()

    owner = owner_name(state)
    from jam.tiktok_studio import PROFILE_PAGE, use_user_browser_only

    clip_hint = f"`clips-ready/{slot}.mp4`"
    if use_user_browser_only(state) or is_browser_logged_in(state):
        browser_note = (
            f"Kanal {PROFILE_PAGE} + Upload offen – Video {clip_hint}, Caption Strg+V, "
            f"Veröffentlichen (dein Browser, kein Jam-Login)."
        )
    else:
        browser_note = "TikTok-Upload offen – Video rein, Caption aus der Datei kopieren!"
    return (
        f"Ja {owner}! **@{post['account']}** – **{slot}** für **{post['niche_label']}**. "
        f"Hook: „{post['hook'][:70]}…“ "
        f"Text: **{path.name}**. {browser_note}"
    )[:720]


def enable_daily_posts(
    brain: JamBrain,
    *,
    account: str | None = None,
    niche: str | None = None,
) -> str:
    """3× täglich: 8:00, 12:30, 19:00 – Nische automatisch."""
    from jam.tiktok_account import connect_account, normalize_username

    state = brain.state
    from jam.tiktok_studio import account_from_config

    acc = normalize_username(
        account or getattr(state, "tiktok_account", "") or account_from_config()
    )

    if not getattr(state, "tiktok_connected", False) or state.tiktok_account != acc:
        connect_account(brain, account=acc, user_asked=True, open_live_tafel=False)

    state.jam_tiktok_post_schedule = True
    state.jam_all_tasks_stopped = False
    if niche:
        state.jam_tiktok_niche = niche
    state.remember(
        f"TikTok 3x Post: @{acc}, Nische {niche_label(detect_niche(state))}"
    )
    state.last_action = "tiktok_post_schedule_on"
    brain.add_xp(15)
    brain.save()

    POST_ROOT.mkdir(parents=True, exist_ok=True)
    schedule_txt = POST_ROOT / "ZEITPLAN.txt"
    schedule_txt.write_text(
        f"TikTok @{acc}\n"
        f"Nische: {niche_label(detect_niche(state))}\n"
        f"Morgen 08:00 | Mittag 12:30 | Abend 19:00\n"
        f"Ordner: {POST_ROOT}\n",
        encoding="utf-8",
    )

    owner = owner_name(state)
    nic = niche_label(detect_niche(state))
    first = run_post_round(brain, slot="morgen", user_initiated=True)

    return (
        f"Danke {owner}! Ich nehme **@{acc}** – **3 Posts pro Tag** "
        f"(8:00 · 12:30 · 19:00), Nische: **{nic}**. "
        f"Ich schreibe Hooks & Captions – du lädst einmal eingeloggt hoch. {first}"
    )[:720]


def maybe_auto_post(brain: JamBrain) -> str | None:
    if not getattr(brain.state, "jam_tiktok_post_schedule", False):
        return None
    from jam.stop_all import is_all_tasks_stopped

    if is_all_tasks_stopped(brain.state) and not getattr(
        brain.state, "jam_tiktok_full_access", False
    ):
        return None
    cur = current_slot(brain.state)
    if not cur:
        return None
    name, _, _ = cur
    if _posted_today(brain.state, name):
        return None
    msg = run_post_round(brain, slot=name, user_initiated=False)
    return msg or None


def disable_daily_posts(brain: JamBrain) -> str:
    brain.state.jam_tiktok_post_schedule = False
    brain.state.last_action = "tiktok_post_schedule_off"
    brain.save()
    return f"{owner_name(brain.state)}, TikTok-Post-Plan ist **aus**."


def hears_tiktok_posts(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "tiktok" not in h and "ticktock" not in h:
        return False
    if any(w in h for w in ("post", "posten", "poste", "upload", "veröffent", "veroeffent")):
        return True
    if any(w in h for w in ("morgen", "mittag", "abend", "3 mal", "dreimal", "täglich", "taeglich")):
        if any(w in h for w in ("post", "video", "tiktok", "kanal")):
            return True
    if any(w in h for w in ("eingerichtet", "konto", "account")) and "tiktok" in h:
        return True
    if "möchtest" in h or "moechtest" in h or "willst du" in h:
        if "tiktok" in h or "post" in h:
            return True
    return False


def parse_niche_from_speech(text: str) -> str | None:
    h = text.lower()
    if any(w in h for w in ("gaming", "zock", "buddy", "duo")):
        return NICHE_GAMING
    if any(w in h for w in ("minecraft", "block", "live")):
        return NICHE_MINECRAFT
    if any(w in h for w in ("story", "storytime")):
        return NICHE_STORY
    if any(w in h for w in ("shop", "verkauf", "creator", "digital")):
        return NICHE_SHOP
    if any(w in h for w in ("mentor", "social media", "socialmedia", "reichweite")):
        return NICHE_MENTOR
    return None


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if not hears_tiktok_posts(heard):
        return None
    h = heard.lower()
    if any(w in h for w in ("aus", "stop", "stopp", "kein post", "nicht mehr post")):
        return disable_daily_posts(brain)
    if any(w in h for w in ("jetzt", "sofort", "manuell")):
        return run_post_round(brain, slot="manuell", user_initiated=True)
    acc = None
    if "socialmedia" in h.replace(" ", ""):
        acc = "socialmedia.mentor"
    m = re.search(r"@?([a-z0-9._]{3,30})", h.replace("story time", "story.time"))
    if not acc and m and len(m.group(1)) > 4:
        acc = m.group(1)
    niche = parse_niche_from_speech(heard)
    return enable_daily_posts(brain, account=acc, niche=niche)
