import requests
import json

BASE_URL = "http://127.0.0.1:8000/api/"
AUTH_URL = "http://127.0.0.1:8000/api/auth/"

# --- Global Variables for Testing ---
ACCESS_TOKEN = None
REFRESH_TOKEN = None
TEST_USER_EMAIL = "test_api_user@example.com"
TEST_USER_USERNAME = "test_api_user"
TEST_USER_PASSWORD = "testpassword123"

# --- Helper Functions ---
def create_user(email, username, password):
    print(f"\n--- Creating User: {username} ---")
    url = f"{AUTH_URL}users/"
    data = {
        "email": email,
        "username": username,
        "password": password,
        "re_password": password
    }
    response = requests.post(url, json=data)
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.json()}")
    response.raise_for_status() # Raise an exception for HTTP errors
    return response.json()

def login(email, password):
    global ACCESS_TOKEN, REFRESH_TOKEN
    print(f"\n--- Logging in User: {email} ---")
    url = f"{AUTH_URL}jwt/create/"
    data = {
        "email": email,
        "password": password
    }
    response = requests.post(url, json=data)
    print(f"Status Code: {response.status_code}")
    response_data = response.json()
    print(f"Response: {response_data}")
    response.raise_for_status()
    ACCESS_TOKEN = response_data["access"]
    REFRESH_TOKEN = response_data["refresh"]
    print("Login successful. Tokens obtained.")
    return ACCESS_TOKEN

def get_headers():
    if not ACCESS_TOKEN:
        raise ValueError("Access token not available. Please login first.")
    return {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "Content-Type": "application/json"
    }

# --- Test Functions for each API ---

def test_auth_endpoints():
    print("\n=== Testing Authentication Endpoints ===")
    try:
        # Create user
        create_user(TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_PASSWORD)

        # Login
        access_token = login(TEST_USER_EMAIL, TEST_USER_PASSWORD)

        # Get user info
        print("\n--- Getting User Info (me) ---")
        response = requests.get(f"{AUTH_URL}users/me/", headers=get_headers())
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Authentication endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Authentication endpoints test FAILED: {e}")
    except ValueError as e:
        print(f"Authentication endpoints test FAILED: {e}")


def test_customers_endpoints():
    print("\n=== Testing Customers Endpoints ===")
    try:
        headers = get_headers()

        # List Customers
        print("\n--- Listing Customers ---")
        response = requests.get(f"{BASE_URL}customers/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Customers endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Customers endpoints test FAILED: {e}")

def test_members_endpoints():
    print("\n=== Testing Members Endpoints ===")
    try:
        headers = get_headers()

        # List Members
        print("\n--- Listing Members ---")
        response = requests.get(f"{BASE_URL}members/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Members endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Members endpoints test FAILED: {e}")

def test_banking_endpoints():
    print("\n=== Testing Banking Endpoints ===")
    try:
        headers = get_headers()

        # List Accounts
        print("\n--- Listing Accounts ---")
        response = requests.get(f"{BASE_URL}banking/accounts/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Transactions
        print("\n--- Listing Transactions ---")
        response = requests.get(f"{BASE_URL}banking/transactions/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Banking endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Banking endpoints test FAILED: {e}")

def test_shares_endpoints():
    print("\n=== Testing Shares Endpoints ===")
    try:
        headers = get_headers()

        # List Share Types
        print("\n--- Listing Share Types ---")
        response = requests.get(f"{BASE_URL}shares/share-types/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Share Subscriptions
        print("\n--- Listing Share Subscriptions ---")
        response = requests.get(f"{BASE_URL}shares/share-subscriptions/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Share Payments
        print("\n--- Listing Share Payments ---")
        response = requests.get(f"{BASE_URL}shares/share-payments/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Shares endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Shares endpoints test FAILED: {e}")

def test_credits_endpoints():
    print("\n=== Testing Credits Endpoints ===")
    try:
        headers = get_headers()

        # List Credit Products
        print("\n--- Listing Credit Products ---")
        response = requests.get(f"{BASE_URL}credits/credit-products/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Loan Applications
        print("\n--- Listing Loan Applications ---")
        response = requests.get(f"{BASE_URL}credits/loan-applications/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Loans
        print("\n--- Listing Loans ---")
        response = requests.get(f"{BASE_URL}credits/loans/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Repayment Schedules
        print("\n--- Listing Repayment Schedules ---")
        response = requests.get(f"{BASE_URL}credits/repayment-schedules/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()

        # List Repayments
        print("\n--- Listing Repayments ---")
        response = requests.get(f"{BASE_URL}credits/repayments/", headers=headers)
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.json()}")
        response.raise_for_status()
        print("Credits endpoints test PASSED.")

    except requests.exceptions.RequestException as e:
        print(f"Credits endpoints test FAILED: {e}")

# --- Main Execution ---
if __name__ == "__main__":
    print("\nStarting API Endpoint Tests...")
    
    # Ensure the server is running before executing tests
    # You might need to manually start the Django development server (python manage.py runserver)
    # before running this script.

    test_auth_endpoints()
    test_customers_endpoints()
    test_members_endpoints()
    test_banking_endpoints()
    test_shares_endpoints()
    test_credits_endpoints()

    print("\nAPI Endpoint Tests Finished.")
