#!/bin/bash

# ============================================================================
# MISSION : Tests Exhaustifs API Veza MVP
# ============================================================================
# Script de test API complet pour valider toutes les fonctionnalités backend
# Utilise curl pour tester chaque endpoint comme un utilisateur réel
# ============================================================================

set -eo pipefail

# Couleurs pour la sortie
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
API_URL="${API_URL:-http://localhost:8080/api/v1}"
FRONTEND_URL="${FRONTEND_URL:-http://localhost:5173}"
TIMESTAMP=$(date +%s)
TEST_EMAIL="test-mvp-${TIMESTAMP}@example.com"
TEST_PASSWORD="TestPassword123!"
TEST_USERNAME="testuser_${TIMESTAMP}"

# Variables pour stocker les tokens et IDs
ACCESS_TOKEN=""
REFRESH_TOKEN=""
USER_ID=""
TRACK_ID=""
PLAYLIST_ID=""

# Compteurs de tests
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0

# ============================================================================
# Fonctions utilitaires
# ============================================================================

log_info() {
    echo -e "${BLUE}[INFO]${NC} $1" >&2
}

log_success() {
    echo -e "${GREEN}[✓]${NC} $1" >&2
    ((TESTS_PASSED++))
    ((TESTS_TOTAL++))
}

log_error() {
    echo -e "${RED}[✗]${NC} $1" >&2
    ((TESTS_FAILED++))
    ((TESTS_TOTAL++))
}

log_warning() {
    echo -e "${YELLOW}[!]${NC} $1" >&2
}

# Test une requête HTTP et vérifie le code de statut
test_request() {
    local method=$1
    local url=$2
    local expected_status=$3
    local description=$4
    local data=$5
    local headers=$6
    
    log_info "Testing: $description"
    
    local cmd="curl -s -w '\n%{http_code}' -X $method"
    
    if [ -n "$headers" ]; then
        cmd="$cmd -H \"$headers\""
    fi
    
    if [ -n "$data" ]; then
        cmd="$cmd -H 'Content-Type: application/json' -d '$data'"
    fi
    
    cmd="$cmd '$url'"
    
    local response=$(eval $cmd)
    local http_code=$(echo "$response" | tail -n1)
    local body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" -eq "$expected_status" ]; then
        log_success "$description (HTTP $http_code)"
        echo "$body"
        return 0
    else
        log_error "$description (Expected HTTP $expected_status, got $http_code)"
        echo "$body" | jq . 2>/dev/null || echo "$body"
        return 1
    fi
}

# ============================================================================
# PHASE 0 : SETUP ENVIRONNEMENT
# ============================================================================

phase_0_setup() {
    echo ""
    echo "============================================================================"
    echo "PHASE 0 : SETUP ENVIRONNEMENT"
    echo "============================================================================"
    
    log_info "Checking backend health..."
    local health_url="${API_URL%/api/v1}/health"
    if test_request "GET" "$health_url" 200 "Backend health check" "" "" > /dev/null 2>&1; then
        log_success "Backend is running"
    else
        # Try alternative health endpoint
        if curl -s "http://localhost:8080/health" > /dev/null 2>&1; then
            log_success "Backend is running (health endpoint found)"
        else
            log_warning "Backend health check failed, but continuing..."
        fi
    fi
    
    log_info "Checking frontend..."
    local frontend_status=$(curl -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL" || echo "000")
    if [ "$frontend_status" = "200" ]; then
        log_success "Frontend is running"
    else
        log_warning "Frontend check failed (HTTP $frontend_status), but continuing..."
    fi
    
    log_info "Test credentials:"
    log_info "  Email: $TEST_EMAIL"
    log_info "  Username: $TEST_USERNAME"
    log_info "  Password: $TEST_PASSWORD"
}

# ============================================================================
# PHASE 1 : TESTS AUTHENTIFICATION
# ============================================================================

phase_1_auth() {
    echo ""
    echo "============================================================================"
    echo "PHASE 1 : TESTS AUTHENTIFICATION"
    echo "============================================================================"
    
    # Test AUTH-001: Page de Login accessible
    log_info "AUTH-001: Checking login page accessibility"
    local login_status=$(curl -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL/login" || echo "000")
    if [ "$login_status" = "200" ]; then
        log_success "Login page is accessible"
    else
        log_error "Login page not accessible (HTTP $login_status)"
    fi
    
    # Test AUTH-002: Page de Register accessible
    log_info "AUTH-002: Checking register page accessibility"
    local register_status=$(curl -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL/register" || echo "000")
    if [ "$register_status" = "200" ]; then
        log_success "Register page is accessible"
    else
        log_error "Register page not accessible (HTTP $register_status)"
    fi
    
    # Test AUTH-003: Inscription nouvel utilisateur
    log_info "AUTH-003: Registering new user"
    local register_data="{\"email\":\"$TEST_EMAIL\",\"username\":\"$TEST_USERNAME\",\"password\":\"$TEST_PASSWORD\",\"password_confirm\":\"$TEST_PASSWORD\"}"
    local register_response
    register_response=$(test_request "POST" "$API_URL/auth/register" 201 "Register new user" "$register_data" "")
    local register_status=$?
    
    if [ $register_status -eq 0 ]; then
        USER_ID=$(echo "$register_response" | jq -r '.data.user.id // .user.id // .id // ""' 2>/dev/null || echo "")
        if [ -n "$USER_ID" ]; then
            log_success "User created with ID: $USER_ID"
        fi
    else
        log_error "AUTH-003: Registration failed - cannot proceed with login test"
        log_warning "Note: Backend may need to be restarted for BUG-004 fix to take effect"
        # Continue anyway to test other endpoints, but skip login
        ACCESS_TOKEN=""
    fi
    
    # Test AUTH-004: Login avec nouvel utilisateur (only if register succeeded)
    if [ $register_status -eq 0 ]; then
        log_info "AUTH-004: Logging in with new user"
        local login_data="{\"email\":\"$TEST_EMAIL\",\"password\":\"$TEST_PASSWORD\"}"
        local login_response
        login_response=$(test_request "POST" "$API_URL/auth/login" 200 "Login with new user" "$login_data" "")
        
        if [ $? -eq 0 ]; then
        # Le format réel est: .data.token.access_token (pas .data.access_token)
        ACCESS_TOKEN=$(echo "$login_response" | jq -r '.data.token.access_token // .data.access_token // .access_token // .token.access_token // ""' 2>/dev/null || echo "")
        REFRESH_TOKEN=$(echo "$login_response" | jq -r '.data.token.refresh_token // .data.refresh_token // .refresh_token // .token.refresh_token // ""' 2>/dev/null || echo "")
        
        if [ -n "$ACCESS_TOKEN" ]; then
            log_success "Login successful, access token obtained"
        else
            log_error "Login response missing access_token"
            log_info "Full Response: $login_response"
            log_info "Response structure: $(echo "$login_response" | jq 'keys' 2>/dev/null || echo 'invalid json')"
            log_info "Data keys: $(echo "$login_response" | jq '.data | keys' 2>/dev/null || echo 'no data')"
        fi
        else
            log_error "AUTH-004: Login failed"
        fi
    else
        log_warning "AUTH-004: Skipped (registration failed in AUTH-003)"
    fi
    
    # Test AUTH-005: Accès route protégée avec token
    if [ -n "$ACCESS_TOKEN" ]; then
        log_info "AUTH-005: Accessing protected route with token"
        test_request "GET" "$API_URL/auth/me" 200 "Get current user profile" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    else
        log_error "AUTH-005: Skipped (no access token)"
    fi
    
    # Test AUTH-006: Accès route protégée SANS token
    log_info "AUTH-006: Accessing protected route without token"
    test_request "GET" "$API_URL/auth/me" 401 "Access protected route without token" "" "" > /dev/null
    
    # Test AUTH-007: Refresh token
    if [ -n "$REFRESH_TOKEN" ]; then
        log_info "AUTH-007: Refreshing token"
        local refresh_data="{\"refresh_token\":\"$REFRESH_TOKEN\"}"
        local refresh_response=$(test_request "POST" "$API_URL/auth/refresh" 200 "Refresh token" "$refresh_data" "")
        
        if [ $? -eq 0 ]; then
            local new_access_token=$(echo "$refresh_response" | jq -r '.data.token.access_token // .data.access_token // .access_token // .token.access_token // ""' 2>/dev/null || echo "")
            if [ -n "$new_access_token" ]; then
                ACCESS_TOKEN="$new_access_token"
                log_success "Token refreshed successfully"
            fi
        fi
    else
        log_warning "AUTH-007: Skipped (no refresh token)"
    fi
    
    # Test AUTH-008: Logout
    if [ -n "$ACCESS_TOKEN" ]; then
        log_info "AUTH-008: Logging out"
        local logout_data="{\"refresh_token\":\"$REFRESH_TOKEN\"}"
        test_request "POST" "$API_URL/auth/logout" 200 "Logout" "$logout_data" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
        
        # Vérifier que le token est invalide après logout
        log_info "AUTH-008: Verifying token is invalid after logout"
        test_request "GET" "$API_URL/auth/me" 401 "Access with invalidated token" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
        
        # Re-login pour les tests suivants
        log_info "Re-logging in for subsequent tests..."
        local login_response=$(test_request "POST" "$API_URL/auth/login" 200 "Re-login" "$login_data" "")
        if [ $? -eq 0 ]; then
            ACCESS_TOKEN=$(echo "$login_response" | jq -r '.data.token.access_token // .data.access_token // .access_token // .token.access_token // ""' 2>/dev/null || echo "")
        fi
    fi
    
    # Test AUTH-009: Login avec mauvais mot de passe
    log_info "AUTH-009: Login with wrong password"
    local wrong_password_data="{\"email\":\"$TEST_EMAIL\",\"password\":\"WrongPassword123!\"}"
    test_request "POST" "$API_URL/auth/login" 401 "Login with wrong password" "$wrong_password_data" "" > /dev/null
    
    # Test AUTH-010: Check username disponibilité
    log_info "AUTH-010: Check username availability"
    local check_username_response=$(test_request "GET" "$API_URL/auth/check-username?username=$TEST_USERNAME" 200 "Check username availability" "" "")
    if [ $? -eq 0 ]; then
        local available=$(echo "$check_username_response" | jq -r '.available // .data.available // false' 2>/dev/null || echo "false")
        if [ "$available" = "false" ]; then
            log_success "Username correctly identified as taken"
        fi
    fi
}

# ============================================================================
# PHASE 2 : TESTS UTILISATEUR/PROFIL
# ============================================================================

phase_2_user() {
    echo ""
    echo "============================================================================"
    echo "PHASE 2 : TESTS UTILISATEUR/PROFIL"
    echo "============================================================================"
    
    if [ -z "$ACCESS_TOKEN" ]; then
        log_error "Skipping user tests (no access token)"
        return
    fi
    
    if [ -z "$USER_ID" ]; then
        # Récupérer l'ID utilisateur depuis /auth/me
        log_info "Getting user ID from /auth/me"
        local me_response=$(test_request "GET" "$API_URL/auth/me" 200 "Get user ID" "" "Authorization: Bearer $ACCESS_TOKEN")
        if [ $? -eq 0 ]; then
            USER_ID=$(echo "$me_response" | jq -r '.data.user.id // .user.id // .data.id // ""' 2>/dev/null || echo "")
        fi
    fi
    
    if [ -z "$USER_ID" ]; then
        log_error "Cannot proceed with user tests (no user ID)"
        return
    fi
    
    # Test USER-001: Voir son profil
    log_info "USER-001: Get user profile"
    test_request "GET" "$API_URL/users/$USER_ID" 200 "Get user profile" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test USER-002: Mettre à jour son profil
    log_info "USER-002: Update user profile"
    local update_data="{\"display_name\":\"Test User Updated\",\"bio\":\"This is my test bio\"}"
    test_request "PUT" "$API_URL/users/$USER_ID" 200 "Update user profile" "$update_data" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test USER-003: Recherche utilisateurs
    log_info "USER-003: Search users"
    test_request "GET" "$API_URL/users/search?q=test" 200 "Search users" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test USER-004: Ne peut pas modifier le profil d'un autre
    log_info "USER-004: Cannot modify another user's profile"
    local fake_user_id="00000000-0000-0000-0000-000000000001"
    local update_other_data="{\"display_name\":\"Hacked\"}"
    test_request "PUT" "$API_URL/users/$fake_user_id" 403 "Modify another user's profile (should fail)" "$update_other_data" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
}

# ============================================================================
# PHASE 3 : TESTS TRACKS
# ============================================================================

phase_3_tracks() {
    echo ""
    echo "============================================================================"
    echo "PHASE 3 : TESTS TRACKS"
    echo "============================================================================"
    
    if [ -z "$ACCESS_TOKEN" ]; then
        log_error "Skipping track tests (no access token)"
        return
    fi
    
    # Test TRACK-001: Lister les tracks
    log_info "TRACK-001: List tracks"
    local tracks_response=$(test_request "GET" "$API_URL/tracks" 200 "List tracks" "" "Authorization: Bearer $ACCESS_TOKEN")
    
    # Test TRACK-002: Upload un track (simulé)
    log_info "TRACK-002: Upload track (simulated)"
    # Créer un fichier audio de test minimal
    echo "fake audio content for testing" > /tmp/test-track-${TIMESTAMP}.mp3
    
    # Note: L'upload réel nécessite multipart/form-data, ce qui est complexe avec curl
    # On teste juste que l'endpoint existe
    log_warning "TRACK-002: Real upload test skipped (requires multipart/form-data)"
    
    # Test TRACK-003: Voir un track spécifique (si on a un ID)
    if [ -n "$TRACK_ID" ]; then
        log_info "TRACK-003: Get specific track"
        test_request "GET" "$API_URL/tracks/$TRACK_ID" 200 "Get track details" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    else
        log_warning "TRACK-003: Skipped (no track ID available)"
    fi
    
    # Test TRACK-005: Recherche de tracks
    log_info "TRACK-005: Search tracks"
    test_request "GET" "$API_URL/tracks/search?q=test" 200 "Search tracks" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
}

# ============================================================================
# PHASE 4 : TESTS PLAYLISTS
# ============================================================================

phase_4_playlists() {
    echo ""
    echo "============================================================================"
    echo "PHASE 4 : TESTS PLAYLISTS"
    echo "============================================================================"
    
    if [ -z "$ACCESS_TOKEN" ]; then
        log_error "Skipping playlist tests (no access token)"
        return
    fi
    
    # Test PLAYLIST-001: Créer une playlist
    log_info "PLAYLIST-001: Create playlist"
    local playlist_data="{\"title\":\"My Test Playlist\",\"description\":\"A playlist for testing\",\"is_public\":false}"
    local playlist_response=$(test_request "POST" "$API_URL/playlists" 201 "Create playlist" "$playlist_data" "Authorization: Bearer $ACCESS_TOKEN")
    
    if [ $? -eq 0 ]; then
        PLAYLIST_ID=$(echo "$playlist_response" | jq -r '.data.id // .id // ""' 2>/dev/null || echo "")
        if [ -n "$PLAYLIST_ID" ]; then
            log_success "Playlist created with ID: $PLAYLIST_ID"
        fi
    fi
    
    # Test PLAYLIST-002: Lister ses playlists
    log_info "PLAYLIST-002: List playlists"
    test_request "GET" "$API_URL/playlists" 200 "List playlists" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test PLAYLIST-003: Voir une playlist
    if [ -n "$PLAYLIST_ID" ]; then
        log_info "PLAYLIST-003: Get playlist details"
        test_request "GET" "$API_URL/playlists/$PLAYLIST_ID" 200 "Get playlist details" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    fi
    
    # Test PLAYLIST-004: Mettre à jour une playlist
    if [ -n "$PLAYLIST_ID" ]; then
        log_info "PLAYLIST-004: Update playlist"
        local update_playlist_data="{\"title\":\"Updated Playlist Name\",\"is_public\":true}"
        test_request "PUT" "$API_URL/playlists/$PLAYLIST_ID" 200 "Update playlist" "$update_playlist_data" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    fi
    
    # Test PLAYLIST-005: Ajouter un track à la playlist (nécessite un track ID)
    if [ -n "$PLAYLIST_ID" ] && [ -n "$TRACK_ID" ]; then
        log_info "PLAYLIST-005: Add track to playlist"
        local add_track_data="{\"track_id\":\"$TRACK_ID\"}"
        test_request "POST" "$API_URL/playlists/$PLAYLIST_ID/tracks" 200 "Add track to playlist" "$add_track_data" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    else
        log_warning "PLAYLIST-005: Skipped (no playlist ID or track ID)"
    fi
    
    # Test PLAYLIST-006: Recherche de playlists
    log_info "PLAYLIST-006: Search playlists"
    test_request "GET" "$API_URL/playlists/search?q=test" 200 "Search playlists" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test PLAYLIST-007: Supprimer une playlist
    if [ -n "$PLAYLIST_ID" ]; then
        log_info "PLAYLIST-007: Delete playlist"
        test_request "DELETE" "$API_URL/playlists/$PLAYLIST_ID" 200 "Delete playlist" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    fi
}

# ============================================================================
# PHASE 5 : TESTS SESSIONS
# ============================================================================

phase_5_sessions() {
    echo ""
    echo "============================================================================"
    echo "PHASE 5 : TESTS SESSIONS"
    echo "============================================================================"
    
    if [ -z "$ACCESS_TOKEN" ]; then
        log_error "Skipping session tests (no access token)"
        return
    fi
    
    # Test SESSION-001: Lister ses sessions
    log_info "SESSION-001: List sessions"
    test_request "GET" "$API_URL/sessions" 200 "List sessions" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test SESSION-002: Stats sessions
    log_info "SESSION-002: Get session stats"
    test_request "GET" "$API_URL/sessions/stats" 200 "Get session stats" "" "Authorization: Bearer $ACCESS_TOKEN" > /dev/null
    
    # Test SESSION-003: Révoquer une session spécifique
    log_info "SESSION-003: Revoke specific session"
    # Note: Nécessite un session ID, on skip si pas disponible
    log_warning "SESSION-003: Skipped (requires session ID from list)"
}

# ============================================================================
# RAPPORT FINAL
# ============================================================================

print_summary() {
    echo ""
    echo "============================================================================"
    echo "RAPPORT FINAL"
    echo "============================================================================"
    echo ""
    echo "Tests passés:  $TESTS_PASSED"
    echo "Tests échoués: $TESTS_FAILED"
    echo "Total:         $TESTS_TOTAL"
    echo ""
    
    if [ $TESTS_FAILED -eq 0 ]; then
        log_success "Tous les tests sont passés !"
        exit 0
    else
        log_error "Certains tests ont échoué"
        exit 1
    fi
}

# ============================================================================
# MAIN
# ============================================================================

main() {
    echo "============================================================================"
    echo "TESTS EXHAUSTIFS API VEZA MVP"
    echo "============================================================================"
    echo ""
    echo "API URL: $API_URL"
    echo "Frontend URL: $FRONTEND_URL"
    echo ""
    
    phase_0_setup
    phase_1_auth
    phase_2_user
    phase_3_tracks
    phase_4_playlists
    phase_5_sessions
    print_summary
}

# Exécuter le script
main

