#!/bin/sh
# Pre-commit hook: runs linters, formatters, and tests on staged files

# Get staged files
STAGED_GO_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$' || true)
STAGED_FRONTEND_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^frontend/.*\.(js|jsx|ts|tsx|vue|mjs|cjs)$' || true)
STAGED_FRONTEND_SOURCE_FILES=$(printf '%s\n' "$STAGED_FRONTEND_FILES" | grep -v '^frontend/bindings/' || true)
STAGED_BINDING_TRIGGER_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '^(app_service\.go|main\.go|internal/.*\.go)$' | grep -v '_test\.go$' || true)
BINDINGS_REFRESHED=0
RUN_FRONTEND_PROJECT_CHECKS=0

if [ -n "$STAGED_BINDING_TRIGGER_FILES" ]; then
    echo "Refreshing committed Wails bindings..."
    if ! sh scripts/sync-wails-bindings.sh --stage; then
        echo ""
        echo "Failed to refresh Wails bindings."
        exit 1
    fi
    BINDINGS_REFRESHED=1
    RUN_FRONTEND_PROJECT_CHECKS=1
fi

# --- Go linting ---
if [ -n "$STAGED_GO_FILES" ]; then
    # Check if golangci-lint is installed
    if ! command -v golangci-lint &> /dev/null; then
        echo "Error: golangci-lint is not installed"
        echo "Install with: brew install golangci-lint"
        exit 1
    fi

    echo "Running golangci-lint --fix..."

    # Run lint-fix
    make lint-fix

    # Re-add any fixed files that were staged
    for file in $STAGED_GO_FILES; do
        if [ -f "$file" ]; then
            git add "$file"
        fi
    done

    # Run lint to check for remaining issues
    if ! golangci-lint run ./...; then
        echo ""
        echo "Go linting failed. Please fix the issues above."
        exit 1
    fi

    echo "Go linting passed."

    # Run Go tests
    echo "Running Go tests..."
    if ! go test ./...; then
        echo ""
        echo "Go tests failed. Please fix the issues above."
        exit 1
    fi

    echo "Go tests passed."
fi

# --- Frontend formatting & linting ---
if [ -n "$STAGED_FRONTEND_SOURCE_FILES" ]; then
    # Strip 'frontend/' prefix for paths since we cd into frontend
    FRONTEND_FILES=$(echo "$STAGED_FRONTEND_SOURCE_FILES" | sed 's|^frontend/||')

    # Format with oxfmt
    echo "Running oxfmt on frontend files..."
    cd frontend && pnpm oxfmt --write $FRONTEND_FILES
    cd ..

    # Re-add formatted files
    for file in $STAGED_FRONTEND_SOURCE_FILES; do
        if [ -f "$file" ]; then
            git add "$file"
        fi
    done

    # Lint with oxlint
    echo "Running oxlint --fix on frontend files..."
    cd frontend && pnpm oxlint --fix $FRONTEND_FILES
    OXLINT_EXIT=$?
    cd ..

    # Re-add any fixed files that were staged
    for file in $STAGED_FRONTEND_SOURCE_FILES; do
        if [ -f "$file" ]; then
            git add "$file"
        fi
    done

    # Check if oxlint found unfixable issues
    if [ $OXLINT_EXIT -ne 0 ]; then
        echo ""
        echo "Frontend linting failed. Please fix the issues above."
        exit 1
    fi

    echo "Frontend formatting & linting passed."
    RUN_FRONTEND_PROJECT_CHECKS=1
fi

if [ "$RUN_FRONTEND_PROJECT_CHECKS" -eq 1 ]; then
    # Run TypeScript type check
    echo "Running TypeScript check..."
    cd frontend && pnpm vue-tsc --noEmit
    TSC_EXIT=$?
    cd ..

    if [ $TSC_EXIT -ne 0 ]; then
        echo ""
        echo "TypeScript check failed. Please fix the type errors above."
        exit 1
    fi

    echo "TypeScript check passed."

    # Run frontend tests
    echo "Running frontend tests..."
    cd frontend && pnpm run test:run
    VITEST_EXIT=$?
    cd ..

    if [ $VITEST_EXIT -ne 0 ]; then
        echo ""
        echo "Frontend tests failed. Please fix the issues above."
        exit 1
    fi

    echo "Frontend tests passed."
fi
