"""Авто-обновление Slack token (xoxc) и cookie d (xoxd) через Playwright.

Держит постоянный профиль браузера (.slack_profile). При первом запуске
засевает в него куку d из .env, дальше профиль сам поддерживает сессию.
Каждый запуск открывает Slack залогиненным, снимает свежие token+cookie
и пишет их в creds.json.

Запуск:  python -m viktor_valency.refresh_creds
"""
from __future__ import annotations

import sys
import time
from pathlib import Path

from playwright.sync_api import sync_playwright

from .config import load_settings
from .creds import load_creds, save_creds

PROFILE_DIR = Path(__file__).resolve().parent.parent / ".slack_profile"


def refresh() -> tuple[str, str]:
    settings = load_settings()
    _, current_cookie = load_creds(settings)  # для засева профиля
    team = settings.slack_team_id
    if not team:
        raise RuntimeError(
            "SLACK_TEAM_ID не задан в .env — рефреш кредов невозможен. "
            "Либо заполните .env, либо заведите аккаунт в TUI (он подхватит team автоматически)."
        )

    with sync_playwright() as p:
        ctx = p.chromium.launch_persistent_context(
            user_data_dir=str(PROFILE_DIR),
            headless=True,
            args=["--disable-blink-features=AutomationControlled"],
        )
        try:
            # засев куки d, если профиль ещё «пустой»
            cookies = ctx.cookies("https://slack.com")
            if not any(c["name"] == "d" for c in cookies):
                ctx.add_cookies([{
                    "name": "d",
                    "value": current_cookie,
                    "domain": ".slack.com",
                    "path": "/",
                    "httpOnly": True,
                    "secure": True,
                    "sameSite": "Lax",
                }])

            page = ctx.pages[0] if ctx.pages else ctx.new_page()
            page.goto(f"https://app.slack.com/client/{team}", wait_until="domcontentloaded")

            # ждём, пока веб-клиент положит токен в localStorage
            token = ""
            for _ in range(40):  # до ~40 сек
                token = page.evaluate(
                    """(team) => {
                        try {
                            const cfg = JSON.parse(localStorage.getItem('localConfig_v2'));
                            const t = cfg.teams[team] || Object.values(cfg.teams)[0];
                            return (t && t.token) || '';
                        } catch (e) { return ''; }
                    }""",
                    team,
                )
                if token.startswith("xoxc-"):
                    break
                page.wait_for_timeout(1000)

            if not token.startswith("xoxc-"):
                raise RuntimeError(
                    "Не удалось получить xoxc — профиль, видимо, разлогинен. "
                    "Залогиньтесь один раз: python -m viktor_valency.refresh_creds --login"
                )

            d_cookie = next(
                (c["value"] for c in ctx.cookies("https://slack.com") if c["name"] == "d"),
                current_cookie,
            )
            save_creds(token, d_cookie)
            return token, d_cookie
        finally:
            ctx.close()


def login() -> None:
    """Разовый интерактивный вход в Slack в постоянный профиль (headed)."""
    settings = load_settings()
    team = settings.slack_team_id
    if not team:
        raise RuntimeError("SLACK_TEAM_ID не задан в .env — заполните и повторите.")
    with sync_playwright() as p:
        ctx = p.chromium.launch_persistent_context(
            user_data_dir=str(PROFILE_DIR), headless=False
        )
        page = ctx.pages[0] if ctx.pages else ctx.new_page()
        page.goto(f"https://app.slack.com/client/{team}")
        print("Залогиньтесь в Slack в открытом окне, потом нажмите Enter здесь…")
        input()
        ctx.close()
        print("Профиль сохранён. Теперь работает авто-обновление.")


def main() -> None:
    if "--login" in sys.argv:
        login()
        return
    t0 = time.time()
    token, cookie = refresh()
    print(f"creds обновлены за {time.time()-t0:.1f}s: token={token[:16]}… cookie={cookie[:12]}…")


if __name__ == "__main__":
    main()
