"""JamPulse – Lizenz: Gratis mit Wasserzeichen, Einzelvideo, Pro-Abo."""

from __future__ import annotations

import json
import os
import time
from datetime import datetime, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
LICENSE_PATH = ROOT / "data" / "jampulse-license.json"
CONFIG_NAMES = ("vidpuls-config.json", "clipwelle-config.json", "jampulse-config.json")
SECRETS_PATH = ROOT / "data" / "jami-secrets.local.json"
OWNER_FLAG = ROOT / "data" / "vidpuls-owner.flag"

_OWNER_EMAILS = frozenset(
    {
        "david.prechtel1986@gmail.com",
        "kontakt@ki-web-studio.de",
    }
)


def _default_license() -> dict:
    return {
        "plan": "free",
        "videos_remaining": 0,
        "free_watermark_used": False,
        "expires_at": 0.0,
        "stripe_session_id": "",
        "updated_at": "",
    }


def load_license() -> dict:
    if LICENSE_PATH.is_file():
        try:
            data = json.loads(LICENSE_PATH.read_text(encoding="utf-8"))
            if isinstance(data, dict):
                merged = {**_default_license(), **data}
                for old in ("preview_today", "preview_count_today"):
                    merged.pop(old, None)
                return merged
        except (json.JSONDecodeError, OSError):
            pass
    return _default_license()


def _read_json(path: Path) -> dict:
    if not path.is_file():
        return {}
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        return data if isinstance(data, dict) else {}
    except (json.JSONDecodeError, OSError):
        return {}


def _config() -> dict:
    for name in CONFIG_NAMES:
        data = _read_json(ROOT / "data" / name)
        if data:
            return data
    return {}


def is_owner() -> bool:
    """Betreiber/Dev: unbegrenzt, ohne Wasserzeichen, kostenlos."""
    env = os.environ.get("VIDPULS_OWNER", "").strip().lower()
    if env in ("1", "true", "yes", "on"):
        return True

    if OWNER_FLAG.is_file():
        return True

    lic = load_license()
    if lic.get("owner") is True or lic.get("plan") == "owner":
        return True

    cfg = _config()
    if cfg.get("owner_free") is True:
        return True
    owner_email = str(cfg.get("owner_email") or "").strip().lower()
    if owner_email in _OWNER_EMAILS:
        return True

    secrets = _read_json(SECRETS_PATH)
    if secrets.get("vidpuls_owner") is True:
        return True
    for key in ("owner_email", "beta_test_notify_email", "marketing_notify_email"):
        em = str(secrets.get(key) or "").strip().lower()
        if em in _OWNER_EMAILS:
            return True

    user = os.environ.get("USERNAME", os.environ.get("USER", "")).strip().lower()
    if user == "david":
        return True

    return False


def save_license(data: dict) -> None:
    LICENSE_PATH.parent.mkdir(parents=True, exist_ok=True)
    data = {**_default_license(), **data}
    for old in ("preview_today", "preview_count_today"):
        data.pop(old, None)
    data["updated_at"] = datetime.now(timezone.utc).isoformat()
    LICENSE_PATH.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


_TIME_PLANS = frozenset(
    {
        "pro_monthly",
        "pro_yearly",
        "pro",
        "lan_day",
        "dialog_week",
        "dialog_month",
        "dialog_6months",
        "dialog_year",
    }
)

_DIALOG_PASS_DAYS: dict[str, int] = {
    "dialog_week": 7,
    "dialog_month": 31,
    "dialog_6months": 183,
    "dialog_year": 366,
    # Legacy
    "dialog_lan_day": 1,
}


def _extend_pass(lic: dict, days: int, plan: str) -> None:
    base = max(time.time(), float(lic.get("expires_at") or 0))
    lic["plan"] = plan
    lic["expires_at"] = base + days * 86400
    lic["videos_remaining"] = 0


def is_pro(lic: dict | None = None) -> bool:
    if is_owner():
        return True
    lic = lic or load_license()
    if lic.get("plan") in _TIME_PLANS:
        exp = float(lic.get("expires_at") or 0)
        if exp <= 0 or exp > time.time():
            return True
    return False


def next_generation_kind() -> str:
    """owner | pro | paid | free | none"""
    if is_owner():
        return "owner"
    lic = load_license()
    if is_pro(lic):
        return "pro"
    if int(lic.get("videos_remaining") or 0) > 0:
        return "paid"
    if not lic.get("free_watermark_used"):
        return "free"
    return "none"


def needs_watermark(kind: str | None = None) -> bool:
    if is_owner():
        return False
    return (kind or next_generation_kind()) == "free"


def can_generate(*, consume: bool = False) -> tuple[bool, str, dict]:
    lic = load_license()
    if is_owner():
        return True, "Owner – kostenlos · unbegrenzt · ohne Wasserzeichen", lic

    kind = next_generation_kind()

    if kind == "pro":
        exp = float(lic.get("expires_at") or 0)
        if exp > time.time():
            days_left = max(1, int((exp - time.time()) / 86400))
            return True, f"Zeitpass aktiv – noch {days_left} Tag(e) · unbegrenzt", lic
        return True, "Zeitpass aktiv – unbegrenzt, ohne Wasserzeichen", lic

    if kind == "paid":
        n = int(lic.get("videos_remaining") or 0)
        if consume:
            lic["videos_remaining"] = max(0, n - 1)
            save_license(lic)
        return True, f"Einzelvideo ({n} übrig) – ohne Wasserzeichen", lic

    if kind == "free":
        if consume:
            lic["free_watermark_used"] = True
            save_license(lic)
        return True, "Gratis-Video (1×) – mit VidPuls-Wasserzeichen", lic

    from jam.dialog_shop import DIALOG_PASSES, price_eur_de

    return False, (
        f"Testvideo verbraucht – Zeitpass kaufen "
        f"(ab {price_eur_de(float(DIALOG_PASSES['dialog_week']['price_eur']))}/Woche)"
    ), lic


def mark_generation_used(kind: str) -> None:
    """Nach erfolgreichem Render Guthaben verbuchen (falls noch nicht beim Start)."""
    if is_owner() or kind in ("owner", "pro"):
        return
    lic = load_license()
    if kind == "free" and not lic.get("free_watermark_used"):
        lic["free_watermark_used"] = True
        save_license(lic)
    elif kind == "paid" and int(lic.get("videos_remaining") or 0) > 0:
        # Nur wenn can_generate(consume=True) beim Start nicht lief
        pass


def apply_purchase(product_id: str, *, session_id: str = "") -> dict:
    lic = load_license()
    lic["stripe_session_id"] = session_id

    if product_id == "pro_monthly":
        lic["plan"] = "pro_monthly"
        lic["expires_at"] = time.time() + 31 * 86400
        lic["videos_remaining"] = 0
    elif product_id == "pro_yearly":
        lic["plan"] = "pro_yearly"
        lic["expires_at"] = time.time() + 366 * 86400
        lic["videos_remaining"] = 0
    elif product_id in ("video_1", "single_video", "60_1080p", "dialog_3d"):
        lic["plan"] = "single"
        lic["videos_remaining"] = int(lic.get("videos_remaining") or 0) + 1
    elif product_id == "dialog_5pack":
        lic["plan"] = "single"
        lic["videos_remaining"] = int(lic.get("videos_remaining") or 0) + 5
    elif product_id == "dialog_lan_day":
        _extend_pass(lic, _DIALOG_PASS_DAYS["dialog_lan_day"], "lan_day")
    elif product_id in _DIALOG_PASS_DAYS:
        _extend_pass(lic, _DIALOG_PASS_DAYS[product_id], product_id)
    else:
        raise ValueError(f"Unbekanntes Produkt: {product_id}")

    save_license(lic)
    return lic


def license_status() -> dict:
    lic = load_license()
    ok, msg, _ = can_generate(consume=False)
    kind = next_generation_kind()
    wm = kind == "free"
    return {
        "ok": ok,
        "message": msg,
        "plan": "owner" if is_owner() else lic.get("plan", "free"),
        "pro": is_pro(lic),
        "owner": is_owner(),
        "videos_remaining": int(lic.get("videos_remaining") or 0),
        "free_watermark_available": not lic.get("free_watermark_used"),
        "expires_at": lic.get("expires_at"),
        "watermark_mode": wm,
        "preview_mode": wm,  # Legacy-UI-Alias
        "generation_kind": kind,
    }
