#!/usr/bin/env python3
"""
Test script to validate refactored backend endpoints
Tests all CRUD operations for profiles, songs, and plans
"""
import requests
import json
import sys
from datetime import datetime

BASE_URL = "http://localhost:8080/api"
session = requests.Session()

# Color output
GREEN = '\033[92m'
RED = '\033[91m'
RESET = '\033[0m'
BLUE = '\033[94m'

test_results = []

def log_test(name, passed, details=""):
    """Log test result"""
    status = f"{GREEN}✓ PASS{RESET}" if passed else f"{RED}✗ FAIL{RESET}"
    print(f"{status} - {name}")
    if details and not passed:
        print(f"  {details}")
    test_results.append((name, passed, details))

def test_health():
    """Test health endpoint"""
    try:
        response = session.get(f"{BASE_URL}/health")
        passed = response.status_code == 200 and response.json().get('status') == 'ok'
        log_test("Health Check", passed)
        return passed
    except Exception as e:
        log_test("Health Check", False, str(e))
        return False

def test_profile_crud():
    """Test profile CRUD operations"""
    print(f"\n{BLUE}=== Testing Profile CRUD ==={RESET}")
    
    # CREATE
    try:
        profile_data = {
            "name": "Test Profile",
            "first_name": "Test",
            "last_name": "User",
            "email": "test@example.com",
            "default_key": "C"
        }
        response = session.post(f"{BASE_URL}/profiles", json=profile_data)
        passed = response.status_code == 200
        profile_id = response.json().get('id') if passed else None
        log_test("Profile Create", passed, response.text if not passed else "")
        
        if not passed:
            return False
    except Exception as e:
        log_test("Profile Create", False, str(e))
        return False
    
    # READ (GET ALL)
    try:
        response = session.get(f"{BASE_URL}/profiles")
        passed = response.status_code == 200 and isinstance(response.json(), list)
        log_test("Profile List", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Profile List", False, str(e))
        return False
    
    # UPDATE
    try:
        update_data = {"notes": "Updated notes from refactored test"}
        response = session.put(f"{BASE_URL}/profiles/{profile_id}", json=update_data)
        passed = response.status_code == 200
        log_test("Profile Update", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Profile Update", False, str(e))
        return False
    
    # DELETE
    try:
        response = session.delete(f"{BASE_URL}/profiles/{profile_id}")
        passed = response.status_code == 200
        log_test("Profile Delete", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Profile Delete", False, str(e))
        return False
    
    return True

def test_song_crud():
    """Test song CRUD operations"""
    print(f"\n{BLUE}=== Testing Song CRUD ==={RESET}")
    
    # CREATE
    try:
        song_data = {
            "title": "Test Song",
            "artist": "Test Artist",
            "lyrics": "Test lyrics content",
            "chords": "C G Am F"
        }
        response = session.post(f"{BASE_URL}/songs", json=song_data)
        passed = response.status_code == 200
        song_id = response.json().get('id') if passed else None
        log_test("Song Create", passed, response.text if not passed else "")
        
        if not passed:
            return False
    except Exception as e:
        log_test("Song Create", False, str(e))
        return False
    
    # READ (SEARCH)
    try:
        response = session.get(f"{BASE_URL}/songs?q=Test")
        passed = response.status_code == 200 and isinstance(response.json(), list)
        log_test("Song Search", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Song Search", False, str(e))
        return False
    
    # READ (GET ONE)
    try:
        response = session.get(f"{BASE_URL}/songs/{song_id}")
        passed = response.status_code == 200
        log_test("Song Get", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Song Get", False, str(e))
        return False
    
    # UPDATE
    try:
        update_data = {"chords": "C G Am F G"}
        response = session.put(f"{BASE_URL}/songs/{song_id}", json=update_data)
        passed = response.status_code == 200
        log_test("Song Update", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Song Update", False, str(e))
        return False
    
    # DELETE
    try:
        response = session.delete(f"{BASE_URL}/songs/{song_id}")
        passed = response.status_code == 200
        log_test("Song Delete", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Song Delete", False, str(e))
        return False
    
    return True

def test_plan_crud():
    """Test plan CRUD operations"""
    print(f"\n{BLUE}=== Testing Plan CRUD ==={RESET}")
    
    # CREATE
    try:
        plan_data = {
            "date": datetime.now().strftime("%Y-%m-%d"),
            "notes": "Test plan from refactored code"
        }
        response = session.post(f"{BASE_URL}/plans", json=plan_data)
        passed = response.status_code == 200
        plan_id = response.json().get('id') if passed else None
        log_test("Plan Create", passed, response.text if not passed else "")
        
        if not passed:
            return False
    except Exception as e:
        log_test("Plan Create", False, str(e))
        return False
    
    # READ
    try:
        response = session.get(f"{BASE_URL}/plans")
        passed = response.status_code == 200 and isinstance(response.json(), list)
        log_test("Plan List", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Plan List", False, str(e))
        return False
    
    # READ (GET ONE)
    try:
        response = session.get(f"{BASE_URL}/plans/{plan_id}")
        passed = response.status_code == 200
        log_test("Plan Get", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Plan Get", False, str(e))
        return False
    
    # UPDATE
    try:
        update_data = {"notes": "Updated plan notes"}
        response = session.put(f"{BASE_URL}/plans/{plan_id}", json=update_data)
        passed = response.status_code == 200
        log_test("Plan Update", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Plan Update", False, str(e))
        return False
    
    # DELETE
    try:
        response = session.delete(f"{BASE_URL}/plans/{plan_id}")
        passed = response.status_code == 200
        log_test("Plan Delete", passed, response.text if not passed else "")
    except Exception as e:
        log_test("Plan Delete", False, str(e))
        return False
    
    return True

def test_validation():
    """Test input validation"""
    print(f"\n{BLUE}=== Testing Input Validation ==={RESET}")
    
    # Test invalid profile (missing name)
    try:
        response = session.post(f"{BASE_URL}/profiles", json={})
        passed = response.status_code == 400
        log_test("Validation: Missing Profile Name", passed)
    except Exception as e:
        log_test("Validation: Missing Profile Name", False, str(e))
    
    # Test invalid song (missing title)
    try:
        response = session.post(f"{BASE_URL}/songs", json={"title": ""})
        passed = response.status_code == 400
        log_test("Validation: Missing Song Title", passed)
    except Exception as e:
        log_test("Validation: Missing Song Title", False, str(e))
    
    # Test invalid ID format
    try:
        long_id = "x" * 300
        response = session.put(f"{BASE_URL}/profiles/{long_id}", json={})
        passed = response.status_code == 400
        log_test("Validation: Invalid ID Format", passed, f"Expected 400, got {response.status_code}")
    except Exception as e:
        log_test("Validation: Invalid ID Format", False, str(e))

def print_summary():
    """Print test summary"""
    print(f"\n{BLUE}{'='*60}{RESET}")
    print(f"{BLUE}TEST SUMMARY{RESET}")
    print(f"{BLUE}{'='*60}{RESET}")
    
    passed = sum(1 for _, p, _ in test_results if p)
    total = len(test_results)
    
    print(f"Total Tests: {total}")
    print(f"Passed: {GREEN}{passed}{RESET}")
    print(f"Failed: {RED}{total - passed}{RESET}")
    print(f"Success Rate: {(passed/total*100):.1f}%")
    
    if passed == total:
        print(f"\n{GREEN}✓ ALL TESTS PASSED - Refactoring successful!{RESET}")
        return 0
    else:
        print(f"\n{RED}✗ Some tests failed - Review errors above{RESET}")
        return 1

if __name__ == "__main__":
    print(f"{BLUE}{'='*60}{RESET}")
    print(f"{BLUE}Refactored Backend Test Suite{RESET}")
    print(f"{BLUE}{'='*60}{RESET}")
    
    # Run tests
    test_health()
    test_profile_crud()
    test_song_crud()
    test_plan_crud()
    test_validation()
    
    # Print summary and exit
    sys.exit(print_summary())
