#!/usr/bin/env python3
"""
Backend test for Nadiplayer Rewarded Ad support.
Tests the new ads_rewarded_id field in settings and ad-config endpoint.
"""
import requests
import json
import sys

# Use localhost for direct testing as per review request
BASE_URL = "http://localhost:8001"
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "admin123"

# Test IDs
GOOGLE_TEST_REWARDED_ID = "ca-app-pub-3940256099942544/5224354917"
REAL_REWARDED_ID = "ca-app-pub-6960839907465160/7452490933"
EXPECTED_APP_ID = "ca-app-pub-6960839907465160~7767874649"

def print_test(name):
    print(f"\n{'='*60}")
    print(f"TEST: {name}")
    print('='*60)

def print_pass(msg):
    print(f"✅ PASS: {msg}")

def print_fail(msg):
    print(f"❌ FAIL: {msg}")
    
def print_info(msg):
    print(f"ℹ️  INFO: {msg}")

def test_1_public_ad_config_initial():
    """Test 1: GET /api/public/ad-config (public, no auth) - initial state with testing mode"""
    print_test("1. GET /api/public/ad-config (public, no auth)")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/ad-config", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        print_info(f"Response: {json.dumps(data, indent=2)}")
        
        # Check required keys
        required_keys = ['enabled', 'testing', 'app_id', 'banner_id', 'interstitial_id', 'native_id', 'rewarded_id', 'interstitial_every']
        missing_keys = [k for k in required_keys if k not in data]
        
        if missing_keys:
            print_fail(f"Missing keys: {missing_keys}")
            return False
        print_pass("All required keys present")
        
        # Check app_id
        if data['app_id'] != EXPECTED_APP_ID:
            print_fail(f"app_id mismatch. Expected: {EXPECTED_APP_ID}, Got: {data['app_id']}")
            return False
        print_pass(f"app_id correct: {data['app_id']}")
        
        # Check testing mode
        if not data['testing']:
            print_fail(f"Expected testing=true, got testing={data['testing']}")
            return False
        print_pass("testing mode is true")
        
        # When testing=true, rewarded_id should be Google's test unit
        if data['rewarded_id'] != GOOGLE_TEST_REWARDED_ID:
            print_fail(f"Expected test rewarded_id: {GOOGLE_TEST_REWARDED_ID}, Got: {data['rewarded_id']}")
            return False
        print_pass(f"rewarded_id is Google's test unit: {data['rewarded_id']}")
        
        # Check other test IDs
        expected_test_banner = "ca-app-pub-3940256099942544/9214589741"
        expected_test_inter = "ca-app-pub-3940256099942544/1033173712"
        expected_test_native = "ca-app-pub-3940256099942544/2247696110"
        
        if data['banner_id'] != expected_test_banner:
            print_fail(f"Expected test banner_id: {expected_test_banner}, Got: {data['banner_id']}")
            return False
        print_pass(f"banner_id is test unit: {data['banner_id']}")
        
        if data['interstitial_id'] != expected_test_inter:
            print_fail(f"Expected test interstitial_id: {expected_test_inter}, Got: {data['interstitial_id']}")
            return False
        print_pass(f"interstitial_id is test unit: {data['interstitial_id']}")
        
        if data['native_id'] != expected_test_native:
            print_fail(f"Expected test native_id: {expected_test_native}, Got: {data['native_id']}")
            return False
        print_pass(f"native_id is test unit: {data['native_id']}")
        
        print_pass("Test 1 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return False

def test_2_admin_login():
    """Test 2: Login as admin and get JWT token"""
    print_test("2. POST /api/login (admin login)")
    
    try:
        # Check if the endpoint is /api/login or /api/auth/login
        # Let me try both
        endpoints = ["/api/login", "/api/auth/login"]
        
        for endpoint in endpoints:
            try:
                response = requests.post(
                    f"{BASE_URL}{endpoint}",
                    json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
                    timeout=10
                )
                
                if response.status_code == 404:
                    continue
                    
                print_info(f"Using endpoint: {endpoint}")
                print_info(f"Status Code: {response.status_code}")
                
                if response.status_code != 200:
                    print_fail(f"Expected 200, got {response.status_code}")
                    print_info(f"Response: {response.text}")
                    return None
                
                data = response.json()
                
                if 'access_token' not in data:
                    print_fail("No access_token in response")
                    print_info(f"Response: {json.dumps(data, indent=2)}")
                    return None
                
                token = data['access_token']
                print_pass(f"Login successful, got token: {token[:20]}...")
                print_pass("Test 2 PASSED")
                return token
                
            except Exception as e:
                continue
        
        print_fail("Could not find working login endpoint")
        return None
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return None

def test_3_get_admin_settings(token):
    """Test 3: GET /api/admin/settings (with bearer token)"""
    print_test("3. GET /api/admin/settings (with auth)")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        response = requests.get(f"{BASE_URL}/api/admin/settings", headers=headers, timeout=10)
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        print_info(f"Response keys: {list(data.keys())}")
        
        # Check if ads_rewarded_id field exists
        if 'ads_rewarded_id' not in data:
            print_fail("ads_rewarded_id field not found in settings")
            return False
        
        print_pass(f"ads_rewarded_id field present: {data['ads_rewarded_id']}")
        print_pass("Test 3 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return False

def test_4_update_settings(token):
    """Test 4: PUT /api/admin/settings to update ads_rewarded_id and disable testing"""
    print_test("4. PUT /api/admin/settings (update ads_rewarded_id and disable testing)")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        payload = {
            "ads_rewarded_id": REAL_REWARDED_ID,
            "ads_testing_mode": False
        }
        
        print_info(f"Payload: {json.dumps(payload, indent=2)}")
        
        response = requests.put(
            f"{BASE_URL}/api/admin/settings",
            headers=headers,
            json=payload,
            timeout=10
        )
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        
        # Verify the update persisted
        if data.get('ads_rewarded_id') != REAL_REWARDED_ID:
            print_fail(f"ads_rewarded_id not updated. Expected: {REAL_REWARDED_ID}, Got: {data.get('ads_rewarded_id')}")
            return False
        print_pass(f"ads_rewarded_id updated to: {data['ads_rewarded_id']}")
        
        if data.get('ads_testing_mode') != False:
            print_fail(f"ads_testing_mode not updated. Expected: False, Got: {data.get('ads_testing_mode')}")
            return False
        print_pass(f"ads_testing_mode updated to: {data['ads_testing_mode']}")
        
        print_pass("Test 4 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return False

def test_5_verify_ad_config_after_update():
    """Test 5: Verify GET /api/public/ad-config returns real IDs after update"""
    print_test("5. GET /api/public/ad-config (verify real IDs after update)")
    
    try:
        response = requests.get(f"{BASE_URL}/api/public/ad-config", timeout=10)
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            return False
        
        data = response.json()
        print_info(f"Response: {json.dumps(data, indent=2)}")
        
        # Check testing is false
        if data.get('testing') != False:
            print_fail(f"Expected testing=false, got testing={data.get('testing')}")
            return False
        print_pass("testing mode is false")
        
        # Check rewarded_id is the real one
        if data.get('rewarded_id') != REAL_REWARDED_ID:
            print_fail(f"Expected real rewarded_id: {REAL_REWARDED_ID}, Got: {data.get('rewarded_id')}")
            return False
        print_pass(f"rewarded_id is real unit: {data['rewarded_id']}")
        
        print_pass("Test 5 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return False

def test_6_reset_to_testing(token):
    """Test 6: Reset ads_testing_mode to true for safety"""
    print_test("6. PUT /api/admin/settings (reset to testing mode)")
    
    if not token:
        print_fail("No token available")
        return False
    
    try:
        headers = {"Authorization": f"Bearer {token}"}
        payload = {"ads_testing_mode": True}
        
        print_info(f"Payload: {json.dumps(payload, indent=2)}")
        
        response = requests.put(
            f"{BASE_URL}/api/admin/settings",
            headers=headers,
            json=payload,
            timeout=10
        )
        
        print_info(f"Status Code: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"Expected 200, got {response.status_code}")
            print_info(f"Response: {response.text}")
            return False
        
        data = response.json()
        
        if data.get('ads_testing_mode') != True:
            print_fail(f"ads_testing_mode not reset. Expected: True, Got: {data.get('ads_testing_mode')}")
            return False
        print_pass(f"ads_testing_mode reset to: {data['ads_testing_mode']}")
        
        print_pass("Test 6 PASSED")
        return True
        
    except Exception as e:
        print_fail(f"Exception: {str(e)}")
        return False

def test_7_regression_checks():
    """Test 7: Regression sanity checks on other endpoints"""
    print_test("7. Regression checks (app-info, playback-mode)")
    
    all_passed = True
    
    # Test /api/public/app-info
    try:
        response = requests.get(f"{BASE_URL}/api/public/app-info", timeout=10)
        print_info(f"GET /api/public/app-info - Status: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"app-info returned {response.status_code}")
            all_passed = False
        else:
            data = response.json()
            # Check basic structure
            if 'update' not in data or 'creator' not in data or 'support' not in data:
                print_fail("app-info missing expected keys")
                all_passed = False
            else:
                print_pass("app-info endpoint working")
    except Exception as e:
        print_fail(f"app-info exception: {str(e)}")
        all_passed = False
    
    # Test /api/public/playback-mode
    try:
        response = requests.get(f"{BASE_URL}/api/public/playback-mode", timeout=10)
        print_info(f"GET /api/public/playback-mode - Status: {response.status_code}")
        
        if response.status_code != 200:
            print_fail(f"playback-mode returned {response.status_code}")
            all_passed = False
        else:
            data = response.json()
            # Check basic structure
            if 'external_player_enabled' not in data:
                print_fail("playback-mode missing expected keys")
                all_passed = False
            else:
                print_pass("playback-mode endpoint working")
    except Exception as e:
        print_fail(f"playback-mode exception: {str(e)}")
        all_passed = False
    
    if all_passed:
        print_pass("Test 7 PASSED")
    else:
        print_fail("Test 7 FAILED")
    
    return all_passed

def main():
    print("\n" + "="*60)
    print("NADIPLAYER BACKEND TEST - REWARDED AD SUPPORT")
    print("="*60)
    
    results = {}
    
    # Test 1: Initial ad-config check
    results['test_1'] = test_1_public_ad_config_initial()
    
    # Test 2: Admin login
    token = test_2_admin_login()
    results['test_2'] = token is not None
    
    # Test 3: Get admin settings
    if token:
        results['test_3'] = test_3_get_admin_settings(token)
        
        # Test 4: Update settings
        results['test_4'] = test_4_update_settings(token)
        
        # Test 5: Verify ad-config after update
        results['test_5'] = test_5_verify_ad_config_after_update()
        
        # Test 6: Reset to testing mode
        results['test_6'] = test_6_reset_to_testing(token)
    else:
        results['test_3'] = False
        results['test_4'] = False
        results['test_5'] = False
        results['test_6'] = False
    
    # Test 7: Regression checks
    results['test_7'] = test_7_regression_checks()
    
    # Summary
    print("\n" + "="*60)
    print("TEST SUMMARY")
    print("="*60)
    
    passed = sum(1 for v in results.values() if v)
    total = len(results)
    
    for test_name, result in results.items():
        status = "✅ PASS" if result else "❌ FAIL"
        print(f"{test_name}: {status}")
    
    print(f"\nTotal: {passed}/{total} tests passed")
    
    if passed == total:
        print("\n🎉 ALL TESTS PASSED!")
        return 0
    else:
        print(f"\n⚠️  {total - passed} test(s) failed")
        return 1

if __name__ == "__main__":
    sys.exit(main())
