#!/bin/bash

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
BOLD='\033[1m'

# Unicode symbols
CHECK="✓"
CROSS="✗"
ARROW="➜"
GEAR="⚙"
HAMMER="🔨"
ROCKET="🚀"

# Default values
BUILD_TYPE="Debug"
CLEAN_BUILD=false
VERBOSE=false
JOBS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)

# Print functions
print_header() {
    echo -e "${BOLD}${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
    echo -e "${BOLD}${BLUE}║${NC}  ${HAMMER} ${BOLD}${CYAN} C/C++ Project Builder${NC}                          ${BOLD}${BLUE}║${NC}"
    echo -e "${BOLD}${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

print_separator() {
    echo -e "${BLUE}────────────────────────────────────────────────────────${NC}"
}

print_success() {
    echo -e "${GREEN}${CHECK}${NC} $1"
}

print_error() {
    echo -e "${RED}${CROSS}${NC} $1"
}

print_info() {
    echo -e "${CYAN}${ARROW}${NC} $1"
}

print_step() {
    echo -e "${YELLOW}${GEAR}${NC} ${BOLD}$1${NC}"
}

show_progress() {
    local duration=$1
    local prefix=$2
    local size=40
    already_done() { for ((done=0; done<$elapsed; done++)); do printf "▓"; done }
    remaining() { for ((remain=$elapsed; remain<$size; remain++)); do printf " "; done }
    percentage() { printf "| %s%%" $(( (($elapsed)*100)/($size)*100/100 )); }
    
    for (( elapsed=1; elapsed<=$size; elapsed++ )); do
        printf "\r${CYAN}${prefix}${NC} [$(already_done)$(remaining)] $(percentage)"
        sleep $(echo "scale=3; $duration/$size" | bc)
    done
    printf "\n"
}

usage() {
    echo -e "${BOLD}Usage:${NC} $0 [OPTIONS] <executable_name>"
    echo ""
    echo -e "${BOLD}Options:${NC}"
    echo -e "  -r, --release         Build in Release mode (default: Debug)"
    echo -e "  -c, --clean           Clean build directory before building"
    echo -e "  -v, --verbose         Verbose make output"
    echo -e "  -j, --jobs <N>        Number of parallel jobs (default: $JOBS)"
    echo -e "  -h, --help            Show this help message"
    echo ""
    echo -e "${BOLD}Examples:${NC}"
    echo -e "  $0 myprogram"
    echo -e "  $0 -r -j8 myprogram"
    echo -e "  $0 --clean --release myprogram"
    exit 1
}

# Parse arguments
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
    case $1 in
        -r|--release)
            BUILD_TYPE="Release"
            shift
            ;;
        -c|--clean)
            CLEAN_BUILD=true
            shift
            ;;
        -v|--verbose)
            VERBOSE=true
            shift
            ;;
        -j|--jobs)
            JOBS="$2"
            shift 2
            ;;
        -h|--help)
            usage
            ;;
        *)
            POSITIONAL_ARGS+=("$1")
            shift
            ;;
    esac
done

set -- "${POSITIONAL_ARGS[@]}"

# Check if executable name is provided
if [ -z "$1" ]; then
    print_header
    print_error "No executable name provided"
    echo ""
    usage
fi

EXECUTABLE_NAME=$1

# Start build process
print_header

# Build configuration info
print_info "Build Configuration:"
echo -e "  ${BOLD}Executable:${NC}   $EXECUTABLE_NAME"
echo -e "  ${BOLD}Build Type:${NC}   $BUILD_TYPE"
echo -e "  ${BOLD}Jobs:${NC}         $JOBS"
echo -e "  ${BOLD}Clean Build:${NC}  $CLEAN_BUILD"
echo ""
print_separator
echo ""

# Clean build directory if requested
if [ "$CLEAN_BUILD" = true ] && [ -d "./build" ]; then
    print_step "Cleaning build directory..."
    rm -rf ./build
    print_success "Build directory cleaned"
    echo ""
fi

# Create build directory
if [ ! -d "./build" ]; then
    print_step "Creating build directory..."
    mkdir -p build
    print_success "Build directory created"
else
    print_info "Using existing build directory"
fi
echo ""

# CMake configuration
print_step "Configuring CMake..."
print_separator
echo ""

cd ./build

CMAKE_CMD="cmake -DOUTPUT_NAME=$EXECUTABLE_NAME -DCMAKE_BUILD_TYPE=$BUILD_TYPE .."

if [ "$VERBOSE" = true ]; then
    eval $CMAKE_CMD
else
    eval $CMAKE_CMD > /dev/null 2>&1
fi

if [ $? -ne 0 ]; then
    print_error "CMake configuration failed"
    exit 1
fi

print_success "CMake configuration complete"
echo ""

# Compilation
print_step "Compiling project..."
print_separator
echo ""

MAKE_CMD="make -j$JOBS"
if [ "$VERBOSE" = true ]; then
    MAKE_CMD="$MAKE_CMD VERBOSE=1"
fi

START_TIME=$(date +%s)

if [ "$VERBOSE" = true ]; then
    eval $MAKE_CMD
    BUILD_RESULT=$?
else
    eval $MAKE_CMD 2>&1 | tee build.log | while IFS= read -r line; do
        if echo "$line" | grep -q "\[.*%\]"; then
            printf "\r${CYAN}${ARROW}${NC} Compiling: %s" "$line"
        elif echo "$line" | grep -qE "error:|Error|ERROR"; then
            echo ""
            print_error "$line"
        fi
    done
    BUILD_RESULT=${PIPESTATUS[0]}
fi

END_TIME=$(date +%s)
BUILD_TIME=$((END_TIME - START_TIME))

echo ""

if [ $BUILD_RESULT -ne 0 ]; then
    print_error "Build failed!"
    echo ""
    print_info "Check build/build.log for details"
    exit 1
fi

print_success "Compilation complete (${BUILD_TIME}s)"
echo ""

# Copy executable
print_step "Copying executable to project root..."

if [ ! -f "./bin/$EXECUTABLE_NAME" ]; then
    print_error "Executable not found: ./bin/$EXECUTABLE_NAME"
    exit 1
fi

cp ./bin/$EXECUTABLE_NAME ../
print_success "Executable copied"
echo ""

# Build summary
print_separator
echo -e "${BOLD}${GREEN}${ROCKET} Build Complete!${NC}"
print_separator
echo ""
echo -e "${BOLD}Summary:${NC}"
echo -e "  ${BOLD}Executable:${NC}      ./$EXECUTABLE_NAME"
echo -e "  ${BOLD}Build Type:${NC}      $BUILD_TYPE"
echo -e "  ${BOLD}Build Time:${NC}      ${BUILD_TIME}s"
echo -e "  ${BOLD}Binary Location:${NC} ./build/bin/$EXECUTABLE_NAME"

echo ""
print_info "Run with: ${BOLD}./$EXECUTABLE_NAME${NC}"
echo ""
