"""
Backend tests for the new app-info / update / about admin-controlled feature.

Covers:
- GET /api/public/app-info (no auth)
- POST /api/auth/login admin token
- GET /api/admin/settings (admin)
- PUT /api/admin/settings (admin) — new fields persist + pre-existing fields not regressed
- GET /api/public/app-info reflects PUT-ed values
"""
import os
import pytest
import requests

from conftest import BASE_URL, ADMIN_USER, ADMIN_PASS

PUB = f"{BASE_URL}/api/public/app-info"
LOGIN = f"{BASE_URL}/api/auth/login"
ADMIN_SET = f"{BASE_URL}/api/admin/settings"


@pytest.fixture(scope="module")
def admin_token():
    r = requests.post(LOGIN, json={"username": ADMIN_USER, "password": ADMIN_PASS}, timeout=15)
    assert r.status_code == 200, f"login failed {r.status_code} {r.text}"
    data = r.json()
    assert "access_token" in data and isinstance(data["access_token"], str)
    return data["access_token"]


@pytest.fixture(scope="module")
def admin_headers(admin_token):
    return {"Authorization": f"Bearer {admin_token}", "Content-Type": "application/json"}


# Snapshot for restore at module teardown
@pytest.fixture(scope="module")
def original_settings(admin_headers):
    r = requests.get(ADMIN_SET, headers=admin_headers, timeout=15)
    assert r.status_code == 200
    snap = r.json()
    yield snap
    # restore
    restore = {
        k: snap.get(k)
        for k in [
            "whatsapp_number", "shared_xtream_server", "shared_xtream_username",
            "shared_xtream_password", "shared_profiles", "external_player_enabled",
            "update_enabled", "app_version", "min_supported_version",
            "update_apk_url", "update_play_url", "update_changelog",
            "whatsapp_message", "privacy_policy_text", "support_email",
            "creator_name", "creator_role", "creator_avatar_url", "creator_bio",
        ]
    }
    requests.put(ADMIN_SET, headers=admin_headers, json=restore, timeout=15)


def test_public_app_info_no_auth():
    """GET /api/public/app-info works without auth, has expected structure."""
    r = requests.get(PUB, timeout=15)
    assert r.status_code == 200, r.text
    data = r.json()
    for top in ("update", "creator", "support", "privacy_policy_text"):
        assert top in data, f"missing top-level key {top}"
    upd = data["update"]
    for k in ("enabled", "latest_version", "min_supported_version", "apk_url", "play_url", "changelog"):
        assert k in upd, f"update missing {k}"
    assert isinstance(upd["enabled"], bool)
    assert isinstance(upd["latest_version"], str)
    creator = data["creator"]
    for k in ("name", "role", "avatar_url", "bio"):
        assert k in creator
    support = data["support"]
    for k in ("whatsapp_number", "whatsapp_message", "email"):
        assert k in support


def test_admin_login(admin_token):
    assert isinstance(admin_token, str) and len(admin_token) > 10


def test_admin_get_settings_has_new_fields(admin_headers, original_settings):
    r = requests.get(ADMIN_SET, headers=admin_headers, timeout=15)
    assert r.status_code == 200
    s = r.json()
    for k in [
        "update_enabled", "app_version", "min_supported_version",
        "update_apk_url", "update_play_url", "update_changelog",
        "whatsapp_message", "support_email", "creator_name", "creator_role",
        "creator_avatar_url", "creator_bio", "privacy_policy_text",
        # pre-existing
        "whatsapp_number", "shared_profiles", "external_player_enabled",
    ]:
        assert k in s, f"admin GET /settings missing field: {k}"


def test_put_settings_persists_new_fields_and_public_reflects(admin_headers, original_settings):
    payload = {
        "update_enabled": True,
        "app_version": "1.5.0",
        "min_supported_version": "1.2.0",
        "update_apk_url": "https://example.com/test.apk",
        "update_play_url": "https://play.google.com/store/apps/details?id=test",
        "update_changelog": "TEST_changelog\n- bug fixes",
        "whatsapp_message": "TEST_Hi from pytest",
        "support_email": "test_support@example.com",
        "creator_name": "TEST_Creator",
        "creator_role": "TEST_Developer",
        "creator_avatar_url": "https://example.com/a.png",
        "creator_bio": "TEST_bio_line",
        "privacy_policy_text": "TEST_privacy_policy_body",
    }
    r = requests.put(ADMIN_SET, headers=admin_headers, json=payload, timeout=15)
    assert r.status_code == 200, r.text
    saved = r.json()
    for k, v in payload.items():
        assert saved.get(k) == v, f"field {k} not persisted; got {saved.get(k)!r}"

    # GET admin again
    r2 = requests.get(ADMIN_SET, headers=admin_headers, timeout=15)
    assert r2.status_code == 200
    s = r2.json()
    for k, v in payload.items():
        assert s.get(k) == v

    # Public reflects
    r3 = requests.get(PUB, timeout=15)
    assert r3.status_code == 200
    pub = r3.json()
    assert pub["update"]["enabled"] is True
    assert pub["update"]["latest_version"] == "1.5.0"
    assert pub["update"]["min_supported_version"] == "1.2.0"
    assert pub["update"]["apk_url"] == payload["update_apk_url"]
    assert pub["update"]["play_url"] == payload["update_play_url"]
    assert pub["update"]["changelog"] == payload["update_changelog"]
    assert pub["creator"]["name"] == payload["creator_name"]
    assert pub["creator"]["role"] == payload["creator_role"]
    assert pub["creator"]["avatar_url"] == payload["creator_avatar_url"]
    assert pub["creator"]["bio"] == payload["creator_bio"]
    assert pub["support"]["whatsapp_message"] == payload["whatsapp_message"]
    assert pub["support"]["email"] == payload["support_email"]
    assert pub["privacy_policy_text"] == payload["privacy_policy_text"]


def test_put_settings_no_regression_existing_fields(admin_headers, original_settings):
    payload = {
        "whatsapp_number": "+19998887777",
        "external_player_enabled": True,
        "shared_profiles": [
            {"name": "TEST_prof", "kind": "xtream", "server": "http://srv", "username": "u", "password": "p"}
        ],
    }
    r = requests.put(ADMIN_SET, headers=admin_headers, json=payload, timeout=15)
    assert r.status_code == 200, r.text
    saved = r.json()
    assert saved["whatsapp_number"] == "+19998887777"
    assert saved["external_player_enabled"] is True
    assert isinstance(saved["shared_profiles"], list)
    assert len(saved["shared_profiles"]) == 1
    assert saved["shared_profiles"][0]["name"] == "TEST_prof"
    # id auto-assigned
    assert saved["shared_profiles"][0].get("id")


def test_public_app_info_unauth_no_authorization_header():
    """Explicitly use a fresh session w/o any auth header."""
    s = requests.Session()
    r = s.get(PUB, timeout=15)
    assert r.status_code == 200
    assert "Authorization" not in s.headers
