#!/usr/bin/env bash

set -euo pipefail
trap 'echo "❌ Error on line $LINENO: $BASH_COMMAND"' ERR

echo "🏗️  Building Binaries (using mise or system tools + .ci-versions config)"
echo ""

# Check OS
OS_MAC='mac'
OS_LINUX='linux'

os_type=$(uname)
os=''

if [[ "$os_type" == "Darwin" ]]; then
  os=$OS_MAC
elif [[ "$os_type" == "Linux" ]]; then
  os=$OS_LINUX
else
  echo "Unsupported OS: $os_type"
  exit 1
fi

echo "💾 OS: $os"
echo ""

# ===================================================
# CONFIGURATION
# ===================================================

# Source centralized CI versions file to avoid duplication (strict; no fallbacks)
CI_VERSIONS_FILE="$(cd "$(dirname "$0")"/.. && pwd)/.ci-versions"
if [ ! -f "$CI_VERSIONS_FILE" ]; then
  echo "❌ Required CI versions file missing at $CI_VERSIONS_FILE" >&2
  exit 1
fi
# shellcheck disable=SC1090
. "$CI_VERSIONS_FILE"

# Validate required variables (subset needed for this build script plus others for reporting)
required_vars=(
  EXPECTED_MACOS_VERSION
  EXPECTED_XCODE_VERSION
  EXPECTED_ANDROID_SDK_VERSION
  EXPECTED_ANDROID_BUILD_TOOLS_VERSION
  EXPECTED_ANDROID_NDK_VERSION
  EXPECTED_NODE_VERSION
  EXPECTED_RUBY_VERSION
  EXPECTED_JAVA_VERSION
)
for v in "${required_vars[@]}"; do
  if [ -z "${!v:-}" ]; then
    echo "❌ Required variable $v not set in $CI_VERSIONS_FILE" >&2
    exit 1
  fi
done

# ===================================================
# LOAD ENVIRONMENT
# ===================================================

if [ -f "$HOME/.bashrc" ]; then
    echo "🔄 Sourcing ~/.bashrc..."
    set +u
    source "$HOME/.bashrc"
    set -u
else
    echo "❌ ~/.bashrc not found. Cannot load environment."
    exit 1
fi

# ===================================================
# ACTIVATE MISE (or use system tools)
# ===================================================

if command -v mise >/dev/null 2>&1; then
    echo "🔧 Activating mise for tool version management..."
    eval "$(mise activate bash)"
    mise trust ~/mise.toml 2>/dev/null || true
    mise trust ./mise.toml 2>/dev/null || true
    echo "📦 Installing tool versions from mise.toml (this may take a few minutes if compiling)..."
    mise install 2>&1 || { echo "❌ mise install failed"; exit 1; }
    echo "✅ mise tools ready"
    echo "📦 Verifying mise is managing versions..."
else
    echo "⚠️  mise not found in PATH - using system-installed tools"
    echo "   (This is expected in Docker Android environments)"
    echo "📦 Verifying system-installed tool versions..."
fi

echo "  🌍 Node.js: $(node -v 2>/dev/null || echo 'Not available')"
echo "  💎 Ruby: $(ruby -v 2>/dev/null | awk '{print $2}' || echo 'Not available')"
echo "  ☕ Java: $(java -version 2>&1 | head -n1 | awk -F'"' '{print $2}' || echo 'Not available')"

# ===================================================
# DISPLAY SYSTEM INFORMATION
# ===================================================

if [ "$os" = "$OS_MAC" ]; then
    # Use the comprehensive display_about function from setup-mac-mini.sh on Mac
    SETUP_SCRIPT="./scripts/setup-mac-mini.sh"
    if [ -f "$SETUP_SCRIPT" ]; then
        echo ""
        echo "📊 Displaying system information via setup-mac-mini.sh..."
        set +e  # Temporarily disable exit on error for display_about
        bash "$SETUP_SCRIPT" about
        set -e  # Re-enable exit on error
    else
        echo "⚠️  Warning: setup-mac-mini.sh not found at: $SETUP_SCRIPT"
        echo "Skipping detailed system information display."
    fi
else
    # Detailed system info display for Linux (Docker Android builds)
    echo ""
    echo "📊 System Information (Linux/Docker)"
    echo "  🐧 OS: Linux"

    # Detect versions
    detected_node=$(node -v 2>/dev/null | sed 's/v//g' || echo 'Not Installed')
    detected_ruby=$(ruby -v 2>/dev/null | awk '{print $2}' || echo 'Not Installed')
    detected_java=$(java -version 2>&1 | head -n1 | awk -F'"' '{print $2}' || echo 'Not Installed')
    detected_yarn=$(yarn -v 2>/dev/null || echo 'Not Installed')

    # Strip suffix from expected Java version for comparison
    expected_java_display="${EXPECTED_JAVA_VERSION%%-*}"

    # Compare and show status
    node_status="❌"; [ "$detected_node" = "$EXPECTED_NODE_VERSION" ] && node_status="✅"
    ruby_status="❌"; [ "$detected_ruby" = "$EXPECTED_RUBY_VERSION" ] && ruby_status="✅"
    java_status="❌"; [ "$detected_java" = "$expected_java_display" ] && java_status="✅"

    printf "  🌍 Node.js:              %-15s Expected: %-15s %s\n" "$detected_node" "$EXPECTED_NODE_VERSION" "$node_status"
    printf "  💎 Ruby:                 %-15s Expected: %-15s %s\n" "$detected_ruby" "$EXPECTED_RUBY_VERSION" "$ruby_status"
    printf "  ☕ Java:                 %-15s Expected: %-15s %s\n" "$detected_java" "$expected_java_display" "$java_status"
    printf "  📦 Yarn:                 %s\n" "$detected_yarn"

    if command -v sdkmanager >/dev/null 2>&1; then
        echo "  📱 Android SDK: Available"
    else
        echo "  📱 Android SDK: Not Installed"
    fi
fi
echo ""

# ===================================================
# VALIDATE VERSIONS
# ===================================================

echo "🔍 Validating environment versions..."

# Detect versions based on OS
if [ "$os" = "$OS_MAC" ]; then
    # Get detected versions from setup-mac-mini.sh (DRY - single source of truth)
    SETUP_SCRIPT="./scripts/setup-mac-mini.sh"
    if [ -f "$SETUP_SCRIPT" ]; then
        eval "$(bash "$SETUP_SCRIPT" export-versions)"
    else
        echo "❌ Cannot validate versions: setup-mac-mini.sh not found"
        exit 1
    fi

    # Map detected versions to local variables for validation
    xcode_version="$DETECTED_XCODE_VERSION"
    node_version="$DETECTED_NODE_VERSION"
    ruby_version="$DETECTED_RUBY_VERSION"
    java_version="$DETECTED_JAVA_VERSION"
    android_sdk_installed="$DETECTED_ANDROID_SDK_VERSION"
    android_build_tools_installed="$DETECTED_ANDROID_BUILD_TOOLS_VERSION"
    android_ndk_version="$DETECTED_ANDROID_NDK_VERSION"
else
    # Detect versions directly on Linux
    xcode_version="Not Installed"

    # Node.js
    if command -v node >/dev/null 2>&1; then
        node_version=$(node -v 2>/dev/null | sed 's/v//g' || echo "Not Installed")
    else
        node_version="Not Installed"
    fi

    # Ruby
    if command -v ruby >/dev/null 2>&1; then
        ruby_version=$(ruby -v 2>/dev/null | awk '{print $2}' || echo "Not Installed")
    else
        ruby_version="Not Installed"
    fi

    # Java
    if command -v java >/dev/null 2>&1; then
        java_version=$(java -version 2>&1 | head -n1 | awk -F'"' '{print $2}' || echo "Not Installed")
    else
        java_version="Not Installed"
    fi

    # Android SDK
    if command -v sdkmanager >/dev/null 2>&1; then
        android_sdk_installed=$(sdkmanager --list_installed 2>/dev/null | grep "platforms;android-" | awk -F';' '{print $2}' | sed 's/^android-//' | awk '{print $1}' | tr -d ' ')
        android_build_tools_installed=$(sdkmanager --list_installed 2>/dev/null | grep "build-tools;" | awk -F';' '{print $2}' | awk '{print $1}' | tr -d ' ')
        android_sdk_installed=${android_sdk_installed:-"Not Installed"}
        android_build_tools_installed=${android_build_tools_installed:-"Not Installed"}

        # NDK version detection
        if [ -n "${EXPECTED_ANDROID_NDK_VERSION:-}" ]; then
            if sdkmanager --list 2>/dev/null | grep -q "ndk;${EXPECTED_ANDROID_NDK_VERSION}"; then
                android_ndk_version="$EXPECTED_ANDROID_NDK_VERSION"
            else
                android_ndk_version="Not Installed"
            fi
        else
            android_ndk_version="Not Installed"
        fi
    else
        android_sdk_installed="Not Installed"
        android_build_tools_installed="Not Installed"
        android_ndk_version="Not Installed"
    fi
fi

expected_java_version_no_suffix="${EXPECTED_JAVA_VERSION%%-*}"

# Check versions and report mismatches
mismatches=()

if [ "$os" = "$OS_MAC" ] && [ "${xcode_version:-}" != "$EXPECTED_XCODE_VERSION" ]; then
    mismatches+=("Xcode: detected $xcode_version, expected $EXPECTED_XCODE_VERSION")
fi

if [ "$os" = "$OS_LINUX" ]; then
    if [ "${android_sdk_installed:-}" != "$EXPECTED_ANDROID_SDK_VERSION" ]; then
        mismatches+=("Android SDK: detected $android_sdk_installed, expected $EXPECTED_ANDROID_SDK_VERSION")
    fi
    if [ "${android_build_tools_installed:-}" != "$EXPECTED_ANDROID_BUILD_TOOLS_VERSION" ]; then
        mismatches+=("Android Build Tools: detected $android_build_tools_installed, expected $EXPECTED_ANDROID_BUILD_TOOLS_VERSION")
    fi
    if [ "${android_ndk_version:-}" != "$EXPECTED_ANDROID_NDK_VERSION" ]; then
        mismatches+=("Android NDK: detected $android_ndk_version, expected $EXPECTED_ANDROID_NDK_VERSION")
    fi
fi

if [ "$node_version" != "$EXPECTED_NODE_VERSION" ]; then
    mismatches+=("Node.js: detected $node_version, expected $EXPECTED_NODE_VERSION")
fi

if [ "$ruby_version" != "$EXPECTED_RUBY_VERSION" ]; then
    mismatches+=("Ruby: detected $ruby_version, expected $EXPECTED_RUBY_VERSION")
fi

if [ "$java_version" != "$expected_java_version_no_suffix" ]; then
    mismatches+=("Java: detected $java_version, expected $expected_java_version_no_suffix")
fi

if [ ${#mismatches[@]} -gt 0 ]; then
    echo "❌ Environment version mismatch. Aborting build - not safe to proceed."
    echo ""
    echo "Mismatched versions:"
    for mismatch in "${mismatches[@]}"; do
        echo "  • $mismatch"
    done
    exit 1
fi

echo "✅ Environment versions correct."
echo ""

# ===================================================
# BUILD STEPS
# ===================================================

echo ""
echo "⚙️  Running your build steps..."

bundlePath="bundle"
if [ ! -z "${BUNDLE_PATH:-}" ]; then
    bundlePath=$BUNDLE_PATH
fi

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

NODE_MODULES_BIN="$(pwd)/node_modules/.bin"
export PATH=$NODE_MODULES_BIN:$PATH

echo "Executing bundleVersion script"
BUNDLE_VERSION_STDERR_FILE=$(mktemp)
BUNDLE_VERSION_OUTPUT=$(./scripts/bundleVersion.sh 2>"$BUNDLE_VERSION_STDERR_FILE")
BUNDLE_VERSION_EXIT_CODE=$?

if [ $BUNDLE_VERSION_EXIT_CODE -ne 0 ]; then
  echo "❌ bundleVersion script failed with exit code $BUNDLE_VERSION_EXIT_CODE"
  echo "Script stdout:"
  echo "$BUNDLE_VERSION_OUTPUT"
  echo "Script stderr:"
  cat "$BUNDLE_VERSION_STDERR_FILE"
  rm -f "$BUNDLE_VERSION_STDERR_FILE"
  exit 1
fi

# Show any stderr warnings (non-fatal)
if [ -s "$BUNDLE_VERSION_STDERR_FILE" ]; then
  echo "⚠️  bundleVersion script produced warnings on stderr:"
  cat "$BUNDLE_VERSION_STDERR_FILE"
fi
rm -f "$BUNDLE_VERSION_STDERR_FILE"

export BUNDLE_VERSION_NAME="$BUNDLE_VERSION_OUTPUT"
echo "BUNDLE_VERSION_NAME: $BUNDLE_VERSION_NAME"

if [ -z "$BUNDLE_VERSION_NAME" ]; then
  echo "❌ BUNDLE_VERSION_NAME is empty. Git may not be configured properly."
  exit 1
fi

platform=""
target=""
if [[ $PLATFORM == "android" ]]; then
    platform="android"
    target=""
elif [[ $PLATFORM == "ios" ]]; then
    platform="ios"
    target="device"
elif [[ $PLATFORM == "iosSimulator" ]]; then
    platform="ios"
    target="simulator"
else
    echo "Unknown argument $PLATFORM"
    exit 1
fi

echo "Executing clean script"
bash -l ./scripts/clean.sh || { echo "❌ Clean script failed"; exit 1; }

echo "Executing reset script"
bash -l ./scripts/reset.sh || { echo "❌ Reset script failed"; exit 1; }

echo "Executing setup script"
bash -l ./scripts/setup.sh || { echo "❌ Setup script failed"; exit 1; }

echo "Executing preinstall script"
bash -l ./scripts/preinstall.sh || { echo "❌ Preinstall script failed"; exit 1; }

echo "Running yarn install"
yarn install || { echo "❌ Yarn install failed"; exit 1; }

echo "Executing postinstall script"
bash -l ./scripts/postinstall.sh || { echo "❌ Postinstall script failed"; exit 1; }

echo "Executing yarnInstallSharp script"
bash -l ./scripts/yarnInstallSharp.sh || { echo "❌ YarnInstallSharp script failed"; exit 1; }

set +u
echo "Executing fastlane deploy_binary"
echo "bundlePath: $bundlePath"
echo "target: $target"
echo "platform: $platform"
echo "Current directory: $(pwd)"
ls -la
cd "$platform"

# @NOTE: If mise is available, it manages Node.js, Ruby, Java, and Yarn versions automatically.
# Ruby version will auto-activate from .ruby-version file in platform directory
# (mise detects it via automatic directory-based version switching).
# In Docker environments without mise, system-installed tools are used directly.

bash -l -c "$bundlePath exec fastlane deploy_binary target:$target --verbose" || { echo "❌ Fastlane failed"; exit 1; }
set -u

echo "✅ Build complete!"

