"""
TikTok Studio – @socialmedia.mentor, voller Zugriff (mit David-Freigabe).

Baut Ordner, Config, Post-Assistent (Playwright) und 3×-Tagesplan auf.
"""

from __future__ import annotations

import json
import os
import subprocess
import sys
import time
from datetime import datetime
from pathlib import Path

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

ROOT = Path(__file__).resolve().parent.parent
CONFIG_PATH = ROOT / "data" / "tiktok-config.json"
PROFILE_DIR = ROOT / "data" / "tiktok-playwright-profile"
LAST_POST_JSON = ROOT / "data" / "tiktok-last-post.json"
PID_FILE = ROOT / "data" / "tiktok-assist.pid"
STATUS_FILE = ROOT / "data" / "tiktok-assist-status.json"
ASSIST_SCRIPT = ROOT / "scripts" / "tiktok_post_assist.py"

STUDIO_ROOT = Path.home() / "Documents" / "Jam-TikTok-Posten"
VIDEO_POOL = STUDIO_ROOT / "video-pool"
CLIPS_READY = STUDIO_ROOT / "clips-ready"

DEFAULT_ACCOUNT = "socialmedia.mentor"
DEFAULT_NICHE = "social_media_mentor"
PROFILE_PAGE = "https://www.tiktok.com/@socialmedia.mentor"
UPLOAD_PAGE = "https://www.tiktok.com/tiktokstudio/upload?from=webapp"
UPLOAD_PAGE_ALT = "https://www.tiktok.com/upload"


def _default_config() -> dict:
    return {
        "account": DEFAULT_ACCOUNT,
        "display_name": "Social Media Mentor",
        "niche": DEFAULT_NICHE,
        "full_access_granted": False,
        "full_access_granted_at": 0.0,
        "granted_by": "",
        "post_schedule": {"morgen": "08:00", "mittag": "12:30", "abend": "19:00"},
        "bio_suggestion": (
            "Social Media Mentor 📱 Tipps für Reichweite, Hooks & TikTok-Wachstum. "
            "Daily Content mit Jam."
        ),
        "video_pool": str(VIDEO_POOL),
        "browser_logged_in": False,
        "browser_logged_in_at": 0.0,
        "auto_publish": False,
        "use_user_browser_only": True,
        "profile_url": PROFILE_PAGE,
        "display_name": "Mentor social Media",
        "profile_bio": "",
    }


def load_config() -> dict:
    if CONFIG_PATH.is_file():
        try:
            data = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
            if isinstance(data, dict):
                return {**_default_config(), **data}
        except (json.JSONDecodeError, OSError):
            pass
    return _default_config()


def save_config(data: dict) -> None:
    CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
    CONFIG_PATH.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")


def account_from_config() -> str:
    return (load_config().get("account") or DEFAULT_ACCOUNT).strip().lstrip("@").lower()


def is_browser_logged_in(state: JamState | None = None) -> bool:
    if state is not None and getattr(state, "jam_tiktok_browser_logged_in", False):
        return True
    return bool(load_config().get("browser_logged_in", False))


def use_user_browser_only(state: JamState | None = None) -> bool:
    """Kein separates Jam-Login – nur Davids Browser + @socialmedia.mentor."""
    if state is not None and getattr(state, "jam_tiktok_user_browser_only", False):
        return True
    return bool(load_config().get("use_user_browser_only", True))


def profile_page_url(account: str | None = None) -> str:
    cfg = load_config()
    fixed = (cfg.get("profile_url") or "").strip()
    if fixed:
        return fixed
    from jam.tiktok_account import profile_url as acc_url

    return acc_url(account or account_from_config())


def open_upload_in_user_browser(
    account: str,
    *,
    caption: str = "",
    slot: str | None = None,
) -> None:
    """Nutzt Davids eingeloggten Standard-Browser (nicht isoliertes Playwright)."""
    import webbrowser

    from jam.tiktok_account import profile_url

    if slot:
        clip = pick_video_for_slot(slot)
        if clip and clip.is_file():
            try:
                import subprocess

                subprocess.run(
                    ["explorer", "/select,", str(clip.resolve())],
                    check=False,
                    timeout=8,
                )
            except OSError:
                pass

    if caption:
        try:
            import subprocess

            subprocess.run(
                [
                    "powershell",
                    "-NoProfile",
                    "-Command",
                    f"Set-Clipboard -Value @'\n{caption[:2200]}\n'@",
                ],
                check=False,
                timeout=8,
            )
        except OSError:
            pass
    prof = profile_page_url(account)
    try:
        webbrowser.open(prof, new=2)
        webbrowser.open(UPLOAD_PAGE, new=2)
        webbrowser.open(UPLOAD_PAGE_ALT, new=0)
    except OSError:
        pass


def mark_browser_logged_in(
    brain: JamBrain,
    *,
    bio: str | None = None,
    display_name: str | None = None,
) -> str:
    """David ist in TikTok eingeloggt – Jam postet im normalen Browser."""
    from jam.active_sell import mark_logged_in as mark_platforms

    cfg = load_config()
    cfg["browser_logged_in"] = True
    cfg["browser_logged_in_at"] = time.time()
    cfg["use_user_browser_only"] = True
    cfg["auto_publish"] = False
    cfg["profile_url"] = PROFILE_PAGE
    cfg["account"] = account_from_config()
    if bio:
        cfg["profile_bio"] = bio
    if display_name:
        cfg["display_name"] = display_name
    save_config(cfg)

    state = brain.state
    state.jam_tiktok_browser_logged_in = True
    state.jam_tiktok_browser_logged_in_at = time.time()
    state.jam_tiktok_user_browser_only = True
    state.tiktok_connected = True
    state.tiktok_account = account_from_config()
    state.jam_tiktok_post_schedule = True
    state.jam_tiktok_full_access = True
    state.jam_tiktok_niche = DEFAULT_NICHE
    mark_platforms(brain)
    state.remember("TikTok @socialmedia.mentor eingeloggt – Posting aktiv")
    state.last_action = "tiktok_logged_in"
    brain.add_xp(10)
    brain.save()

    owner = owner_name(state)
    from jam.tiktok_post import current_slot, run_post_round

    slot_msg = ""
    cur = current_slot()
    if cur:
        slot_msg = " " + run_post_round(
            brain, slot=cur[0], user_initiated=True, open_upload=True
        )
    else:
        slot_msg = " " + run_post_round(
            brain, slot="mittag", user_initiated=True, open_upload=True
        )

    return (
        f"Perfekt {owner}! Kanal **{PROFILE_PAGE}** – ich nutze **deinen Browser**, "
        f"kein separates Jam-Login. Upload + Caption in Zwischenablage. "
        f"3× täglich.{slot_msg}"
    )[:720]


def write_last_post(post: dict) -> None:
    payload = {**post, "saved_at": time.time(), "when": datetime.now().isoformat()}
    LAST_POST_JSON.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")


def setup_studio_folders() -> list[str]:
    created: list[str] = []
    for path in (
        STUDIO_ROOT,
        VIDEO_POOL,
        CLIPS_READY,
        STUDIO_ROOT / "captions",
        STUDIO_ROOT / "thumbnails",
    ):
        if not path.is_dir():
            path.mkdir(parents=True, exist_ok=True)
            created.append(str(path.name))
    readme = STUDIO_ROOT / "DAVID_LESEN.txt"
    if not readme.is_file():
        readme.write_text(
            f"""JAM TIKTOK STUDIO – @{account_from_config()}
==========================================

Ordner:
  video-pool/     – Roh-Videos (.mp4) für Auto-Auswahl
  clips-ready/    – Fertige Clips nach Slot (morgen.mp4 …)
  captions/       – Jam schreibt Texte (auch Datum-Ordner)

3× täglich: 08:00 · 12:30 · 19:00
Nische: Social Media Mentor

Einmalig:
1. start-tiktok-studio.bat → Browser öffnet TikTok (einloggen als @{account_from_config()})
2. Videos in video-pool oder clips-ready legen
3. Jam füllt Caption ein – du klickst Veröffentlichen (oder JAM_TIKTOK_AUTO_POST=1)

Assistent: scripts/tiktok_post_assist.py
Profil (Login bleibt): data/tiktok-playwright-profile

Stand: {datetime.now().strftime('%d.%m.%Y %H:%M')}
""",
            encoding="utf-8",
        )
        created.append("DAVID_LESEN.txt")
    return created


def grant_full_access(brain: JamBrain, *, granted_by: str = "") -> str:
    """David-Freigabe: Account, Nische, Schedule, Studio."""
    from jam.tiktok_account import connect_account, normalize_username

    cfg = load_config()
    acc = normalize_username(cfg.get("account") or DEFAULT_ACCOUNT)
    owner = owner_name(brain.state)

    cfg["account"] = acc
    cfg["full_access_granted"] = True
    cfg["full_access_granted_at"] = time.time()
    cfg["granted_by"] = granted_by or owner
    cfg["niche"] = DEFAULT_NICHE
    save_config(cfg)

    state = brain.state
    state.tiktok_account = acc
    state.tiktok_connected = True
    state.tiktok_connected_at = time.time()
    state.jam_tiktok_full_access = True
    state.jam_tiktok_niche = DEFAULT_NICHE
    state.jam_tiktok_post_schedule = True
    state.jam_all_tasks_stopped = False
    state.jam_owner_auth_granted = True
    state.jam_owner_auth_granted_at = time.time()
    state.remember(f"TikTok Vollzugriff @{acc} Social Media Mentor")
    state.last_action = "tiktok_full_access"
    brain.add_xp(20)
    brain.save()

    connect_account(brain, account=acc, user_asked=True, open_live_tafel=False)
    created = setup_studio_folders()

    from jam.tiktok_post import enable_daily_posts

    msg = enable_daily_posts(brain, account=acc, niche=DEFAULT_NICHE)
    cfg["use_user_browser_only"] = True
    cfg["auto_publish"] = False
    cfg["profile_url"] = PROFILE_PAGE
    save_config(cfg)
    brain.state.jam_tiktok_user_browser_only = True
    brain.save()
    if not use_user_browser_only(brain.state):
        start_post_assist(background=True)
    assist_note = (
        f"Kanal: {PROFILE_PAGE} (dein Browser, kein Extra-Login)."
        if use_user_browser_only(brain.state)
        else "Playwright-Assistent läuft im Hintergrund."
    )

    return (
        f"{owner}, **voller TikTok-Zugriff** für **@{acc}** ist aktiv! "
        f"Nische: **Social Media Mentor**, 3× täglich. "
        f"Studio: {STUDIO_ROOT.name}. "
        f"Neu: {', '.join(created) or 'bereits da'}. "
        f"{assist_note} {msg}"
    )[:720]


def auto_publish_enabled(state: JamState | None = None) -> bool:
    if use_user_browser_only(state):
        return False
    if os.environ.get("JAM_TIKTOK_AUTO_POST", "").strip().lower() in ("1", "true", "yes"):
        return True
    if state is not None and getattr(state, "jam_tiktok_auto_publish", False):
        return True
    return bool(load_config().get("auto_publish", False))


def run_playwright_upload(
    brain: JamBrain | None = None,
    *,
    background: bool = False,
    timeout_sec: int = 180,
) -> tuple[bool, str]:
    """Video hochladen + Caption + Veröffentlichen (Edge-Profil data/tiktok-playwright-profile)."""
    if brain is not None and use_user_browser_only(brain.state):
        return False, (
            f"Nutze deinen Browser: {PROFILE_PAGE} – kein Jam-Login nötig."
        )
    if use_user_browser_only():
        return False, f"Nutze deinen Browser: {PROFILE_PAGE}"
    if not ASSIST_SCRIPT.is_file():
        return False, "Assistent-Skript fehlt."

    if PID_FILE.is_file():
        try:
            pid = int(PID_FILE.read_text(encoding="utf-8").strip())
            os.kill(pid, 0)
            return True, f"Upload läuft bereits (PID {pid})."
        except (OSError, ValueError, ProcessLookupError):
            PID_FILE.unlink(missing_ok=True)

    env = {**os.environ, "JAM_TIKTOK_AUTO_POST": "1"}
    py = sys.executable
    cmd = [py, str(ASSIST_SCRIPT)]

    if background:
        try:
            flags = getattr(subprocess, "CREATE_NO_WINDOW", 0)
            subprocess.Popen(
                cmd,
                cwd=str(ROOT),
                env=env,
                creationflags=flags,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
            )
            return True, "Playwright-Upload im Hintergrund gestartet."
        except OSError as e:
            return False, str(e)

    try:
        proc = subprocess.run(
            cmd,
            cwd=str(ROOT),
            env=env,
            timeout=timeout_sec,
            capture_output=True,
            text=True,
            encoding="utf-8",
            errors="replace",
        )
    except subprocess.TimeoutExpired:
        return False, "Upload-Timeout – TikTok-Fenster prüfen."

    detail = (proc.stdout or proc.stderr or "").strip()[-400:]
    if STATUS_FILE.is_file():
        try:
            st = json.loads(STATUS_FILE.read_text(encoding="utf-8"))
            if st.get("published"):
                if brain:
                    brain.state.remember(f"TikTok veröffentlicht: {st.get('slot')}")
                    brain.state.last_action = "tiktok_published"
                    brain.save()
                return True, f"Veröffentlicht! Slot {st.get('slot')}."
            if st.get("video_uploaded"):
                return True, (
                    f"Video + Caption gesetzt – Publish-Klick evtl. manuell. "
                    f"({detail})"
                )[:400]
            err = st.get("error") or detail
            return False, err or "Upload unvollständig."
        except (json.JSONDecodeError, OSError):
            pass
    return proc.returncode == 0, detail or "Upload beendet."


def start_post_assist(*, background: bool = True) -> bool:
    ok, _ = run_playwright_upload(None, background=background)
    return ok


def pick_video_for_slot(slot: str) -> Path | None:
    for name in (f"{slot}.mp4", f"{slot}.mov", "default.mp4"):
        p = CLIPS_READY / name
        if p.is_file():
            return p
    pool = list(VIDEO_POOL.glob("*.mp4")) + list(VIDEO_POOL.glob("*.mov"))
    if pool:
        return sorted(pool, key=lambda x: x.stat().st_mtime, reverse=True)[0]
    return None


def hears_logged_in(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "tiktok" not in h and "socialmedia" not in h.replace(" ", ""):
        return False
    return any(
        w in h
        for w in (
            "eingeloggt",
            "angemeldet",
            "login fertig",
            "bin drin",
            "schon eingelog",
            "bereits eingelog",
        )
    )


def hears_full_access(text: str) -> bool:
    h = text.lower().replace("jam", " ")
    if "socialmedia" in h.replace(" ", "") or "social media mentor" in h:
        return True
    if any(w in h for w in ("voller zugriff", "vollen zugriff", "vollzugriff", "freigabe")):
        if "tiktok" in h or "social" in h:
            return True
    if any(w in h for w in ("baue dir", "bau dir", "richt ein", "einrichten")):
        if "tiktok" in h or "socialmedia" in h.replace(" ", ""):
            return True
    return False


def parse_account_override(text: str) -> str | None:
    h = text.lower().replace(" ", "")
    if "socialmedia.mentor" in h or "socialmediamentor" in h:
        return DEFAULT_ACCOUNT
    import re

    m = re.search(r"@?([a-z0-9._]{4,30})", text.lower())
    if m and ("mentor" in m.group(1) or "socialmedia" in m.group(1)):
        return m.group(1).lstrip("@")
    return None


def handle_speech(brain: JamBrain, heard: str) -> str | None:
    if hears_logged_in(heard):
        bio = (
            "Mentor für Social Media. Video-Schnitt, Tipps & Tricks, "
            "persönliche Unterstützung beim Dreh."
        )
        return mark_browser_logged_in(
            brain, bio=bio, display_name="Mentor social Media"
        )
    if not hears_full_access(heard):
        return None
    acc = parse_account_override(heard)
    if acc:
        cfg = load_config()
        cfg["account"] = acc
        save_config(cfg)
    return grant_full_access(brain, granted_by=owner_name(brain.state))
