#!/usr/bin/env bash

##############################################################
# Rust Documentation Generator with Custom Themes
# Generates beautiful Rust documentation with custom color schemes
##############################################################

set -euo pipefail

# Color definitions using tput
RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" BOLD="" DIM="" RESET=""

if [[ -t 1 ]] && command -v tput >/dev/null 2>&1; then
    COLORS=$(tput colors 2>/dev/null || echo 0)
    if [[ ${COLORS:-0} -ge 8 ]]; then
        RED=$(tput setaf 1 2>/dev/null || echo "")
        GREEN=$(tput setaf 2 2>/dev/null || echo "")
        YELLOW=$(tput setaf 3 2>/dev/null || echo "")
        BLUE=$(tput setaf 4 2>/dev/null || echo "")
        MAGENTA=$(tput setaf 5 2>/dev/null || echo "")
        CYAN=$(tput setaf 6 2>/dev/null || echo "")
        BOLD=$(tput bold 2>/dev/null || echo "")
        DIM=$(tput dim 2>/dev/null || echo "")
        RESET=$(tput sgr0 2>/dev/null || echo "")
    fi
fi

# Script paths
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly ASSETS_DIR="${SCRIPT_DIR}/assets/doc_rust_generate"
readonly THEME_DIR="${ASSETS_DIR}/theme"
readonly TMP_DIR="${SCRIPT_DIR}/tmp"

# Default values
OUTPUT_DIR="${PWD}/output"
PRIMARY_COLOR="#ff69b4"  # Default pink
STYLE="slate"
FONT_SANS="Inter"
FONT_MONO="JetBrains Mono"
INPUT_FILES=()
VERBOSE=false
DRY_RUN=false
SERVE=false
OPEN=false
SERVE_PORT=8000

# Style color mappings (neutral background colors)
declare -A STYLE_COLORS=(
    ["slate"]="#64748b"
    ["zinc"]="#71717a"
    ["neutral"]="#737373"
    ["stone"]="#78716c"
    ["gray"]="#6b7280"
)

##############################################################
# UI Functions
##############################################################

info() {
    echo "${BLUE}${BOLD}==>${RESET} $*"
}

success() {
    echo "${GREEN}${BOLD}[OK]${RESET} $*"
}

error() {
    echo "${RED}${BOLD}[ERROR]${RESET} $*" >&2
}

warning() {
    echo "${YELLOW}${BOLD}[WARN]${RESET} $*"
}

verbose() {
    if [[ "$VERBOSE" == true ]]; then
        echo "${DIM}  -> $*${RESET}"
    fi
    return 0
}

# Spinner for long-running operations
spinner() {
    local pid=$1
    local message=$2
    local delay=0.1
    local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'

    # Only show spinner if not verbose and output is a terminal
    if [[ "$VERBOSE" == true ]] || [[ ! -t 1 ]]; then
        wait "$pid"
        return $?
    fi

    echo -n "${message} "

    while kill -0 "$pid" 2>/dev/null; do
        local temp=${spinstr#?}
        printf "${CYAN}%c${RESET} " "$spinstr"
        spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b"
    done

    wait "$pid"
    local exit_code=$?

    if [[ $exit_code -eq 0 ]]; then
        printf "${GREEN}✓${RESET}\n"
    else
        printf "${RED}✗${RESET}\n"
    fi

    return $exit_code
}

##############################################################
# Help and Usage
##############################################################

show_help() {
    cat << EOF
${BOLD}${MAGENTA}Rust Documentation Generator with Custom Themes${RESET}

${BOLD}USAGE:${RESET}
    $(basename "$0") [OPTIONS] <inputs...>

${BOLD}DESCRIPTION:${RESET}
    Generate beautiful Rust documentation with custom color schemes and styling.
    Supports various input types including Rust projects, individual files, and more.

${BOLD}ARGUMENTS:${RESET}
    <inputs>                 Input file(s) or pattern(s) to document:
                             - Rust project directories (containing Cargo.toml)
                             - Individual .rs files
                             - Markdown files (.md)
                             - JSON/TOML configuration files
                             - Glob patterns (e.g., src/**/*.rs)

${BOLD}OPTIONS:${RESET}
    -o, --output DIR         Output directory for generated docs
                             (default: \$PWD/output)
    -c, --color COLOR        Primary accent color (hex format)
                             (default: #ff69b4)
                             Examples: #3498db, #10b981, #8b5cf6
    -s, --style STYLE        Background style theme
                             Options: slate, zinc, neutral, stone, gray
                             (default: slate)
    --font-sans FONT         Google Font for body text (default: Inter)
    --font-mono FONT         Google Font for code blocks
                             (default: JetBrains Mono)
    --serve                  Start HTTP server after generation
    --open                   Open documentation in browser (implies --serve)
    -p, --port PORT          Port for HTTP server (default: 8000)
    -v, --verbose            Enable verbose output
    -d, --dry-run            Show what would be done without executing
    -h, --help               Show this help message

${BOLD}EXAMPLES:${RESET}
    ${DIM}# Generate docs for current Rust project${RESET}
    $(basename "$0") .

    ${DIM}# Custom color scheme${RESET}
    $(basename "$0") . -c "#3498db" -s zinc -o ./docs

    ${DIM}# Document specific files${RESET}
    $(basename "$0") src/lib.rs src/main.rs -o ./api-docs

    ${DIM}# Use custom fonts${RESET}
    $(basename "$0") . --font-sans "Roboto" --font-mono "Fira Code"

    ${DIM}# Generate and open in browser${RESET}
    $(basename "$0") . --open

${BOLD}NOTES:${RESET}
    - Requires: cargo, rustdoc, bc, yq, jq, python3 with jinja2
    - Colors are automatically generated in light and dark variants
    - Google Fonts are automatically imported
    - Mermaid.js diagrams are automatically rendered

EOF
}

##############################################################
# Dependency Checks
##############################################################

check_dependencies() {
    local missing=()

    command -v cargo >/dev/null 2>&1 || missing+=("cargo")
    command -v rustdoc >/dev/null 2>&1 || missing+=("rustdoc")
    command -v bc >/dev/null 2>&1 || missing+=("bc")
    command -v yq >/dev/null 2>&1 || missing+=("yq")
    command -v jq >/dev/null 2>&1 || missing+=("jq")
    command -v python3 >/dev/null 2>&1 || missing+=("python3")

    if ! python3 -c "import jinja2" 2>/dev/null; then
        missing+=("python3-jinja2")
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        error "Missing required dependencies: ${missing[*]}"
        exit 1
    fi

    # Check for helper scripts
    if [[ ! -x "${SCRIPT_DIR}/css_color_palette.sh" ]]; then
        error "Helper script not found: ${SCRIPT_DIR}/css_color_palette.sh"
        exit 1
    fi

    if [[ ! -x "${SCRIPT_DIR}/jinja_template_render.sh" ]]; then
        error "Helper script not found: ${SCRIPT_DIR}/jinja_template_render.sh"
        exit 1
    fi

    return 0
}

##############################################################
# Input Processing
##############################################################

validate_color() {
    local color="$1"
    # Remove leading # if present
    color="${color#\#}"

    if [[ ! "$color" =~ ^[0-9A-Fa-f]{3}$ ]] && [[ ! "$color" =~ ^[0-9A-Fa-f]{6}$ ]]; then
        error "Invalid hex color: $1"
        error "Expected format: #RGB or #RRGGBB"
        exit 1
    fi

    # Ensure 6-digit format
    if [[ ${#color} -eq 3 ]]; then
        color="${color:0:1}${color:0:1}${color:1:1}${color:1:1}${color:2:1}${color:2:1}"
    fi

    echo "#${color}"
}

validate_style() {
    local style="$1"

    case "$style" in
        slate|zinc|neutral|stone|gray)
            echo "$style"
            ;;
        *)
            error "Invalid style: $style"
            error "Valid options: slate, zinc, neutral, stone, gray"
            exit 1
            ;;
    esac
}

##############################################################
# Color Palette Generation
##############################################################

generate_color_palette() {
    local primary_color="$1"
    local style="$2"
    local output_file="$3"

    verbose "Primary color: $primary_color"
    verbose "Style: $style"

    # Generate primary color palette (monochromatic)
    if [[ "$VERBOSE" == false ]]; then
        info "Generating color palette..."
    fi

    if ! "${SCRIPT_DIR}/css_color_palette.sh" "$primary_color" \
        -p monochromatic \
        -o "${TMP_DIR}/primary_palette.yaml" \
        -m dark \
        -s all >/dev/null 2>&1; then
        error "Failed to generate primary color palette"
        return 1
    fi

    verbose "Generated primary palette: ${TMP_DIR}/primary_palette.yaml"

    if [[ "$VERBOSE" == false ]]; then
        success "Color palette generated"
    fi
}

##############################################################
# CSS Variables Generation
##############################################################

generate_css_variables() {
    local primary_color="$1"
    local style="$2"
    local output_file="$3"

    info "Generating CSS variables..."

    # Read the generated palette
    local palette_file="${TMP_DIR}/primary_palette.yaml"

    if [[ ! -f "$palette_file" ]]; then
        error "Palette file not found: $palette_file"
        return 1
    fi

    # Extract color values from the palette
    local primary_50 primary_100 primary_200 primary_300 primary_400
    local primary_500 primary_600 primary_700 primary_800 primary_900 primary_950

    primary_50=$(yq -r '.colors.primary."50"' "$palette_file")
    primary_100=$(yq -r '.colors.primary."100"' "$palette_file")
    primary_200=$(yq -r '.colors.primary."200"' "$palette_file")
    primary_300=$(yq -r '.colors.primary."300"' "$palette_file")
    primary_400=$(yq -r '.colors.primary."400"' "$palette_file")
    primary_500=$(yq -r '.colors.primary."500"' "$palette_file")
    primary_600=$(yq -r '.colors.primary."600"' "$palette_file")
    primary_700=$(yq -r '.colors.primary."700"' "$palette_file")
    primary_800=$(yq -r '.colors.primary."800"' "$palette_file")
    primary_900=$(yq -r '.colors.primary."900"' "$palette_file")
    primary_950=$(yq -r '.colors.primary."950"' "$palette_file")

    # Get style-specific colors (from existing theme.yaml)
    local style_file="${THEME_DIR}/theme.yaml"

    # Generate CSS custom properties
    cat > "$output_file" << EOF
/* Generated CSS Variables for Rustdoc Theme */
/* Primary Color: ${primary_color} */
/* Style: ${style} */

/* Import Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=${FONT_SANS// /+}:wght@300;400;500;600;700&family=${FONT_MONO// /+}:wght@400;500;600;700&display=swap');

/* Base variables for all themes */
:root {
    /* Primary color palette */
    --primary-50: ${primary_50};
    --primary-100: ${primary_100};
    --primary-200: ${primary_200};
    --primary-300: ${primary_300};
    --primary-400: ${primary_400};
    --primary-500: ${primary_500};
    --primary-600: ${primary_600};
    --primary-700: ${primary_700};
    --primary-800: ${primary_800};
    --primary-900: ${primary_900};
    --primary-950: ${primary_950};

    /* Google Fonts */
    --font-family: '${FONT_SANS}', 'Fira Sans', Arial, sans-serif;
    --font-family-code: '${FONT_MONO}', 'Fira Mono', monospace;
}

/* Dark theme overrides */
:root[data-theme="dark"] {
EOF

    # Now read the theme.yaml and replace color references with our palette
    verbose "Processing theme variables..."

    # Read theme.yaml and substitute colors
    while IFS=': ' read -r key value; do
        # Skip empty lines and comments
        [[ -z "$key" || "$key" =~ ^# ]] && continue

        # Remove quotes and leading/trailing whitespace
        value="${value#\"}"
        value="${value%\"}"
        value="${value#\'}"
        value="${value%\'}"
        value="${value# }"
        value="${value% }"

        # Replace hardcoded colors with our palette where appropriate
        # This is a simple substitution - for primary/accent colors use our palette
        if [[ "$value" == "#ff69b4" || "$value" == "#ff1493" || "$value" == "#ec407a" ]]; then
            value="${primary_500}"
        elif [[ "$value" == "#f06292" ]]; then
            value="${primary_400}"
        fi

        echo "    --${key}: ${value};" >> "$output_file"
    done < <(grep -E '^[a-zA-Z]' "$style_file" || true)

    # Close the dark theme block
    echo "}" >> "$output_file"

    # Add light theme variant (with adjusted colors)
    cat >> "$output_file" << EOF

/* Light theme overrides */
:root[data-theme="light"] {
EOF

    # For light theme, read theme.yaml again but use lighter colors
    while IFS=': ' read -r key value; do
        # Skip empty lines and comments
        [[ -z "$key" || "$key" =~ ^# ]] && continue

        # Remove quotes and leading/trailing whitespace
        value="${value#\"}"
        value="${value%\"}"
        value="${value#\'}"
        value="${value%\'}"
        value="${value# }"
        value="${value% }"

        # For light theme, invert dark backgrounds to light
        case "$key" in
            *background*|*-bg-*)
                # Use lighter shades for backgrounds
                if [[ "$value" == "#2f3542" ]]; then
                    value="#f8f9fa"  # main background
                elif [[ "$value" == "#1e272e" ]]; then
                    value="#ffffff"  # secondary background
                elif [[ "$value" == "#24272e" ]]; then
                    value="#f1f3f5"  # hover background
                fi
                ;;
            *color*|*-fg-*)
                # Use darker text for light backgrounds
                if [[ "$value" == "#e8eaed" ]]; then
                    value="#2f3542"  # main text color
                elif [[ "$value" == "#ffffff" ]]; then
                    value="#000000"  # white text -> black
                fi
                ;;
            *border*)
                # Adjust borders for light theme
                if [[ "$value" == "#57606f" ]]; then
                    value="#dee2e6"
                fi
                ;;
        esac

        # Replace primary accent colors with our palette
        if [[ "$value" == "#ff69b4" || "$value" == "#ff1493" || "$value" == "#ec407a" ]]; then
            value="${primary_600}"  # Slightly darker for light theme
        elif [[ "$value" == "#f06292" ]]; then
            value="${primary_500}"
        fi

        echo "    --${key}: ${value};" >> "$output_file"
    done < <(grep -E '^[a-zA-Z]' "$style_file" || true)

    # Close the light theme block
    echo "}" >> "$output_file"

    verbose "Generated CSS variables: $output_file"
    success "CSS variables generated"
}

##############################################################
# Render Header Template
##############################################################

render_header_template() {
    local output_file="$1"

    info "Rendering header template..."

    # Process mermaid.yaml variables to match our theme
    local mermaid_yaml="${TMP_DIR}/mermaid_processed.yaml"

    # Copy and update mermaid colors
    cp "${THEME_DIR}/mermaid.yaml" "$mermaid_yaml"

    # Update with our primary color
    yq -i ".primaryColor = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".lineColor = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".border1 = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".noteBorderColor = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".arrowheadColor = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".clusterBorder = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".defaultLinkColor = \"${PRIMARY_COLOR}\"" "$mermaid_yaml"
    yq -i ".fontFamily = \"${FONT_SANS}, system-ui, -apple-system, sans-serif\"" "$mermaid_yaml"

    verbose "Processed mermaid config: $mermaid_yaml"

    # Render the Jinja2 template
    if ! "${SCRIPT_DIR}/jinja_template_render.sh" \
        -f "$mermaid_yaml" \
        -o "${TMP_DIR}" \
        "${THEME_DIR}/header.html.jinja"; then
        error "Failed to render header template"
        return 1
    fi

    # Move rendered file to expected location if different
    if [[ "${TMP_DIR}/header.html" != "$output_file" ]]; then
        mv "${TMP_DIR}/header.html" "$output_file"
    fi

    verbose "Rendered header: $output_file"
    success "Header template rendered"
}

##############################################################
# Consolidate CSS
##############################################################

consolidate_css() {
    local output_file="$1"

    info "Consolidating CSS files..."

    # Combine variables.css and theme.css
    cat "${TMP_DIR}/variables.css" > "$output_file"
    echo "" >> "$output_file"
    cat "${THEME_DIR}/theme.css" >> "$output_file"

    verbose "Consolidated CSS: $output_file"
    success "CSS consolidated"
}

##############################################################
# Run Rustdoc
##############################################################

run_rustdoc() {
    local inputs=("$@")

    info "Running rustdoc..."

    local header_file="${TMP_DIR}/header.html"
    local css_file="${TMP_DIR}/theme-combined.css"

    # Determine if we're documenting a cargo project or individual files
    local is_cargo_project=false

    for input in "${inputs[@]}"; do
        if [[ -f "${input}/Cargo.toml" ]] || [[ -f "${input%/}/Cargo.toml" ]]; then
            is_cargo_project=true
            break
        fi
    done

    if [[ "$is_cargo_project" == true ]]; then
        info "Detected Cargo project, using 'cargo doc'..."

        # Find the Cargo.toml directory
        local cargo_dir=""
        for input in "${inputs[@]}"; do
            if [[ -f "${input}/Cargo.toml" ]]; then
                cargo_dir="$input"
                break
            elif [[ -f "${input%/}/Cargo.toml" ]]; then
                cargo_dir="${input%/}"
                break
            fi
        done

        # Build cargo doc command with custom theme
        local cargo_args=(
            "doc"
            "--no-deps"
            "--target-dir" "${OUTPUT_DIR}"
        )

        # Set RUSTDOCFLAGS environment variable for custom styling
        export RUSTDOCFLAGS="--html-in-header ${header_file} --extend-css ${css_file}"

        if [[ "$VERBOSE" == true ]]; then
            cargo_args+=("-v")
        fi

        verbose "Running: cargo ${cargo_args[*]}"
        verbose "RUSTDOCFLAGS: $RUSTDOCFLAGS"

        if [[ "$DRY_RUN" == true ]]; then
            warning "Dry run: would execute cargo ${cargo_args[*]}"
        else
            if [[ "$VERBOSE" == false ]]; then
                info "Running cargo doc (this may take a while)..."
            fi

            # In non-verbose mode, show cargo progress messages
            if [[ "$VERBOSE" == true ]]; then
                # Verbose: show everything
                if ! (cd "$cargo_dir" && cargo "${cargo_args[@]}"); then
                    error "cargo doc failed"
                    return 1
                fi
            else
                # Non-verbose: filter output to show only important messages
                if ! (cd "$cargo_dir" && cargo "${cargo_args[@]}" 2>&1 | grep -E '(Documenting|Compiling|Finished|error|warning)' || true); then
                    # Check if cargo actually failed
                    if ! (cd "$cargo_dir" && cargo "${cargo_args[@]}" >/dev/null 2>&1); then
                        error "cargo doc failed"
                        return 1
                    fi
                fi
            fi

            success "Documentation generated successfully"
            info "Output directory: ${OUTPUT_DIR}/doc"
        fi
    else
        # Document individual files using rustdoc directly
        warning "Individual file documentation not fully implemented yet"
        warning "Please provide a Cargo project directory"
        return 1
    fi
}

##############################################################
# Serve and Open Documentation
##############################################################

serve_and_open_docs() {
    local doc_dir="${OUTPUT_DIR}/doc"
    local index_file="${doc_dir}/universal_lsp/index.html"

    # Find the actual index.html file (might be in different location)
    if [[ ! -f "$index_file" ]]; then
        # Try to find any index.html in the doc directory
        index_file=$(find "$doc_dir" -name "index.html" -type f | head -1)
        if [[ -z "$index_file" ]]; then
            warning "Could not find index.html in documentation"
            index_file="${doc_dir}/index.html"
        fi
    fi

    # Get the relative path from doc_dir to index_file for the URL
    local rel_path="${index_file#$doc_dir/}"
    local url="http://localhost:${SERVE_PORT}/${rel_path}"

    info "Starting HTTP server on port ${SERVE_PORT}..."
    echo ""

    # Start Python HTTP server in the background
    cd "$doc_dir" || {
        error "Failed to change to documentation directory: $doc_dir"
        return 1
    }

    # Kill any existing server on this port
    if lsof -Pi ":${SERVE_PORT}" -sTCP:LISTEN -t >/dev/null 2>&1; then
        warning "Port ${SERVE_PORT} is already in use. Trying to kill existing process..."
        lsof -Pi ":${SERVE_PORT}" -sTCP:LISTEN -t | xargs kill -9 2>/dev/null || true
        sleep 1
    fi

    # Start server
    python3 -m http.server "$SERVE_PORT" >/dev/null 2>&1 &
    local server_pid=$!

    # Give the server a moment to start
    sleep 1

    # Check if server started successfully
    if ! kill -0 "$server_pid" 2>/dev/null; then
        error "Failed to start HTTP server"
        return 1
    fi

    success "Server started (PID: $server_pid)"
    info "Documentation available at: ${CYAN}${url}${RESET}"

    # Open in browser if requested
    if [[ "$OPEN" == true ]]; then
        info "Opening documentation in browser..."

        # Try different browser openers
        if command -v xdg-open >/dev/null 2>&1; then
            xdg-open "$url" >/dev/null 2>&1 &
        elif command -v open >/dev/null 2>&1; then
            open "$url" >/dev/null 2>&1 &
        elif command -v sensible-browser >/dev/null 2>&1; then
            sensible-browser "$url" >/dev/null 2>&1 &
        else
            warning "Could not detect browser opener (xdg-open, open, sensible-browser)"
            info "Please open manually: $url"
        fi

        sleep 1
        success "Browser opened"
    fi

    echo ""
    echo "${BOLD}${GREEN}Server running!${RESET}"
    echo "${DIM}Press Ctrl+C to stop the server${RESET}"
    echo ""

    # Wait for Ctrl+C
    trap "echo ''; info 'Shutting down server...'; kill $server_pid 2>/dev/null; success 'Server stopped'; exit 0" INT TERM

    # Keep the script running
    wait "$server_pid"
}

##############################################################
# Cleanup
##############################################################

cleanup() {
    if [[ "$VERBOSE" == true ]]; then
        verbose "Temporary files preserved in: ${TMP_DIR}"
    fi
}

trap cleanup EXIT

##############################################################
# Main Function
##############################################################

main() {
    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -o|--output)
                OUTPUT_DIR="$2"
                shift 2
                ;;
            -c|--color)
                PRIMARY_COLOR=$(validate_color "$2")
                shift 2
                ;;
            -s|--style)
                STYLE=$(validate_style "$2")
                shift 2
                ;;
            --font-sans)
                FONT_SANS="$2"
                shift 2
                ;;
            --font-mono)
                FONT_MONO="$2"
                shift 2
                ;;
            --serve)
                SERVE=true
                shift
                ;;
            --open)
                OPEN=true
                SERVE=true  # Opening implies serving
                shift
                ;;
            -p|--port)
                SERVE_PORT="$2"
                shift 2
                ;;
            -v|--verbose)
                VERBOSE=true
                shift
                ;;
            -d|--dry-run)
                DRY_RUN=true
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            -*)
                error "Unknown option: $1"
                echo "Use -h or --help for usage information"
                exit 1
                ;;
            *)
                INPUT_FILES+=("$1")
                shift
                ;;
        esac
    done

    # Print banner
    echo "${MAGENTA}${BOLD}"
    echo "=============================================="
    echo "  Rust Documentation Generator"
    echo "=============================================="
    echo "${RESET}"

    # Check dependencies
    info "Checking dependencies..."
    check_dependencies
    success "All dependencies found"

    # Validate inputs
    if [[ ${#INPUT_FILES[@]} -eq 0 ]]; then
        error "No input files specified"
        echo "Use -h or --help for usage information"
        exit 1
    fi

    # Create temporary directory
    mkdir -p "$TMP_DIR"
    verbose "Temporary directory: $TMP_DIR"

    # Show configuration
    echo ""
    info "Configuration:"
    echo "  Primary Color: ${PRIMARY_COLOR}"
    echo "  Style: ${STYLE}"
    echo "  Font Sans: ${FONT_SANS}"
    echo "  Font Mono: ${FONT_MONO}"
    echo "  Output: ${OUTPUT_DIR}"
    echo "  Inputs: ${INPUT_FILES[*]}"
    echo ""

    # Generate color palette
    generate_color_palette "$PRIMARY_COLOR" "$STYLE" "${TMP_DIR}/palette.yaml"

    # Generate CSS variables
    generate_css_variables "$PRIMARY_COLOR" "$STYLE" "${TMP_DIR}/variables.css"

    # Render header template
    render_header_template "${TMP_DIR}/header.html"

    # Consolidate CSS
    consolidate_css "${TMP_DIR}/theme-combined.css"

    # Run rustdoc
    run_rustdoc "${INPUT_FILES[@]}"

    echo ""
    success "Documentation generation complete!"

    if [[ "$DRY_RUN" == false ]]; then
        info "View your documentation:"
        echo "  ${CYAN}${OUTPUT_DIR}/doc/index.html${RESET}"

        # Serve and/or open documentation if requested
        if [[ "$SERVE" == true ]]; then
            echo ""
            serve_and_open_docs
        fi
    fi

    echo ""
}

# Run main function
main "$@"
