#!/bin/bash

# Exit on error
set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Logging functions
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# Validation functions
check_command() {
    if ! command -v $1 &> /dev/null; then
        # Try rbenv shims for pod command
        if [ "$1" = "pod" ] && [ -f "$HOME/.rbenv/shims/pod" ]; then
            log_info "Found pod in rbenv shims"
            return 0
        fi
        log_error "$1 is not installed. Please install it first."
        exit 1
    fi
}

# Get pod command (handles rbenv)
get_pod_command() {
    if command -v pod &> /dev/null; then
        echo "pod"
    elif [ -f "$HOME/.rbenv/shims/pod" ]; then
        echo "$HOME/.rbenv/shims/pod"
    else
        log_error "CocoaPods (pod) not found. Please install CocoaPods first."
        exit 1
    fi
}

check_environment() {
    log_step "Checking environment..."
    
    # Check for required tools
    check_command "xcodebuild"
    check_command "pod"
    check_command "node"
    check_command "npm"
    
    # Check for Xcode
    if ! xcodebuild -version &> /dev/null; then
        log_error "Xcode is not installed or not properly configured"
        exit 1
    fi
    
    # Check Node.js version
    NODE_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
    if [ "$NODE_VERSION" -lt 14 ]; then
        log_error "Node.js version 14 or higher is required"
        exit 1
    fi
    
    log_info "Environment check passed"
}

# Parse arguments
TARGET="simulator"
BUILD_CONFIG="Debug"

while [[ $# -gt 0 ]]; do
    case $1 in
        --simulator)
            TARGET="simulator"
            shift
            ;;
        --device)
            TARGET="device"
            shift
            ;;
        --release)
            BUILD_CONFIG="Release"
            shift
            ;;
        --help)
            echo "Usage: $0 [--simulator|--device] [--release]"
            echo ""
            echo "Options:"
            echo "  --simulator    Build for iOS Simulator (default)"
            echo "  --device       Build for physical device"
            echo "  --release      Build Release configuration (default: Debug)"
            echo "  --help         Show this help message"
            exit 0
            ;;
        *)
            log_error "Unknown option: $1"
            echo "Use --help for usage information"
            exit 1
            ;;
    esac
done

# Check if iOS test app exists
TEST_APP_DIR="test-apps/ios-test-app"
if [ ! -d "$TEST_APP_DIR" ]; then
    log_error "iOS test app not found at $TEST_APP_DIR"
    log_info "The iOS test app needs to be created first."
    log_info "See doc/directives/0003-iOS-Android-Parity-Directive.md for requirements."
    exit 1
fi

# Main build function
build_ios_test_app() {
    log_step "Building iOS test app..."
    
    # Get repo root before changing directories (we're currently in repo root from main())
    REPO_ROOT="$(pwd)"
    
    # Navigate to iOS App directory (where workspace is located)
    IOS_APP_DIR="$TEST_APP_DIR/ios/App"
    if [ ! -d "$IOS_APP_DIR" ]; then
        log_error "iOS App directory not found: $IOS_APP_DIR"
        exit 1
    fi
    
    cd "$IOS_APP_DIR" || exit 1
    
    # Check for workspace or project (these are directories, not files)
    if [ -d "App.xcworkspace" ]; then
        WORKSPACE="App.xcworkspace"
        SCHEME="App"
    elif [ -d "App.xcodeproj" ]; then
        PROJECT="App.xcodeproj"
        SCHEME="App"
    else
        log_error "No Xcode workspace or project found in $IOS_APP_DIR"
        log_info "Expected: App.xcworkspace or App.xcodeproj"
        log_info "Found files: $(ls -la | head -10)"
        exit 1
    fi
    
    # Install CocoaPods dependencies
    log_step "Installing CocoaPods dependencies..."
    POD_CMD=$(get_pod_command)
    if [ -f "Podfile" ]; then
        if ! $POD_CMD install; then
            log_error "CocoaPods installation failed"
            exit 1
        fi
        log_info "CocoaPods dependencies installed"
    else
        log_warn "No Podfile found, skipping pod install"
    fi
    
    # Copy canonical UI from www/index.html to test app
    log_step "Copying canonical UI from www/index.html..."
    # Use REPO_ROOT calculated before changing directories
    CANONICAL_UI="$REPO_ROOT/www/index.html"
    IOS_UI_SOURCE="$REPO_ROOT/$TEST_APP_DIR/App/App/Public/index.html"
    IOS_UI_RUNTIME="$REPO_ROOT/$TEST_APP_DIR/ios/App/App/public/index.html"
    
    if [ -f "$CANONICAL_UI" ]; then
        # Copy to source location (for Capacitor sync)
        if cp "$CANONICAL_UI" "$IOS_UI_SOURCE"; then
            log_info "Copied canonical UI to iOS test app source"
        else
            log_error "Failed to copy canonical UI to source"
            exit 1
        fi
        
        # Also copy directly to runtime location (in case sync doesn't run or is cached)
        if [ -d "$(dirname "$IOS_UI_RUNTIME")" ]; then
            if cp "$CANONICAL_UI" "$IOS_UI_RUNTIME"; then
                log_info "Copied canonical UI to iOS test app runtime"
            else
                log_warn "Failed to copy canonical UI to runtime (may be synced later)"
            fi
        else
            log_warn "Runtime directory not found, will be created by Capacitor sync"
        fi
    else
        log_warn "Canonical UI not found at $CANONICAL_UI, skipping copy"
    fi
    
    # Sync Capacitor from test app root (where capacitor.config.json is located)
    # This must run from test-apps/ios-test-app, not from ios/App/App
    log_step "Syncing Capacitor..."
    TEST_APP_ROOT="$REPO_ROOT/$TEST_APP_DIR"
    if [ -f "$TEST_APP_ROOT/capacitor.config.json" ] || [ -f "$TEST_APP_ROOT/capacitor.config.ts" ]; then
        if command -v npx &> /dev/null; then
            # Save current directory
            CURRENT_DIR="$(pwd)"
            # Change to test app root for sync
            cd "$TEST_APP_ROOT" || exit 1
            if ! npx cap sync ios; then
                log_error "Capacitor sync failed"
                cd "$CURRENT_DIR" || exit 1
                exit 1
            fi
            # Return to ios/App directory
            cd "$CURRENT_DIR" || exit 1
            log_info "Capacitor synced"
        else
            log_warn "npx not found, skipping Capacitor sync"
        fi
    else
        log_warn "Capacitor config not found at $TEST_APP_ROOT, skipping sync"
    fi
    
    # Build TypeScript/JavaScript if package.json exists
    if [ -f "package.json" ]; then
        log_step "Building web assets..."
        if [ -f "package.json" ] && grep -q "\"build\"" package.json; then
            if ! npm run build; then
                log_error "Web assets build failed"
                exit 1
            fi
            log_info "Web assets built"
        fi
    fi
    
    # Determine SDK and destination
    if [ "$TARGET" = "simulator" ]; then
        SDK="iphonesimulator"
        
        # Initialize simulator variables
        SIMULATOR_ID=""
        SIMULATOR_NAME=""
        
        # Auto-detect available iPhone simulator using device ID (more reliable)
        log_step "Detecting available iPhone simulator..."
        SIMULATOR_LINE=$(xcrun simctl list devices available 2>&1 | grep -i "iPhone" | head -1)
        
        if [ -n "$SIMULATOR_LINE" ]; then
            # Extract device ID (UUID in parentheses)
            SIMULATOR_ID=$(echo "$SIMULATOR_LINE" | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
            # Extract device name (everything before the first parenthesis)
            SIMULATOR_NAME=$(echo "$SIMULATOR_LINE" | sed -E 's/^[[:space:]]*([^(]+).*/\1/' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
            
            if [ -n "$SIMULATOR_ID" ] && [ "$SIMULATOR_ID" != "Shutdown" ] && [ "$SIMULATOR_ID" != "Booted" ]; then
                # Use device ID (most reliable)
                DESTINATION="platform=iOS Simulator,id=$SIMULATOR_ID"
                log_info "Building for iOS Simulator ($SIMULATOR_NAME, ID: $SIMULATOR_ID)..."
            elif [ -n "$SIMULATOR_NAME" ]; then
                # Fallback to device name
                DESTINATION="platform=iOS Simulator,name=$SIMULATOR_NAME"
                log_info "Building for iOS Simulator ($SIMULATOR_NAME)..."
            else
                # Last resort: generic destination
                DESTINATION="platform=iOS Simulator,name=Any iOS Simulator Device"
                log_warn "Using generic simulator destination"
            fi
        else
            # No iPhone simulators found, use generic
            DESTINATION="platform=iOS Simulator,name=Any iOS Simulator Device"
            log_warn "No iPhone simulators found, using generic destination"
        fi
        
        ARCHIVE_PATH="build/ios-test-app-simulator.xcarchive"
    else
        SDK="iphoneos"
        DESTINATION="generic/platform=iOS"
        ARCHIVE_PATH="build/ios-test-app-device.xcarchive"
    fi
    
    # Ensure UI is copied to runtime location one more time before build
    # (in case sync didn't run or was cached)
    log_step "Ensuring canonical UI is in runtime location before build..."
    if [ -f "$CANONICAL_UI" ] && [ -d "$(dirname "$IOS_UI_RUNTIME")" ]; then
        if cp "$CANONICAL_UI" "$IOS_UI_RUNTIME"; then
            log_info "Canonical UI copied to runtime location (pre-build)"
        fi
    fi
    
    # Clean build folder (removes old DerivedData)
    log_step "Cleaning build folder..."
    if [ -n "$WORKSPACE" ]; then
        xcodebuild clean -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration "$BUILD_CONFIG" -sdk "$SDK" || true
    else
        xcodebuild clean -project "$PROJECT" -scheme "$SCHEME" -configuration "$BUILD_CONFIG" -sdk "$SDK" || true
    fi
    
    # Also clean DerivedData for this specific project to remove cached HTML
    log_step "Cleaning DerivedData for fresh build..."
    DERIVED_DATA_PATH="$HOME/Library/Developer/Xcode/DerivedData"
    if [ -d "$DERIVED_DATA_PATH" ]; then
        # Find and remove DerivedData folders for this project
        find "$DERIVED_DATA_PATH" -maxdepth 1 -type d -name "App-*" -exec rm -rf {} \; 2>/dev/null || true
        log_info "DerivedData cleaned"
    fi
    
    # Build
    log_step "Building for $TARGET ($BUILD_CONFIG)..."
    if [ -n "$WORKSPACE" ]; then
        if ! xcodebuild build \
            -workspace "$WORKSPACE" \
            -scheme "$SCHEME" \
            -configuration "$BUILD_CONFIG" \
            -sdk "$SDK" \
            -destination "$DESTINATION" \
            CODE_SIGN_IDENTITY="" \
            CODE_SIGNING_REQUIRED=NO \
            CODE_SIGNING_ALLOWED=NO; then
            log_error "Build failed"
            exit 1
        fi
    else
        if ! xcodebuild build \
            -project "$PROJECT" \
            -scheme "$SCHEME" \
            -configuration "$BUILD_CONFIG" \
            -sdk "$SDK" \
            -destination "$DESTINATION" \
            CODE_SIGN_IDENTITY="" \
            CODE_SIGNING_REQUIRED=NO \
            CODE_SIGNING_ALLOWED=NO; then
            log_error "Build failed"
            exit 1
        fi
    fi
    
    log_info "Build successful!"
    
    # Find the built app in DerivedData
    if [ "$TARGET" = "simulator" ]; then
        # Xcode builds to DerivedData, find the app there
        DERIVED_DATA_PATH="$HOME/Library/Developer/Xcode/DerivedData"
        APP_PATH=$(find "$DERIVED_DATA_PATH" -name "App.app" -path "*/Build/Products/Debug-iphonesimulator/*" -type d 2>/dev/null | head -1)
        
        if [ -n "$APP_PATH" ]; then
            log_info "App built at: $APP_PATH"
            
            # Force copy canonical UI directly into built app bundle (ensures latest version)
            log_step "Copying canonical UI into built app bundle..."
            BUILT_APP_HTML="$APP_PATH/public/index.html"
            if [ -f "$CANONICAL_UI" ] && [ -d "$(dirname "$BUILT_APP_HTML")" ]; then
                if cp "$CANONICAL_UI" "$BUILT_APP_HTML"; then
                    log_info "✅ Canonical UI copied directly into app bundle"
                else
                    log_warn "Failed to copy UI into app bundle (may use cached version)"
                fi
            fi
            log_info ""
            
            # Boot simulator if not already booted
            log_step "Checking simulator status..."
            if [ -n "$SIMULATOR_ID" ]; then
                SIMULATOR_STATE=$(xcrun simctl list devices | grep "$SIMULATOR_ID" | grep -o "(Booted\|Shutdown)" | head -1)
                
                if [ "$SIMULATOR_STATE" != "Booted" ]; then
                    log_step "Booting simulator ($SIMULATOR_NAME)..."
                    xcrun simctl boot "$SIMULATOR_ID" 2>/dev/null || log_warn "Simulator may already be booting"
                    
                    # Open Simulator app if not already open
                    if ! pgrep -x "Simulator" > /dev/null; then
                        log_step "Opening Simulator app..."
                        open -a Simulator
                    fi
                    
                    # Wait for simulator to fully boot (up to 60 seconds)
                    log_step "Waiting for simulator to boot (this may take up to 60 seconds)..."
                    BOOT_TIMEOUT=60
                    ELAPSED=0
                    CURRENT_STATE="Shutdown"
                    while [ $ELAPSED -lt $BOOT_TIMEOUT ]; do
                        CURRENT_STATE=$(xcrun simctl list devices | grep "$SIMULATOR_ID" | grep -o "(Booted\|Shutdown)" | head -1)
                        if [ "$CURRENT_STATE" = "Booted" ]; then
                            log_info "Simulator booted successfully (took ${ELAPSED}s)"
                            # Give it a few more seconds to fully initialize
                            sleep 3
                            break
                        fi
                        if [ $((ELAPSED % 5)) -eq 0 ] && [ $ELAPSED -gt 0 ]; then
                            log_info "Still waiting... (${ELAPSED}s elapsed)"
                        fi
                        sleep 1
                        ELAPSED=$((ELAPSED + 1))
                    done
                    
                    if [ "$CURRENT_STATE" != "Booted" ]; then
                        log_warn "Simulator may not have finished booting (waited ${ELAPSED}s)"
                        log_warn "You may need to manually boot the simulator and try again"
                    else
                        # Verify simulator is actually ready (not just booted)
                        log_info "Verifying simulator is ready..."
                        READY_ATTEMPTS=0
                        MAX_READY_ATTEMPTS=10
                        while [ $READY_ATTEMPTS -lt $MAX_READY_ATTEMPTS ]; do
                            # Try a simple command to verify simulator is responsive
                            if xcrun simctl list devices | grep "$SIMULATOR_ID" | grep -q "Booted"; then
                                # Try to get device info to verify it's responsive
                                if xcrun simctl get_app_container "$SIMULATOR_ID" com.apple.Preferences >/dev/null 2>&1; then
                                    log_info "Simulator is ready"
                                    break
                                fi
                            fi
                            sleep 1
                            READY_ATTEMPTS=$((READY_ATTEMPTS + 1))
                        done
                        if [ $READY_ATTEMPTS -eq $MAX_READY_ATTEMPTS ]; then
                            log_warn "Simulator may not be fully ready yet"
                        fi
                    fi
                else
                    log_info "Simulator already booted"
                    # Verify it's actually ready
                    if ! xcrun simctl get_app_container "$SIMULATOR_ID" com.apple.Preferences >/dev/null 2>&1; then
                        log_warn "Simulator is booted but may not be fully ready"
                        log_info "Waiting a few seconds for simulator to be ready..."
                        sleep 5
                    fi
                fi
                
                # Uninstall existing app (if present) to ensure clean install
                log_step "Uninstalling existing app (if present)..."
                APP_BUNDLE_ID="org.timesafari.dailynotification.test"
                if xcrun simctl uninstall "$SIMULATOR_ID" "$APP_BUNDLE_ID" 2>&1; then
                    log_info "Existing app uninstalled"
                else
                    # App may not be installed, which is fine
                    log_info "No existing app to uninstall (or uninstall failed - continuing anyway)"
                fi
                
                # Wait a moment after uninstall
                sleep 1
                
                # Install the app
                log_step "Installing app on simulator..."
                if xcrun simctl install "$SIMULATOR_ID" "$APP_PATH" 2>&1; then
                    log_info "App installed successfully"
                else
                    log_warn "Install may have failed (app may already be installed)"
                fi
                
                # Wait a moment for install to complete
                sleep 1
                
                # Launch the app (try multiple methods)
                log_step "Launching app..."
                LAUNCH_SUCCESS=false
                LAUNCH_ERROR=""
                
                # Wait a moment for simulator to be fully ready
                sleep 2
                
                # Method 1: Direct launch (capture output to check for errors)
                # Note: Bundle ID is org.timesafari.dailynotification.test
                log_info "Attempting to launch app..."
                LAUNCH_OUTPUT=$(xcrun simctl launch "$SIMULATOR_ID" "$APP_BUNDLE_ID" 2>&1)
                LAUNCH_EXIT_CODE=$?
                
                if [ $LAUNCH_EXIT_CODE -eq 0 ]; then
                    # Check if output contains process ID (successful launch)
                    # Format can be either "PID" or "bundle: PID"
                    if echo "$LAUNCH_OUTPUT" | grep -qE "^[0-9]+$|^[^:]+: [0-9]+$"; then
                        LAUNCH_SUCCESS=true
                        # Extract PID (either standalone number or after colon)
                        APP_PID=$(echo "$LAUNCH_OUTPUT" | sed -E 's/^[^:]*:? *([0-9]+).*/\1/' | head -1)
                        log_info "✅ App launched successfully! (PID: $APP_PID)"
                    else
                        # Launch command succeeded but may not have actually launched
                        log_warn "Launch command returned success but output unexpected: $LAUNCH_OUTPUT"
                    fi
                else
                    # Capture error message
                    LAUNCH_ERROR="$LAUNCH_OUTPUT"
                    log_warn "Launch failed: $LAUNCH_ERROR"
                fi
                
                # Method 2: Verify app is actually running
                if [ "$LAUNCH_SUCCESS" = false ]; then
                    log_info "Checking if app is already running..."
                    sleep 2
                    RUNNING_APPS=$(xcrun simctl listapps "$SIMULATOR_ID" 2>/dev/null | grep -A 5 "$APP_BUNDLE_ID" || echo "")
                    
                    if [ -n "$RUNNING_APPS" ]; then
                        log_info "App appears to be installed. Trying to verify it's running..."
                        # Try to get app state
                        APP_STATE=$(xcrun simctl listapps "$SIMULATOR_ID" 2>/dev/null | grep -A 10 "$APP_BUNDLE_ID" | grep "ApplicationType" || echo "")
                        if [ -n "$APP_STATE" ]; then
                            log_info "App found in simulator. Attempting manual launch..."
                            # Try opening via Simulator app
                            open -a Simulator
                            sleep 1
                            # Try launch one more time
                            if xcrun simctl launch "$SIMULATOR_ID" "$APP_BUNDLE_ID" >/dev/null 2>&1; then
                                LAUNCH_SUCCESS=true
                                log_info "✅ App launched successfully on retry!"
                            fi
                        fi
                    fi
                fi
                
                # Final verification: check if app process is running
                if [ "$LAUNCH_SUCCESS" = true ]; then
                    sleep 2
                    # Try to verify app is running by checking if we can get its container
                    if xcrun simctl get_app_container "$SIMULATOR_ID" "$APP_BUNDLE_ID" >/dev/null 2>&1; then
                        log_info "✅ Verified: App is installed and accessible"
                    else
                        log_warn "⚠️  Launch reported success but app verification failed"
                        log_warn "   The app may still be starting. Check the Simulator."
                    fi
                else
                    log_warn "❌ Automatic launch failed"
                    log_info ""
                    log_info "The app is installed. To launch manually:"
                    log_info "  1. Open Simulator app (if not already open)"
                    log_info "  2. Find the app icon on the home screen and tap it"
                    log_info "  3. Or run: xcrun simctl launch $SIMULATOR_ID $APP_BUNDLE_ID"
                    if [ -n "$LAUNCH_ERROR" ]; then
                        log_info ""
                        log_info "Launch error details:"
                        log_info "  $LAUNCH_ERROR"
                    fi
                fi
                
                log_info ""
                log_info "✅ Build and deployment complete!"
            else
                log_info ""
                log_info "To run on simulator manually:"
                log_info "  xcrun simctl install booted \"$APP_PATH\""
                log_info "  xcrun simctl launch booted org.timesafari.dailynotification.test"
            fi
        else
            log_warn "Could not find built app in DerivedData"
            log_info "App was built successfully, but path detection failed."
            log_info "You can find it in Xcode's DerivedData folder or run from Xcode directly."
        fi
    else
        log_info ""
        log_info "To install on device:"
        log_info "  Open App.xcworkspace in Xcode"
        log_info "  Select your device"
        log_info "  Press Cmd+R to build and run"
    fi
    
    cd - > /dev/null
}

# Main execution
main() {
    log_info "iOS Test App Build Script"
    log_info "Target: $TARGET | Configuration: $BUILD_CONFIG"
    log_info ""
    
    check_environment
    
    # Get absolute path to repo root
    SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    REPO_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
    cd "$REPO_ROOT"
    
    build_ios_test_app
    
    log_info ""
    log_info "✅ Build complete!"
}

main "$@"

