#!/bin/bash
# build-web.sh
# Author: Matthew Raymer
# Description: Web build script for TimeSafari application
# This script handles the complete web build process including cleanup,
# environment setup, Vite build, and optional Docker containerization.
#
# Usage:
#   ./scripts/build-web.sh                    # Development build
#   ./scripts/build-web.sh --dev              # Development build (explicit)
#   ./scripts/build-web.sh --test             # Test environment build
#   ./scripts/build-web.sh --prod             # Production environment build
#   ./scripts/build-web.sh --docker           # Build with Docker containerization
#   ./scripts/build-web.sh --docker:test      # Test environment + Docker
#   ./scripts/build-web.sh --docker:prod      # Production environment + Docker
#   ./scripts/build-web.sh --serve            # Build and serve locally
#   ./scripts/build-web.sh --help             # Show help
#   ./scripts/build-web.sh --verbose          # Enable verbose logging
#
# NPM Script Equivalents:
#   npm run build:web                         # Development build
#   npm run build:web:test                    # Test environment build
#   npm run build:web:prod                    # Production environment build
#   npm run build:web:docker                  # Docker build
#   npm run build:web:docker:test             # Test Docker build
#   npm run build:web:docker:prod             # Production Docker build
#
# Exit Codes:
# 1 - Web cleanup failed
# 2 - Environment setup failed
# 3 - Vite build failed
# 4 - Docker build failed
# 5 - Serve command failed
# 6 - Invalid build mode

# Exit on any error
set -e

# Source common utilities
source "$(dirname "$0")/common.sh"

# Default values
BUILD_MODE="development"
BUILD_ACTION="build"
DOCKER_BUILD=false
SERVE_BUILD=false

# Function to show usage
show_usage() {
    cat << EOF
Usage: $0 [OPTIONS]

OPTIONS:
    --dev, --development    Build for development environment (default)
    --test                  Build for test environment
    --prod, --production    Build for production environment
    --docker                Build and create Docker container
    --docker:test           Build for test environment and create Docker container
    --docker:prod           Build for production environment and create Docker container
    --serve                 Build and serve locally
    --help                  Show this help message
    --verbose               Enable verbose logging
    --env                   Show environment variables

EXAMPLES:
    $0                                   # Development build
    $0 --test                            # Test environment build
    $0 --prod                            # Production environment build
    $0 --docker                          # Development + Docker
    $0 --docker:test                     # Test + Docker
    $0 --docker:prod                     # Production + Docker
    $0 --serve                           # Build and serve

BUILD MODES:
    development: Starts Vite development server with hot reload (default)
    test: Optimized for testing with minimal minification
    production: Optimized for production with full minification and optimization

EOF
}

# Function to parse web-specific arguments
parse_web_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --dev|--development)
                BUILD_MODE="development"
                shift
                ;;
            --test)
                BUILD_MODE="test"
                shift
                ;;
            --prod|--production)
                BUILD_MODE="production"
                shift
                ;;
            --docker)
                DOCKER_BUILD=true
                shift
                ;;
            --docker:test)
                BUILD_MODE="test"
                DOCKER_BUILD=true
                shift
                ;;
            --docker:prod)
                BUILD_MODE="production"
                DOCKER_BUILD=true
                shift
                ;;
            --serve)
                SERVE_BUILD=true
                shift
                ;;
            --help)
                show_usage
                exit 0
                ;;
            --verbose)
                VERBOSE=true
                shift
                ;;
            --env)
                print_env_vars "VITE_"
                exit 0
                ;;
            *)
                log_warn "Unknown option: $1"
                shift
                ;;
        esac
    done
}

# Function to validate web build environment
validate_web_environment() {
    log_info "Validating web build environment..."
    
    # Check if Node.js is available
    if ! check_command "node"; then
        log_error "Node.js is required but not installed"
        exit 2
    fi
    
    # Check if npm is available
    if ! check_command "npm"; then
        log_error "npm is required but not installed"
        exit 2
    fi
    
    # Check if Vite is available
    if ! check_command "npx"; then
        log_error "npx is required but not installed"
        exit 2
    fi
    
    # Check if package.json exists
    if ! check_file "package.json"; then
        log_error "package.json not found in current directory"
        exit 2
    fi
    
    log_success "Web build environment validated"
}

# Function to setup web-specific environment
setup_web_environment() {
    log_info "Setting up web environment for $BUILD_MODE mode..."
    
    # Set NODE_ENV based on build mode
    case $BUILD_MODE in
        "production")
            export NODE_ENV="production"
            ;;
        "test")
            export NODE_ENV="test"
            ;;
        "development"|*)
            export NODE_ENV="development"
            ;;
    esac
    
    # Load environment-specific .env file if it exists
    local env_file=".env.$BUILD_MODE"
    if [ -f "$env_file" ]; then
        load_env_file "$env_file"
    else
        log_debug "No $env_file file found, using default environment"
    fi
    
    # Load .env file if it exists (fallback)
    if [ -f ".env" ]; then
        load_env_file ".env"
    fi
    
    log_success "Web environment configured for $BUILD_MODE mode"
    log_debug "NODE_ENV=$NODE_ENV"
}

# Function to execute Vite build
execute_vite_build() {
    local mode="$1"
    log_info "Executing Vite build for $mode mode..."
    
    # Construct Vite build command
    local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite build --config vite.config.web.mts"
    
    # Add mode if not development (development is default)
    if [ "$mode" != "development" ]; then
        vite_cmd="$vite_cmd --mode $mode"
    fi
    
    log_debug "Vite command: $vite_cmd"
    
    if ! measure_time eval "$vite_cmd"; then
        log_error "Vite build failed for $mode mode!"
        exit 3
    fi
    
    log_success "Vite build completed for $mode mode"
}

# Function to execute Docker build
execute_docker_build() {
    local mode="$1"
    log_info "Executing Docker build for $mode mode..."
    
    # Build Docker image with appropriate tags
    local docker_cmd="docker build"
    local image_tag="timesafari-web"
    
    # Add build arguments
    docker_cmd="$docker_cmd --build-arg BUILD_MODE=$mode"
    docker_cmd="$docker_cmd --build-arg NODE_ENV=$NODE_ENV"
    
    # Add image tag
    docker_cmd="$docker_cmd -t $image_tag:$mode"
    docker_cmd="$docker_cmd -t $image_tag:latest"
    
    # Add context
    docker_cmd="$docker_cmd ."
    
    log_debug "Docker command: $docker_cmd"
    
    if ! measure_time eval "$docker_cmd"; then
        log_error "Docker build failed for $mode mode!"
        exit 4
    fi
    
    log_success "Docker build completed for $mode mode"
    log_info "Docker image available as: $image_tag:$mode"
}

# Function to run type checking based on build mode
run_type_checking() {
    local mode="$1"
    
    # Only run type checking for production and test builds
    if [ "$mode" = "production" ] || [ "$mode" = "test" ]; then
        log_info "Running TypeScript type checking for $mode mode..."
        
        if ! measure_time npm run type-check; then
            log_error "TypeScript type checking failed for $mode mode!"
            exit 2
        fi
        
        log_success "TypeScript type checking completed for $mode mode"
    else
        log_debug "Skipping TypeScript type checking for development mode"
    fi
}

# Function to start Vite development server
start_dev_server() {
    log_info "Starting Vite development server..."
    
    # Construct Vite dev server command
    local vite_cmd="VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) npx vite --config vite.config.web.mts"
    
    # Add mode if specified (though development is default)
    if [ "$BUILD_MODE" != "development" ]; then
        vite_cmd="$vite_cmd --mode $BUILD_MODE"
    fi
    
    log_debug "Vite dev server command: $vite_cmd"
    log_info "Starting development server on http://localhost:8080"
    
    # Start the development server (this will block and run the server)
    eval "$vite_cmd"
}

# Function to serve build locally
serve_build() {
    log_info "Serving build locally..."
    
    # Check if dist directory exists
    if [ ! -d "dist" ]; then
        log_error "dist directory not found. Build must be completed first."
        exit 5
    fi
    
    # Use a server that supports SPA routing (serves index.html for all routes)
    if command -v npx &> /dev/null; then
        log_info "Starting npx serve with SPA support on port 8080..."
        npx serve -s dist -l 8080
    elif command -v python3 &> /dev/null; then
        log_warn "Python HTTP server doesn't support SPA routing. Routes like /discover, /account will return 404."
        log_info "Starting Python HTTP server on port 8080..."
        cd dist && python3 -m http.server 8080
    elif command -v python &> /dev/null; then
        log_warn "Python HTTP server doesn't support SPA routing. Routes like /discover, /account will return 404."
        log_info "Starting Python HTTP server on port 8080..."
        cd dist && python -m SimpleHTTPServer 8080
    else
        log_error "No suitable HTTP server found. Install npx serve or Python."
        exit 5
    fi
}

# Parse command line arguments
parse_web_args "$@"

# Print build header
print_header "TimeSafari Web Build Process"
log_info "Starting web build process at $(date)"
log_info "Build mode: $BUILD_MODE"
log_info "Docker build: $DOCKER_BUILD"
log_info "Serve build: $SERVE_BUILD"

# Validate environment
validate_web_environment

# Setup environment for web build
setup_build_env "web" "$BUILD_MODE"

# Setup application directories
setup_app_directories

# Setup web-specific environment
setup_web_environment

# Handle different build modes
if [ "$BUILD_MODE" = "development" ] && [ "$DOCKER_BUILD" = false ] && [ "$SERVE_BUILD" = false ]; then
    # Development mode: Start dev server
    log_info "Development mode detected - starting development server"
    start_dev_server
    # Note: start_dev_server doesn't return, it runs the server
elif [ "$SERVE_BUILD" = true ]; then
    # Serve mode: Build then serve
    log_info "Serve mode detected - building then serving"
    
    # Step 1: Clean dist directory
    log_info "Cleaning dist directory..."
    clean_build_artifacts "dist"
    
    # Step 2: Run type checking (for production/test builds)
    safe_execute "Type checking for $BUILD_MODE mode" "run_type_checking $BUILD_MODE" || exit 2
    
    # Step 3: Execute Vite build
    safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
    
    # Step 3: Serve the build
    log_info "Starting local server..."
    serve_build
    # Note: serve_build doesn't return, it starts the server
else
    # Build mode: Build (and optionally Docker)
    log_info "Build mode detected - building for $BUILD_MODE"
    
    # Step 1: Clean dist directory
    log_info "Cleaning dist directory..."
    clean_build_artifacts "dist"
    
    # Step 2: Run type checking (for production/test builds)
    safe_execute "Type checking for $BUILD_MODE mode" "run_type_checking $BUILD_MODE" || exit 2
    
    # Step 3: Execute Vite build
    safe_execute "Vite build for $BUILD_MODE mode" "execute_vite_build $BUILD_MODE" || exit 3
    
    # Step 3: Execute Docker build if requested
    if [ "$DOCKER_BUILD" = true ]; then
        safe_execute "Docker build for $BUILD_MODE mode" "execute_docker_build $BUILD_MODE" || exit 4
    fi
    
    # Print build summary
    log_success "Web build completed successfully!"
    log_info "Build output available in: dist/"
    
    if [ "$DOCKER_BUILD" = true ]; then
        log_info "Docker image available as: timesafari-web:$BUILD_MODE"
    fi
    
    print_footer "Web Build"
    
    # Exit with success
    exit 0
fi 