#!/bin/bash
# ClaudeTools Bidirectional Sync Script
# Ensures proper pull BEFORE push on all machines
# Prints incoming/outgoing change summary with author attribution

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

# Machine + timestamp
if [ -n "$COMPUTERNAME" ]; then
    MACHINE="$COMPUTERNAME"
else
    MACHINE=$(hostname)
fi
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")

echo -e "${GREEN}[OK]${NC} Starting ClaudeTools sync from $MACHINE at $TIMESTAMP"

# Navigate to ClaudeTools directory (check common locations)
for candidate in "$HOME/ClaudeTools" "/d/ClaudeTools" "D:/ClaudeTools" "/d/claudetools" "D:/claudetools"; do
    if [ -d "$candidate" ]; then
        cd "$candidate"
        break
    fi
done

if [ ! -d ".git" ]; then
    echo -e "${RED}[ERROR]${NC} Not in a git working tree"
    exit 1
fi

echo -e "${GREEN}[OK]${NC} Working directory: $(pwd)"

# Detect Python interpreter — verify it actually runs (Windows Store stub passes command -v but fails to execute)
PYTHON=""
for candidate in py python3 python; do
    if command -v "$candidate" >/dev/null 2>&1; then
        if "$candidate" -c "import sys; sys.exit(0)" >/dev/null 2>&1; then
            PYTHON="$candidate"
            break
        fi
    fi
done
if [ -z "$PYTHON" ]; then
    echo -e "${RED}[ERROR]${NC} No Python interpreter found (tried: py, python3, python)"
    exit 1
fi

# Load user identity
USER_DISPLAY="unknown"
USER_GITEA=""
if [ -f ".claude/identity.json" ]; then
    USER_DISPLAY=$($PYTHON -c "import json,sys; d=json.load(open('.claude/identity.json')); print(d.get('full_name', d.get('user','unknown')))" 2>/dev/null || echo "unknown")
    USER_GITEA=$($PYTHON -c "import json,sys; d=json.load(open('.claude/identity.json')); print(d.get('user',''))" 2>/dev/null || echo "")
fi
echo -e "${GREEN}[OK]${NC} Syncing as: $USER_DISPLAY (machine: $MACHINE)"

# Phase 1: Local changes
echo ""
echo "=== Phase 1: Local changes ==="

if ! git diff-index --quiet HEAD -- 2>/dev/null; then
    echo -e "${YELLOW}[INFO]${NC} Local changes detected:"
    git status --short
    echo ""

    echo -e "${GREEN}[OK]${NC} Staging all changes..."
    git add -A

    # Commit message (Co-Authored-By uses local git user if configured)
    COMMIT_MSG="sync: auto-sync from $MACHINE at $TIMESTAMP

Author: $USER_DISPLAY
Machine: $MACHINE
Timestamp: $TIMESTAMP"

    if git diff-index --quiet --cached HEAD -- 2>/dev/null; then
        echo -e "${GREEN}[OK]${NC} No stageable changes (submodule internal changes skipped)."
    else
        git commit -m "$COMMIT_MSG"
        echo -e "${GREEN}[OK]${NC} Committed."
    fi
else
    echo -e "${GREEN}[OK]${NC} No local changes to commit."
fi

# Phase 2: Remote sync
echo ""
echo "=== Phase 2: Fetch + inspect ==="

LOCAL_BEFORE=$(git rev-parse HEAD)

echo -e "${GREEN}[OK]${NC} Fetching from origin..."
git fetch origin --quiet

LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse origin/main 2>/dev/null || git rev-parse origin/master 2>/dev/null || echo "$LOCAL")
REMOTE_BRANCH="origin/main"
if ! git rev-parse origin/main >/dev/null 2>&1; then
    REMOTE_BRANCH="origin/master"
fi

# Count and show incoming
INCOMING_COUNT=$(git rev-list --count HEAD..$REMOTE_BRANCH 2>/dev/null || echo 0)
OUTGOING_COUNT=$(git rev-list --count $REMOTE_BRANCH..HEAD 2>/dev/null || echo 0)

if [ "$INCOMING_COUNT" -gt 0 ]; then
    echo ""
    echo -e "${CYAN}--- Incoming: $INCOMING_COUNT commits from remote ---${NC}"
    git log --oneline --format='  %C(yellow)%h%Creset  %C(cyan)%an%Creset  %s  %C(dim)(%ar)%Creset' HEAD..$REMOTE_BRANCH | head -30
    echo ""
    echo -e "${CYAN}--- Files touched by incoming commits ---${NC}"
    git diff --stat HEAD..$REMOTE_BRANCH | tail -20
else
    echo -e "${GREEN}[OK]${NC} No incoming changes."
fi

if [ "$OUTGOING_COUNT" -gt 0 ]; then
    echo ""
    echo -e "${CYAN}--- Outgoing: $OUTGOING_COUNT commits to remote ---${NC}"
    git log --oneline --format='  %C(yellow)%h%Creset  %C(cyan)%an%Creset  %s  %C(dim)(%ar)%Creset' $REMOTE_BRANCH..HEAD | head -30
fi

# Phase 3: Pull (if needed)
if [ "$INCOMING_COUNT" -gt 0 ]; then
    echo ""
    echo "=== Phase 3: Pull (rebase) ==="
    if git pull origin main --rebase; then
        echo -e "${GREEN}[OK]${NC} Pulled successfully."
    else
        echo -e "${RED}[ERROR]${NC} Pull failed (likely conflicts). Resolve and re-run sync."
        exit 1
    fi
fi

# Phase 4: Push (if needed)
OUTGOING_AFTER_PULL=$(git rev-list --count $REMOTE_BRANCH..HEAD 2>/dev/null || echo 0)
if [ "$OUTGOING_AFTER_PULL" -gt 0 ]; then
    echo ""
    echo "=== Phase 4: Push ==="
    if git push origin main; then
        echo -e "${GREEN}[OK]${NC} Pushed successfully."
    else
        echo -e "${RED}[ERROR]${NC} Push failed. Check auth / network."
        exit 1
    fi
else
    echo -e "${GREEN}[OK]${NC} Nothing to push."
fi

# Phase 5: Scan pulled session logs for cross-user messages
# Look for "## Note for" or "## Message for" sections in any session log
# touched by incoming commits. Print them prominently so they aren't missed.
if [ "$INCOMING_COUNT" -gt 0 ] && [ -n "$LOCAL_BEFORE" ]; then
    CHANGED_LOGS=$(git diff --name-only "$LOCAL_BEFORE"..HEAD -- '**/session-logs/*.md' 'session-logs/*.md' 2>/dev/null || true)
    if [ -n "$CHANGED_LOGS" ]; then
        NOTES_FOUND=0
        for LOG_FILE in $CHANGED_LOGS; do
            if [ -f "$LOG_FILE" ]; then
                # Extract author from "## User" block and any "## Note for" / "## Message for" sections
                NOTE_CONTENT=$(awk '
                    /^## (Note|Message) for /{ in_note=1; header=$0; next }
                    in_note && /^## /{ in_note=0 }
                    in_note{ buf=buf"\n"$0 }
                    END{ if(buf) print header buf }
                ' "$LOG_FILE")
                if [ -n "$NOTE_CONTENT" ]; then
                    if [ "$NOTES_FOUND" -eq 0 ]; then
                        echo ""
                        echo -e "${YELLOW}============================================================${NC}"
                        echo -e "${YELLOW}  MESSAGES FROM OTHER TEAM MEMBERS${NC}"
                        echo -e "${YELLOW}============================================================${NC}"
                        NOTES_FOUND=1
                    fi
                    LOG_AUTHOR=$(awk '/^- \*\*User:\*\*/{print; exit}' "$LOG_FILE" | sed 's/.*\*\*User:\*\* //')
                    LOG_DATE=$(basename "$LOG_FILE" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
                    echo ""
                    echo -e "${YELLOW}  From: ${LOG_AUTHOR:-unknown}  |  ${LOG_DATE:-unknown date}  |  ${LOG_FILE}${NC}"
                    echo -e "${YELLOW}------------------------------------------------------------${NC}"
                    echo "$NOTE_CONTENT"
                fi
            fi
        done
        if [ "$NOTES_FOUND" -gt 0 ]; then
            echo ""
            echo -e "${YELLOW}============================================================${NC}"
            echo -e "${YELLOW}  Address the above before continuing with other work.${NC}"
            echo -e "${YELLOW}============================================================${NC}"
            echo ""
        fi
    fi
fi

# Phase 6: Vault sync
echo ""
echo "=== Phase 6: Vault sync ==="

VAULT_PATH=""
if [ -f ".claude/identity.json" ]; then
    VAULT_PATH=$($PYTHON -c "import json; d=json.load(open('.claude/identity.json')); print(d.get('vault_path',''))" 2>/dev/null || echo "")
fi

if [ -z "$VAULT_PATH" ]; then
    echo -e "${YELLOW}[INFO]${NC} vault_path not set in identity.json — skipping vault sync."
elif [ ! -d "$VAULT_PATH/.git" ]; then
    echo -e "${YELLOW}[WARNING]${NC} Vault path '$VAULT_PATH' is not a git repo — skipping."
else
    CLAUDETOOLS_DIR=$(pwd)
    cd "$VAULT_PATH"
    echo -e "${GREEN}[OK]${NC} Vault: $VAULT_PATH"

    # Commit any local vault changes
    if ! git diff-index --quiet HEAD -- 2>/dev/null; then
        echo -e "${YELLOW}[INFO]${NC} Local vault changes detected — committing..."
        git add -A
        git commit -m "sync: auto-sync vault from $MACHINE at $TIMESTAMP"
        echo -e "${GREEN}[OK]${NC} Vault committed."
    else
        echo -e "${GREEN}[OK]${NC} No local vault changes."
    fi

    VAULT_LOCAL_BEFORE=$(git rev-parse HEAD)
    git fetch origin --quiet

    VAULT_REMOTE_BRANCH="origin/main"
    if ! git rev-parse origin/main >/dev/null 2>&1; then
        VAULT_REMOTE_BRANCH="origin/master"
    fi

    VAULT_INCOMING=$(git rev-list --count HEAD..$VAULT_REMOTE_BRANCH 2>/dev/null || echo 0)
    VAULT_OUTGOING=$(git rev-list --count $VAULT_REMOTE_BRANCH..HEAD 2>/dev/null || echo 0)

    if [ "$VAULT_INCOMING" -gt 0 ]; then
        echo -e "${CYAN}--- Vault: $VAULT_INCOMING incoming commit(s) ---${NC}"
        git log --oneline --format='  %C(yellow)%h%Creset  %C(cyan)%an%Creset  %s  %C(dim)(%ar)%Creset' HEAD..$VAULT_REMOTE_BRANCH | head -10
        if git pull origin main --rebase; then
            echo -e "${GREEN}[OK]${NC} Vault pulled."
        else
            echo -e "${RED}[ERROR]${NC} Vault pull failed — resolve conflicts manually in $VAULT_PATH."
        fi
    else
        echo -e "${GREEN}[OK]${NC} Vault: no incoming changes."
    fi

    VAULT_OUTGOING_AFTER=$(git rev-list --count $VAULT_REMOTE_BRANCH..HEAD 2>/dev/null || echo 0)
    if [ "$VAULT_OUTGOING_AFTER" -gt 0 ]; then
        if git push origin main; then
            echo -e "${GREEN}[OK]${NC} Vault pushed ($VAULT_OUTGOING_AFTER commit(s))."
        else
            echo -e "${RED}[ERROR]${NC} Vault push failed."
        fi
    else
        echo -e "${GREEN}[OK]${NC} Vault: nothing to push."
    fi

    cd "$CLAUDETOOLS_DIR"
fi

# Phase 7: Summary
echo ""
echo "=== Sync Summary ==="

if [ "$INCOMING_COUNT" -gt 0 ]; then
    INCOMING_AUTHORS=$(git log --format='%an' $LOCAL_BEFORE..HEAD 2>/dev/null | sort | uniq -c | sort -rn | awk '{printf "%s (%s), ", substr($0, index($0,$2)), $1}' | sed 's/, $//')
    echo -e "${CYAN}Pulled in:${NC} $INCOMING_COUNT commit(s) — authors: ${INCOMING_AUTHORS:-unknown}"
fi
if [ "$OUTGOING_AFTER_PULL" -gt 0 ]; then
    echo -e "${CYAN}Pushed out:${NC} $OUTGOING_AFTER_PULL commit(s) by $USER_DISPLAY"
fi
if [ "$INCOMING_COUNT" -eq 0 ] && [ "$OUTGOING_AFTER_PULL" -eq 0 ]; then
    echo -e "${GREEN}Already in sync — no commits moved in either direction.${NC}"
fi

echo -e "${GREEN}[OK]${NC} HEAD: $(git log -1 --oneline)"
echo -e "${GREEN}[OK]${NC} Status: $(git status -sb | head -1)"

echo ""
echo -e "${GREEN}[SUCCESS]${NC} Sync complete."
