"""
Comprehensive test script for Extended Routines API

This script can be run manually to test all endpoints.
Usage: python test_routines_api.py
"""

import requests
import json
import sys
import uuid
import time

BASE_URL = "http://localhost:8080"

# Test user credentials
TEST_USERNAME = "testuser"
TEST_PASSWORD = "testpass123"

def get_token():
    """Login and get auth token."""
    resp = requests.post(f"{BASE_URL}/api/login", json={
        "username": TEST_USERNAME,
        "password": TEST_PASSWORD
    })
    if resp.status_code == 200:
        return resp.json()["token"]
    print(f"Login failed: {resp.text}")
    return None

def make_request(method, endpoint, token, data=None):
    """Make authenticated API request."""
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }
    url = f"{BASE_URL}{endpoint}"
    resp = requests.request(method, url, headers=headers, json=data)
    return resp

def test_medications_crud(token):
    """Test medications CRUD operations."""
    print("\n=== Testing Medications CRUD ===")
    
    # List medications
    resp = make_request("GET", "/api/medications", token)
    print(f"GET /api/medications: {resp.status_code}")
    
    # Add medication
    med_data = {
        "name": f"Test Med {uuid.uuid4().hex[:6]}",
        "dosage": "100",
        "unit": "mg",
        "frequency": "daily",
        "times": ["08:00"]
    }
    resp = make_request("POST", "/api/medications", token, med_data)
    print(f"POST /api/medications: {resp.status_code}")
    med_id = resp.json().get("id")
    
    # Get medication
    if med_id:
        resp = make_request("GET", f"/api/medications/{med_id}", token)
        print(f"GET /api/medications/{med_id}: {resp.status_code}")
        
        # Update medication
        resp = make_request("PUT", f"/api/medications/{med_id}", token, {"notes": "test note"})
        print(f"PUT /api/medications/{med_id}: {resp.status_code}")
        
        # Take medication
        resp = make_request("POST", f"/api/medications/{med_id}/take", token, {"scheduled_time": "08:00"})
        print(f"POST /api/medications/{med_id}/take: {resp.status_code}")
        
        # Get adherence
        resp = make_request("GET", f"/api/medications/{med_id}/adherence", token)
        print(f"GET /api/medications/{med_id}/adherence: {resp.status_code}")
        
        # Delete medication
        resp = make_request("DELETE", f"/api/medications/{med_id}", token)
        print(f"DELETE /api/medications/{med_id}: {resp.status_code}")

def test_routines_crud(token):
    """Test routines CRUD operations."""
    print("\n=== Testing Routines CRUD ===")
    
    # List routines
    resp = make_request("GET", "/api/routines", token)
    print(f"GET /api/routines: {resp.status_code}")
    
    # Create routine
    routine_data = {
        "name": f"Test Routine {uuid.uuid4().hex[:6]}",
        "description": "A test routine"
    }
    resp = make_request("POST", "/api/routines", token, routine_data)
    print(f"POST /api/routines: {resp.status_code}")
    routine_id = resp.json().get("id")
    
    if routine_id:
        # Get routine
        resp = make_request("GET", f"/api/routines/{routine_id}", token)
        print(f"GET /api/routines/{routine_id}: {resp.status_code}")
        
        # Add step
        step_data = {
            "name": "Test Step",
            "duration_minutes": 5
        }
        resp = make_request("POST", f"/api/routines/{routine_id}/steps", token, step_data)
        print(f"POST /api/routines/{routine_id}/steps: {resp.status_code}")
        step_id = resp.json().get("id")
        
        if step_id:
            # Update step instructions
            resp = make_request("PUT", f"/api/routines/{routine_id}/steps/{step_id}/instructions", 
                              token, {"instructions": "Do this step carefully"})
            print(f"PUT /steps/{step_id}/instructions: {resp.status_code}")
            
            # Update step type
            resp = make_request("PUT", f"/api/routines/{routine_id}/steps/{step_id}/type",
                              token, {"step_type": "timer"})
            print(f"PUT /steps/{step_id}/type: {resp.status_code}")
            
            # Update step media
            resp = make_request("PUT", f"/api/routines/{routine_id}/steps/{step_id}/media",
                              token, {"media_url": "https://example.com/audio.mp3"})
            print(f"PUT /steps/{step_id}/media: {resp.status_code}")
        
        # Start session
        resp = make_request("POST", f"/api/routines/{routine_id}/start", token)
        print(f"POST /routines/{routine_id}/start: {resp.status_code}")
        session_id = resp.json().get("session", {}).get("id")
        
        if session_id:
            # Complete step
            resp = make_request("POST", f"/api/sessions/{session_id}/complete-step", token)
            print(f"POST /sessions/{session_id}/complete-step: {resp.status_code}")
            
            # Pause session (if still active)
            resp = make_request("POST", f"/api/routines/{routine_id}/start", token)
            if resp.status_code == 201:
                session_id2 = resp.json().get("session", {}).get("id")
                resp = make_request("POST", f"/api/sessions/{session_id2}/pause", token)
                print(f"POST /sessions/{session_id2}/pause: {resp.status_code}")
                
                # Resume session
                resp = make_request("POST", f"/api/sessions/{session_id2}/resume", token)
                print(f"POST /sessions/{session_id2}/resume: {resp.status_code}")
                
                # Abort session
                resp = make_request("POST", f"/api/sessions/{session_id2}/abort", token, {"reason": "Test abort"})
                print(f"POST /sessions/{session_id2}/abort: {resp.status_code}")
            
            # Get session details
            resp = make_request("GET", f"/api/sessions/{session_id}", token)
            print(f"GET /sessions/{session_id}: {resp.status_code}")
        
        # Get stats
        resp = make_request("GET", f"/api/routines/{routine_id}/stats", token)
        print(f"GET /routines/{routine_id}/stats: {resp.status_code}")
        
        # Get streak
        resp = make_request("GET", f"/api/routines/{routine_id}/streak", token)
        print(f"GET /routines/{routine_id}/streak: {resp.status_code}")
        
        # Delete routine
        resp = make_request("DELETE", f"/api/routines/{routine_id}", token)
        print(f"DELETE /api/routines/{routine_id}: {resp.status_code}")

def test_templates(token):
    """Test template operations."""
    print("\n=== Testing Templates ===")
    
    # List templates
    resp = make_request("GET", "/api/templates", token)
    print(f"GET /api/templates: {resp.status_code}")
    
    # Create template
    template_data = {
        "name": f"Test Template {uuid.uuid4().hex[:6]}",
        "description": "A test template"
    }
    resp = make_request("POST", "/api/templates", token, template_data)
    print(f"POST /api/templates: {resp.status_code}")
    template_id = resp.json().get("id")
    
    if template_id:
        # Get template
        resp = make_request("GET", f"/api/templates/{template_id}", token)
        print(f"GET /api/templates/{template_id}: {resp.status_code}")
        
        # Add template step
        step_data = {"name": "Template Step 1"}
        resp = make_request("POST", f"/api/templates/{template_id}/steps", token, step_data)
        print(f"POST /templates/{template_id}/steps: {resp.status_code}")
        
        # Clone template
        resp = make_request("POST", f"/api/templates/{template_id}/clone", token)
        print(f"POST /templates/{template_id}/clone: {resp.status_code}")
        
        # Delete template
        resp = make_request("DELETE", f"/api/templates/{template_id}", token)
        print(f"DELETE /api/templates/{template_id}: {resp.status_code}")

def test_tags(token):
    """Test tag operations."""
    print("\n=== Testing Tags ===")
    
    # List tags
    resp = make_request("GET", "/api/tags", token)
    print(f"GET /api/tags: {resp.status_code}")
    
    # Create tag
    tag_data = {
        "name": f"testtag_{uuid.uuid4().hex[:6]}",
        "color": "#FF0000"
    }
    resp = make_request("POST", "/api/tags", token, tag_data)
    print(f"POST /api/tags: {resp.status_code}")
    tag_id = resp.json().get("id")
    
    # Get streaks
    resp = make_request("GET", "/api/routines/streaks", token)
    print(f"GET /api/routines/streaks: {resp.status_code}")
    
    # Get weekly summary
    resp = make_request("GET", "/api/routines/weekly-summary", token)
    print(f"GET /api/routines/weekly-summary: {resp.status_code}")
    
    if tag_id:
        # Delete tag
        resp = make_request("DELETE", f"/api/tags/{tag_id}", token)
        print(f"DELETE /api/tags/{tag_id}: {resp.status_code}")

def test_auth_errors(token):
    """Test authentication errors."""
    print("\n=== Testing Auth Errors ===")
    
    # Request without token
    resp = requests.get(f"{BASE_URL}/api/medications")
    print(f"GET /api/medications (no token): {resp.status_code}")
    
    # Request with invalid token
    resp = requests.get(f"{BASE_URL}/api/medications", 
                       headers={"Authorization": "Bearer invalid_token"})
    print(f"GET /api/medications (invalid token): {resp.status_code}")

def main():
    """Run all tests."""
    print("=" * 50)
    print("Extended Routines API - Comprehensive Test")
    print("=" * 50)
    
    # Wait for API to be ready
    print("\nWaiting for API...")
    for i in range(10):
        try:
            resp = requests.get(f"{BASE_URL}/health")
            if resp.status_code == 200:
                print("API is ready!")
                break
        except:
            pass
        time.sleep(1)
    
    # Get auth token
    token = get_token()
    if not token:
        print("Failed to get auth token")
        sys.exit(1)
    
    print(f"Got auth token: {token[:20]}...")
    
    # Run tests
    test_auth_errors(token)
    test_medications_crud(token)
    test_routines_crud(token)
    test_templates(token)
    test_tags(token)
    
    print("\n" + "=" * 50)
    print("All tests completed!")
    print("=" * 50)

if __name__ == "__main__":
    main()
