"""
BUG-7 Deep Fix Tests: Own-mode user isolation
Tests that 'own' mode users with no servers configured:
1. Get empty profiles from /api/shared-profiles
2. Get xtream_mode='own', xtream_configured=false from /api/subscription/status
3. Admin (non-own-mode) still gets shared profiles
"""
import pytest
import requests
import os

BASE_URL = os.environ.get("REACT_APP_BACKEND_URL", "").rstrip("/")

# Test credentials
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "admin123"
OWN_MODE_USER = "googletest"
OWN_MODE_PASS = "test123"


class TestBug7OwnModeIsolation:
    """Tests for BUG-7: Own-mode user isolation from shared profiles"""

    @pytest.fixture(scope="class")
    def admin_token(self):
        """Get admin auth token"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
        )
        if response.status_code != 200:
            pytest.skip(f"Admin login failed: {response.status_code} - {response.text}")
        data = response.json()
        # API returns access_token, not token
        return data.get("access_token") or data.get("token")

    @pytest.fixture(scope="class")
    def own_mode_user_token(self):
        """Get own-mode user (googletest) auth token"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": OWN_MODE_USER, "password": OWN_MODE_PASS},
        )
        if response.status_code != 200:
            pytest.skip(f"Own-mode user login failed: {response.status_code} - {response.text}")
        data = response.json()
        # API returns access_token, not token
        return data.get("access_token") or data.get("token")

    # ─── Backend: /api/shared-profiles tests ───

    def test_shared_profiles_returns_empty_for_own_mode_user(self, own_mode_user_token):
        """BUG-7 FIX: /api/shared-profiles returns empty profiles for 'own' mode user"""
        response = requests.get(
            f"{BASE_URL}/api/shared-profiles",
            headers={"Authorization": f"Bearer {own_mode_user_token}"},
        )
        assert response.status_code == 200, f"Expected 200, got {response.status_code}: {response.text}"
        data = response.json()
        
        # CRITICAL: profiles list must be empty for own-mode user
        assert "profiles" in data, "Response must contain 'profiles' key"
        assert data["profiles"] == [], f"Expected empty profiles list, got {data['profiles']}"
        
        # Should also return xtream_mode='own' indicator
        assert data.get("xtream_mode") == "own", f"Expected xtream_mode='own', got {data.get('xtream_mode')}"

    def test_shared_profiles_returns_profiles_for_admin(self, admin_token):
        """Admin (non-own-mode) should still get shared profiles if configured"""
        response = requests.get(
            f"{BASE_URL}/api/shared-profiles",
            headers={"Authorization": f"Bearer {admin_token}"},
        )
        assert response.status_code == 200, f"Expected 200, got {response.status_code}: {response.text}"
        data = response.json()
        
        # Admin should get profiles (may be empty if none configured, but not blocked)
        assert "profiles" in data, "Response must contain 'profiles' key"
        # Admin should NOT have xtream_mode='own' in response
        assert data.get("xtream_mode") != "own", "Admin should not be in 'own' mode"

    def test_shared_profiles_requires_auth(self):
        """Unauthenticated request should return 401"""
        response = requests.get(f"{BASE_URL}/api/shared-profiles")
        assert response.status_code == 401, f"Expected 401, got {response.status_code}"

    # ─── Backend: /api/subscription/status tests ───

    def test_subscription_status_own_mode_not_configured(self, own_mode_user_token):
        """BUG-7 FIX: /api/subscription/status returns xtream_mode='own', xtream_configured=false"""
        response = requests.get(
            f"{BASE_URL}/api/subscription/status",
            headers={"Authorization": f"Bearer {own_mode_user_token}"},
        )
        assert response.status_code == 200, f"Expected 200, got {response.status_code}: {response.text}"
        data = response.json()
        
        # Check xtream_mode is 'own'
        assert data.get("xtream_mode") == "own", f"Expected xtream_mode='own', got {data.get('xtream_mode')}"
        
        # Check xtream_configured is false (no credentials set)
        assert data.get("xtream_configured") == False, f"Expected xtream_configured=false, got {data.get('xtream_configured')}"
        
        # Xtream credentials should be empty (not shared creds)
        xtream = data.get("xtream", {})
        assert xtream.get("server") == "", f"Expected empty server, got {xtream.get('server')}"
        assert xtream.get("username") == "", f"Expected empty username, got {xtream.get('username')}"
        assert xtream.get("password") == "", f"Expected empty password, got {xtream.get('password')}"

    def test_subscription_status_user_info(self, own_mode_user_token):
        """Verify user info is returned correctly"""
        response = requests.get(
            f"{BASE_URL}/api/subscription/status",
            headers={"Authorization": f"Bearer {own_mode_user_token}"},
        )
        assert response.status_code == 200
        data = response.json()
        
        user = data.get("user", {})
        assert user.get("username") == OWN_MODE_USER, f"Expected username={OWN_MODE_USER}, got {user.get('username')}"
        assert user.get("role") == "user", f"Expected role='user', got {user.get('role')}"

    def test_subscription_status_requires_auth(self):
        """Unauthenticated request should return 401"""
        response = requests.get(f"{BASE_URL}/api/subscription/status")
        assert response.status_code == 401, f"Expected 401, got {response.status_code}"


class TestAdminUserCreation:
    """Tests for admin creating users with xtream_mode='own'"""

    @pytest.fixture(scope="class")
    def admin_token(self):
        """Get admin auth token"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
        )
        if response.status_code != 200:
            pytest.skip(f"Admin login failed: {response.status_code}")
        data = response.json()
        return data.get("access_token") or data.get("token")

    def test_admin_can_create_own_mode_user(self, admin_token):
        """Admin can create a user with xtream_mode='own'"""
        import uuid
        test_username = f"TEST_own_user_{uuid.uuid4().hex[:8]}"
        
        response = requests.post(
            f"{BASE_URL}/api/admin/users",
            headers={"Authorization": f"Bearer {admin_token}"},
            json={
                "username": test_username,
                "password": "testpass123",
                "xtream_mode": "own",
            },
        )
        
        # Should succeed
        assert response.status_code in [200, 201], f"Expected 200/201, got {response.status_code}: {response.text}"
        data = response.json()
        
        # Verify xtream_mode is set
        assert data.get("xtream_mode") == "own", f"Expected xtream_mode='own', got {data.get('xtream_mode')}"
        
        # Cleanup: delete the test user
        user_id = data.get("id")
        if user_id:
            requests.delete(
                f"{BASE_URL}/api/admin/users/{user_id}",
                headers={"Authorization": f"Bearer {admin_token}"},
            )


class TestAuthEndpoints:
    """Basic auth endpoint tests"""

    def test_admin_login_success(self):
        """Admin login works"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
        )
        assert response.status_code == 200, f"Expected 200, got {response.status_code}"
        data = response.json()
        # API returns access_token
        assert "access_token" in data or "token" in data, "Response must contain access_token or token"
        assert data.get("user", {}).get("role") == "admin", "Admin should have admin role"

    def test_own_mode_user_login_success(self):
        """Own-mode user (googletest) login works"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": OWN_MODE_USER, "password": OWN_MODE_PASS},
        )
        assert response.status_code == 200, f"Expected 200, got {response.status_code}"
        data = response.json()
        # API returns access_token
        assert "access_token" in data or "token" in data, "Response must contain access_token or token"
        assert data.get("user", {}).get("role") == "user", "googletest should have user role"

    def test_invalid_login_fails(self):
        """Invalid credentials return 401"""
        response = requests.post(
            f"{BASE_URL}/api/auth/login",
            json={"username": "nonexistent", "password": "wrongpass"},
        )
        assert response.status_code == 401, f"Expected 401, got {response.status_code}"


class TestHealthEndpoints:
    """Basic health check tests"""

    def test_api_root(self):
        """API root returns Hello World"""
        response = requests.get(f"{BASE_URL}/api/")
        assert response.status_code == 200
        assert response.json().get("message") == "Hello World"

    def test_public_shared_xtream(self):
        """Public shared-xtream endpoint works"""
        response = requests.get(f"{BASE_URL}/api/public/shared-xtream")
        assert response.status_code == 200
        data = response.json()
        assert "configured" in data
