#!/bin/bash

# Bulk Upsert Feature Test Script
# Tests CSV/JSON bulk imports with various edge cases and upsert scenarios

# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Source the test configuration
source "$SCRIPT_DIR/../test-config.sh"

echo "🧪 Testing bulk upsert feature..."
echo "================================"

# Configuration
# Remove /api if it's already included in TEST_API_BASE
if [[ "$TEST_API_BASE" == */api ]]; then
    API_BASE="$TEST_API_BASE"
else
    API_BASE="${TEST_API_BASE}/api"
fi
ADMIN_USERNAME="$TEST_ADMIN_USERNAME"
ADMIN_PASSWORD="$TEST_ADMIN_PASSWORD"
AUTH_TOKEN=""

# Dynamic table name to avoid conflicts
TEST_TABLE="test_bulk_upsert_$(date +%s)"
DATA_DIR="$SCRIPT_DIR/test-data/bulk-upsert"

# Create test data directory
mkdir -p "$DATA_DIR"

# Helper function to create test files
create_test_files() {
    echo "📁 Creating test data files..."
    
    # 1. Basic CSV file
    cat > "$DATA_DIR/products.csv" << 'EOF'
sku,name,price,quantity,active
PROD-001,Laptop Computer,1299.99,50,true
PROD-002,Wireless Mouse,29.99,200,true
PROD-003,USB-C Cable,19.99,500,false
PROD-004,Monitor Stand,79.99,100,true
PROD-005,Keyboard,89.99,150,true
EOF

    # 2. CSV with special characters
    cat > "$DATA_DIR/special-chars.csv" << 'EOF'
sku,name,description,price
SPEC-001,"Product with ""quotes""","Description with ""quoted text""",99.99
SPEC-002,"Product, with comma","Has a comma, in the name",149.99
SPEC-003,"Multi-line
Product","Description
spans multiple
lines",199.99
SPEC-004,"Special & < > chars","Contains & < > $ % characters",49.99
EOF

    # 3. CSV for upsert testing (contains duplicates)
    cat > "$DATA_DIR/upsert-test.csv" << 'EOF'
sku,name,price,quantity,active
PROD-001,Updated Laptop,1399.99,45,true
PROD-002,Updated Mouse,34.99,180,false
PROD-006,New Headphones,149.99,75,true
EOF

    # 4. JSON array file
    cat > "$DATA_DIR/products.json" << 'EOF'
[
  {
    "sku": "JSON-001",
    "name": "Smart Watch",
    "price": 299.99,
    "quantity": 30,
    "active": true,
    "metadata": {
      "brand": "TechCo",
      "warranty": "2 years"
    }
  },
  {
    "sku": "JSON-002",
    "name": "Bluetooth Speaker",
    "price": 89.99,
    "quantity": 100,
    "active": true,
    "metadata": {
      "color": "black",
      "waterproof": true
    }
  },
  {
    "sku": "JSON-003",
    "name": "Phone Case",
    "price": 24.99,
    "quantity": 250,
    "active": false,
    "metadata": null
  }
]
EOF

    # 5. Single JSON object
    cat > "$DATA_DIR/single-product.json" << 'EOF'
{
  "sku": "SINGLE-001",
  "name": "Premium Subscription",
  "price": 99.99,
  "quantity": 999,
  "active": true,
  "metadata": {
    "type": "subscription",
    "duration": "annual"
  }
}
EOF

    # 6. CSV with NULL values
    cat > "$DATA_DIR/null-values.csv" << 'EOF'
sku,name,price,quantity,active
NULL-001,,99.99,,true
NULL-002,Product with nulls,,,false
NULL-003,Only SKU and Name,,,
NULL-004,Complete Product,49.99,25,true
EOF

    # 7. Large CSV file (1000 rows)
    echo "sku,name,price,quantity,active" > "$DATA_DIR/large-dataset.csv"
    for i in $(seq 1 1000); do
        echo "LARGE-$(printf %04d $i),Product $i,$(echo "scale=2; $RANDOM/100" | bc),$(($RANDOM % 1000)),true" >> "$DATA_DIR/large-dataset.csv"
    done

    # 8. CSV with Unicode/Emoji
    cat > "$DATA_DIR/unicode.csv" << 'EOF'
sku,name,price,quantity,description
UNI-001,Café ☕ Français,15.99,100,Délicieux café
UNI-002,寿司 🍣 セット,35.99,50,新鮮な魚
UNI-003,Москва 🇷🇺 Souvenir,25.99,75,Русский сувенир
UNI-004,🚀 Rocket Toy,19.99,200,Fun emoji product 🎉
EOF

    # 9. Invalid CSV (for error testing)
    cat > "$DATA_DIR/invalid.csv" << 'EOF'
sku,name,price
INV-001,Product 1,99.99,Extra Column
INV-002,Missing Price
INV-003
EOF

    # 10. Empty files
    touch "$DATA_DIR/empty.csv"
    echo "[]" > "$DATA_DIR/empty.json"
    
    echo "✅ Test files created"
}

# Function to login as admin
login_admin() {
    echo "🔐 Logging in as admin..."
    
    # First check if backend is running
    if ! curl -s "$API_BASE/health" > /dev/null 2>&1; then
        echo "❌ Backend server is not running!"
        echo "   Please start the backend first:"
        echo "   cd backend && npm run dev"
        exit 1
    fi
    
    local payload
    payload=$(build_admin_login_payload "$ADMIN_USERNAME" "$ADMIN_PASSWORD")

    local response
    response=$(curl -s -X POST "$API_BASE/auth/admin/sessions" \
        -H "Content-Type: application/json" \
        -d "$payload")
    
    AUTH_TOKEN=$(echo "$response" | grep -o '"accessToken":"[^"]*' | cut -d'"' -f4)
    
    if [ -z "$AUTH_TOKEN" ]; then
        echo "❌ Failed to login as admin"
        echo "   Response: $response"
        echo ""
        echo "   Make sure you have the correct root admin credentials:"
        echo "   Username: $ADMIN_USERNAME"
        echo "   Password: <hidden>"
        echo ""
        echo "   You can set these with environment variables:"
        echo "   TEST_ADMIN_USERNAME=admin TEST_ADMIN_PASSWORD=yourpassword ./test-bulk-upsert.sh"
        exit 1
    fi
    
    echo "✅ Admin login successful"
}

# Function to create test table
create_test_table() {
    echo "📊 Creating test table: $TEST_TABLE"
    
    local response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"query\": \"CREATE TABLE $TEST_TABLE (id SERIAL PRIMARY KEY, sku VARCHAR(50) UNIQUE, name VARCHAR(255), description TEXT, price DECIMAL(10,2), quantity INTEGER, active BOOLEAN, metadata JSONB)\"}")
    
    if echo "$response" | grep -q "error"; then
        echo "❌ Failed to create table: $response"
        exit 1
    fi
    
    echo "✅ Table created successfully"
    
    # Register table for cleanup
    register_test_table "$TEST_TABLE"
}

# Function to test bulk upsert
test_bulk_upsert() {
    local file_name=$1
    local table=$2
    local upsert_key=$3
    local description=$4
    local expect_failure=${5:-false}
    
    if [ "$expect_failure" != "true" ]; then
        echo ""
        echo "🧪 Test: $description"
        echo "   File: $file_name"
    fi
    
    # Build form data
    local curl_cmd="curl -s -X POST \"$API_BASE/database/advance/bulk-upsert\" \
        -H \"Authorization: Bearer $AUTH_TOKEN\" \
        -F \"file=@$DATA_DIR/$file_name\" \
        -F \"table=$table\""
    
    if [ ! -z "$upsert_key" ]; then
        curl_cmd="$curl_cmd -F \"upsertKey=$upsert_key\""
    fi
    
    local response=$(eval $curl_cmd)
    
    if echo "$response" | grep -q "\"success\":true"; then
        local rows=$(echo "$response" | grep -o '"rowsAffected":[0-9]*' | cut -d':' -f2)
        local total=$(echo "$response" | grep -o '"totalRecords":[0-9]*' | cut -d':' -f2)
        if [ "$expect_failure" != "true" ]; then
            echo "   ✅ Success: $rows/$total rows inserted"
        fi
        return 0
    else
        local error=$(echo "$response" | grep -o '"message":"[^"]*' | cut -d'"' -f4)
        if [ "$expect_failure" != "true" ]; then
            echo "   ⚠️  Expected error: $error"
        fi
        return 1
    fi
}

# Function to verify data
verify_data() {
    local expected_count=$1
    local description=$2
    
    echo ""
    echo "🔍 Verifying: $description"
    
    local response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"query\": \"SELECT COUNT(*) as count FROM $TEST_TABLE\"}")
    
    local actual_count=$(echo "$response" | grep -o '"count":"[0-9]*' | cut -d'"' -f4)
    
    if [ "$actual_count" = "$expected_count" ]; then
        echo "   ✅ Correct: $actual_count rows in table"
    else
        echo "   ❌ Mismatch: Expected $expected_count, got $actual_count"
        return 1
    fi
}

# Function to check specific data
check_data() {
    local query=$1
    local expected=$2
    local description=$3
    
    echo "   🔍 $description"
    
    local response=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"query\": \"$query\"}")
    
    if echo "$response" | grep -q "$expected"; then
        echo "      ✅ Found: $expected"
    else
        echo "      ❌ Not found: $expected"
        echo "      Response: $response"
    fi
}

# Cleanup function
cleanup() {
    echo ""
    echo "🧹 Cleaning up..."
    
    # Drop test table
    curl -s -X POST "$API_BASE/database/advance/rawsql" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"query\": \"DROP TABLE IF EXISTS $TEST_TABLE CASCADE\"}" > /dev/null
    
    # Remove test data directory
    rm -rf "$DATA_DIR"
    
    echo "✅ Cleanup complete"
}

# Main test execution
main() {
    # Setup
    create_test_files
    login_admin
    create_test_table
    
    echo ""
    echo "="
    echo "🚀 RUNNING BULK UPSERT TESTS"
    echo "="
    
    # Test 1: Basic CSV import
    test_bulk_upsert "products.csv" "$TEST_TABLE" "" "Basic CSV Import"
    verify_data 5 "5 products imported"
    
    # Test 2: JSON array import
    test_bulk_upsert "products.json" "$TEST_TABLE" "sku" "JSON Array Import (with upsert)"
    verify_data 8 "3 new products added"
    
    # Test 3: Single JSON object
    test_bulk_upsert "single-product.json" "$TEST_TABLE" "sku" "Single JSON Object"
    verify_data 9 "1 product added"
    
    # Test 4: CSV with special characters
    test_bulk_upsert "special-chars.csv" "$TEST_TABLE" "sku" "Special Characters in CSV"
    verify_data 13 "4 products with special chars"
    
    # Test 5: Upsert test (update existing)
    test_bulk_upsert "upsert-test.csv" "$TEST_TABLE" "sku" "Upsert - Update Existing"
    verify_data 14 "1 new product, 2 updated"
    check_data "SELECT name, price FROM $TEST_TABLE WHERE sku='PROD-001'" "Updated Laptop" "PROD-001 was updated"
    
    # Test 6: NULL values handling
    test_bulk_upsert "null-values.csv" "$TEST_TABLE" "sku" "NULL Values in CSV"
    verify_data 18 "4 products with nulls"
    
    # Test 7: Unicode/Emoji support
    test_bulk_upsert "unicode.csv" "$TEST_TABLE" "sku" "Unicode and Emoji Support"
    verify_data 22 "4 unicode products"
    check_data "SELECT name FROM $TEST_TABLE WHERE sku='UNI-004'" "🚀 Rocket Toy" "Emoji preserved"
    
    # Test 8: Error handling - empty file
    echo ""
    echo "🧪 Test: Error Handling - Empty CSV"
    echo "   File: empty.csv"
    if test_bulk_upsert "empty.csv" "$TEST_TABLE" "" "Empty CSV (should fail)" true; then
        echo "   ❌ ERROR: Empty file was accepted (should have been rejected)"
    else
        echo "   ✅ Correctly rejected empty file (expected behavior)"
    fi
    
    # Test 9: Error handling - invalid CSV
    echo ""
    echo "🧪 Test: Error Handling - Invalid CSV"
    echo "   File: invalid.csv"
    if test_bulk_upsert "invalid.csv" "$TEST_TABLE" "" "Invalid CSV (should fail)" true; then
        echo "   ❌ ERROR: Invalid CSV was accepted (should have been rejected)"
    else
        echo "   ✅ Correctly rejected invalid CSV (expected behavior)"
    fi
    
    # Test 10: Performance test
    echo ""
    echo "🧪 Test: Large Dataset Performance"
    START_TIME=$(date +%s%N)
    test_bulk_upsert "large-dataset.csv" "$TEST_TABLE" "sku" "1000 rows bulk insert"
    END_TIME=$(date +%s%N)
    ELAPSED=$((($END_TIME - $START_TIME) / 1000000))
    echo "   ⏱️  Time: ${ELAPSED}ms ($(echo "scale=1; 1000000/$ELAPSED" | bc) rows/sec)"
    
    echo ""
    echo "="
    echo "📊 TEST SUMMARY"
    echo "="
    
    # Final verification
    local final_count=$(curl -s -X POST "$API_BASE/database/advance/rawsql" \
        -H "Authorization: Bearer $AUTH_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"query\": \"SELECT COUNT(*) as count FROM $TEST_TABLE\"}" | grep -o '"count":"[0-9]*' | cut -d'"' -f4)
    
    echo "Total records in table: $final_count"
    echo ""
    
    # Cleanup
    cleanup
    
    echo ""
    echo "✅ All bulk upsert tests completed!"
}

# Trap to ensure cleanup on exit
trap cleanup EXIT

# Run the tests
main
