#!/bin/bash

# Interactive GitHub User Removal Script
# Removes a specified user from all repositories matching a prefix pattern
# under a given username or organization with interactive prompts

set -euo pipefail

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

# Global variables
GITHUB_TOKEN=""
ROOT_USER=""
USER_TO_REMOVE=""
REPO_PREFIX=""
DRY_RUN=false
VERBOSE=false

# Statistics
TOTAL_REPOS_FOUND=0
MATCHING_REPOS=0
COLLABORATOR_REPOS=0
SUCCESSFUL_REMOVALS=0
FAILED_REMOVALS=0
ALREADY_REMOVED=0

# Utility functions
log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

log_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

log_error() {
    echo -e "${RED}❌ $1${NC}"
}

log_verbose() {
    if [[ "$VERBOSE" == "true" ]]; then
        echo -e "${CYAN}🔍 $1${NC}"
    fi
}

log_header() {
    echo -e "\n${BOLD}${PURPLE}$1${NC}"
    echo -e "${PURPLE}$(printf '=%.0s' {1..60})${NC}"
}

show_welcome() {
    clear
    cat << 'EOF'
  ╔══════════════════════════════════════════════════════════╗
  ║                                                          ║
  ║           🚀 GitHub User Removal Tool 🚀                ║
  ║                                                          ║
  ║     Remove users from repositories with ease!           ║
  ║                                                          ║
  ╚══════════════════════════════════════════════════════════╝
EOF
    echo ""
    log_info "Welcome to the Interactive GitHub User Removal Script!"
    echo ""
}

prompt_github_token() {
    log_header "🔑 GitHub Authentication"
    
    echo -e "${YELLOW}Please provide your GitHub Personal Access Token:${NC}"
    echo -e "${CYAN}💡 The token should have 'repo' and 'admin:org' permissions${NC}"
    echo -e "${CYAN}💡 You can create one at: https://github.com/settings/tokens${NC}"
    echo ""
    
    while true; do
        echo -e -n "${BLUE}🔐 Enter your GitHub token: ${NC}"
        read -s -r GITHUB_TOKEN < /dev/tty
        echo ""
        
        if [[ -z "$GITHUB_TOKEN" ]]; then
            log_error "Token cannot be empty. Please try again."
            echo ""
            continue
        fi
        
        # Validate token
        log_info "Validating token..."
        local response
        response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" 2>/dev/null)
        
        local login
        login=$(echo "$response" | jq -r '.login // empty' 2>/dev/null)
        
        if [[ -z "$login" ]]; then
            log_error "Invalid or expired GitHub token. Please try again."
            echo ""
            continue
        fi
        
        log_success "Token validated successfully! (Authenticated as: $login)"
        echo ""
        break
    done
}

prompt_root_user() {
    log_header "👤 Target Organization/User"
    
    echo -e "${YELLOW}Enter the GitHub username or organization name:${NC}"
    echo -e "${CYAN}💡 This is where we'll look for repositories${NC}"
    echo -e "${CYAN}💡 Examples: 'mycompany', 'john-doe', 'my-organization'${NC}"
    echo ""
    
    while true; do
        echo -e -n "${BLUE}🏢 Organization/Username: ${NC}"
        read -r ROOT_USER < /dev/tty
        
        if [[ -z "$ROOT_USER" ]]; then
            log_error "Username/organization cannot be empty. Please try again."
            echo ""
            continue
        fi
        
        # Validate username format
        if [[ ! "$ROOT_USER" =~ ^[a-zA-Z0-9._-]+$ ]]; then
            log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens."
            echo ""
            continue
        fi
        
        log_success "Target set to: $ROOT_USER"
        echo ""
        break
    done
}

prompt_user_to_remove() {
    log_header "🎯 User to Remove"
    
    echo -e "${YELLOW}Enter the username you want to remove from repositories:${NC}"
    echo -e "${CYAN}💡 This user will be removed as a collaborator from matching repositories${NC}"
    echo -e "${CYAN}💡 They will lose access to private repositories (if applicable)${NC}"
    echo ""
    
    while true; do
        echo -e -n "${BLUE}👤 Username to remove: ${NC}"
        read -r USER_TO_REMOVE < /dev/tty
        
        if [[ -z "$USER_TO_REMOVE" ]]; then
            log_error "Username cannot be empty. Please try again."
            echo ""
            continue
        fi
        
        # Validate username format
        if [[ ! "$USER_TO_REMOVE" =~ ^[a-zA-Z0-9._-]+$ ]]; then
            log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens."
            echo ""
            continue
        fi
        
        # Confirmation prompt
        echo ""
        echo -e "${YELLOW}⚠️  You are about to remove user '${BOLD}$USER_TO_REMOVE${NC}${YELLOW}' from repositories${NC}"
        echo -e -n "${BLUE}Are you sure this is correct? (yes/no): ${NC}"
        read -r confirm < /dev/tty
        
        if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then
            log_success "User to remove set to: $USER_TO_REMOVE"
            echo ""
            break
        else
            echo -e "${YELLOW}Let's try again...${NC}"
            echo ""
        fi
    done
}

prompt_repo_prefix() {
    log_header "📁 Repository Filter"
    
    echo -e "${YELLOW}Enter a repository name pattern to filter repositories:${NC}"
    echo -e "${CYAN}💡 Pattern examples:${NC}"
    echo -e "${CYAN}   • '*' - All repositories${NC}"
    echo -e "${CYAN}   • 'myproject-' - Repos starting with 'myproject-'${NC}"
    echo -e "${CYAN}   • '*api*' - Repos containing 'api'${NC}"
    echo -e "${CYAN}   • 'web-app' - Repos starting with 'web-app'${NC}"
    echo ""
    
    while true; do
        echo -e -n "${BLUE}🔍 Repository pattern: ${NC}"
        read -r REPO_PREFIX < /dev/tty
        
        if [[ -z "$REPO_PREFIX" ]]; then
            log_error "Pattern cannot be empty. Please try again."
            echo ""
            continue
        fi
        
        # Show what this pattern will match
        echo ""
        case "$REPO_PREFIX" in
            "*")
                log_info "This will match ALL repositories under $ROOT_USER"
                ;;
            *"*"*)
                log_info "This will match repositories containing: ${REPO_PREFIX//\*/[text]}"
                ;;
            *)
                log_info "This will match repositories starting with: $REPO_PREFIX"
                ;;
        esac
        
        echo ""
        echo -e -n "${BLUE}Is this pattern correct? (yes/no): ${NC}"
        read -r confirm < /dev/tty
        
        if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then
            log_success "Repository pattern set to: $REPO_PREFIX"
            echo ""
            break
        fi
    done
}

prompt_options() {
    log_header "⚙️  Operation Options"
    
    echo -e "${YELLOW}Choose your operation mode:${NC}"
    echo ""
    echo -e "${CYAN}1) 🔍 Dry Run - Preview what would be done (Recommended)${NC}"
    echo -e "${CYAN}2) 🚀 Execute - Perform the actual removal${NC}"
    echo ""
    
    while true; do
        echo -e -n "${BLUE}Select option (1 or 2): ${NC}"
        read -r option < /dev/tty
        
        case "$option" in
            1)
                DRY_RUN=true
                log_info "Dry run mode selected - no changes will be made"
                break
                ;;
            2)
                DRY_RUN=false
                echo ""
                echo -e "${YELLOW}⚠️  WARNING: This will make actual changes to repositories!${NC}"
                echo -e -n "${BLUE}Are you absolutely sure? Type 'YES' to confirm: ${NC}"
                read -r final_confirm < /dev/tty
                
                if [[ "$final_confirm" == "YES" ]]; then
                    log_info "Execute mode selected - changes will be made"
                    break
                else
                    log_info "Switching to dry run mode for safety"
                    DRY_RUN=true
                    break
                fi
                ;;
            *)
                log_error "Please enter 1 or 2"
                ;;
        esac
    done
    
    echo ""
    echo -e -n "${BLUE}Enable verbose logging? (y/n): ${NC}"
    read -r verbose_choice < /dev/tty
    
    if [[ "$verbose_choice" =~ ^[Yy]$ ]]; then
        VERBOSE=true
        log_info "Verbose logging enabled"
    else
        VERBOSE=false
        log_info "Standard logging enabled"
    fi
    echo ""
}

show_summary() {
    log_header "📋 Operation Summary"
    
    echo -e "${BOLD}Configuration:${NC}"
    echo -e "  🏢 Organization/User: ${CYAN}$ROOT_USER${NC}"
    echo -e "  👤 User to remove: ${CYAN}$USER_TO_REMOVE${NC}"
    echo -e "  🔍 Repository pattern: ${CYAN}$REPO_PREFIX${NC}"
    echo -e "  ⚙️  Mode: ${CYAN}$([ "$DRY_RUN" = true ] && echo "Dry Run" || echo "Execute")${NC}"
    echo -e "  📝 Logging: ${CYAN}$([ "$VERBOSE" = true ] && echo "Verbose" || echo "Standard")${NC}"
    echo ""
    
    echo -e -n "${BLUE}Ready to proceed? (yes/no): ${NC}"
    read -r proceed < /dev/tty
    
    if [[ ! "$proceed" =~ ^[Yy]([Ee][Ss])?$ ]]; then
        log_warning "Operation cancelled by user"
        exit 0
    fi
}

# Fetch all repositories for a user or organization
fetch_all_repos() {
    local owner="$1"
    local all_repos=()
    local page=1
    
    log_verbose "Fetching repositories for: $owner"
    
    while true; do
        local response
        response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
            "https://api.github.com/users/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null)
        
        # Check if response is valid JSON
        if ! echo "$response" | jq empty 2>/dev/null; then
            log_warning "Invalid response from GitHub API for page $page"
            break
        fi
        
        # Check for errors
        local error_message
        error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null)
        if [[ -n "$error_message" ]]; then
            if [[ "$error_message" == "Not Found" ]]; then
                # Try as organization
                log_verbose "User not found, trying as organization..."
                response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
                    "https://api.github.com/orgs/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null)
                
                if ! echo "$response" | jq empty 2>/dev/null; then
                    log_error "Could not fetch repositories for '$owner' (not found as user or organization)"
                    exit 1
                fi
            else
                log_error "GitHub API error: $error_message"
                exit 1
            fi
        fi
        
        local repos
        repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null)
        
        if [[ -z "$repos" ]]; then
            break
        fi
        
        while IFS= read -r repo; do
            if [[ -n "$repo" && "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then
                all_repos+=("$repo")
                log_verbose "Found repository: $repo"
            fi
        done <<< "$repos"
        
        ((page++))
    done
    
    TOTAL_REPOS_FOUND=${#all_repos[@]}
    if [[ ${#all_repos[@]} -gt 0 ]]; then
        printf '%s\n' "${all_repos[@]}"
    fi
}

# Check if repository name matches prefix pattern
matches_prefix() {
    local repo_full_name="$1"
    local pattern="$2"
    local repo_name
    repo_name=$(basename "$repo_full_name")
    
    # Convert shell wildcard pattern to bash pattern
    case "$pattern" in
        "*")
            return 0  # Match all
            ;;
        *"*"*)
            # Pattern contains wildcards
            if [[ "$repo_name" == $pattern ]]; then
                return 0
            fi
            ;;
        *)
            # Simple prefix match
            if [[ "$repo_name" == "$pattern"* ]]; then
                return 0
            fi
            ;;
    esac
    
    return 1
}

# Check if user is a collaborator on a repository
is_collaborator() {
    local repo="$1"
    local user="$2"
    
    local response
    response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \
        "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null)
    
    local http_code="${response: -3}"
    
    case "$http_code" in
        204)
            return 0  # User is a collaborator
            ;;
        404)
            return 1  # User is not a collaborator
            ;;
        403)
            log_verbose "Access forbidden for $repo (insufficient permissions)"
            return 1
            ;;
        *)
            log_verbose "Failed to check collaboration status for $user on $repo (HTTP: $http_code)"
            return 1
            ;;
    esac
}

# Remove user from repository
remove_user_from_repo() {
    local repo="$1"
    local user="$2"
    
    if [[ "$DRY_RUN" == "true" ]]; then
        log_info "[DRY RUN] Would remove $user from $repo"
        return 0
    fi
    
    log_verbose "Removing $user from $repo..."
    
    local response
    response=$(curl -s -w "%{http_code}" -X DELETE \
        -H "Authorization: token $GITHUB_TOKEN" \
        "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null)
    
    local http_code="${response: -3}"
    
    case "$http_code" in
        204)
            log_success "Successfully removed $user from $repo"
            ((SUCCESSFUL_REMOVALS++))
            return 0
            ;;
        404)
            log_info "User $user was not a collaborator on $repo (already removed)"
            ((ALREADY_REMOVED++))
            return 0
            ;;
        *)
            log_error "Failed to remove $user from $repo (HTTP: $http_code)"
            ((FAILED_REMOVALS++))
            return 1
            ;;
    esac
}

# Show final results
show_final_summary() {
    log_header "🎉 Operation Complete"
    
    echo -e "${BOLD}📊 Statistics:${NC}"
    echo -e "  📁 Repositories scanned: ${CYAN}$TOTAL_REPOS_FOUND${NC}"
    echo -e "  🔍 Repositories matching pattern: ${CYAN}$MATCHING_REPOS${NC}"
    echo -e "  👤 Repositories where user was collaborator: ${CYAN}$COLLABORATOR_REPOS${NC}"
    echo ""
    echo -e "  ${GREEN}✅ Successful removals: $SUCCESSFUL_REMOVALS${NC}"
    echo -e "  ${YELLOW}ℹ️  Already removed: $ALREADY_REMOVED${NC}"
    echo -e "  ${RED}❌ Failed removals: $FAILED_REMOVALS${NC}"
    
    if [[ $((SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS)) -gt 0 ]]; then
        local success_rate=$((((SUCCESSFUL_REMOVALS + ALREADY_REMOVED) * 100) / (SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS)))
        echo -e "  📈 Success rate: ${CYAN}${success_rate}%${NC}"
    fi
    
    echo ""
    
    if [[ "$DRY_RUN" == "true" ]]; then
        log_warning "This was a dry run - no actual changes were made"
        echo -e "${BLUE}💡 To perform the actual removal, run the script again and select 'Execute' mode${NC}"
    else
        if [[ $FAILED_REMOVALS -gt 0 ]]; then
            log_warning "Some operations failed. Check the logs above for details."
        else
            log_success "All operations completed successfully!"
        fi
    fi
    
    echo ""
    echo -e "${CYAN}🙏 Thank you for using the GitHub User Removal Tool!${NC}"
}

# Main execution function
main() {
    # Show welcome screen
    show_welcome
    
    # Interactive prompts
    prompt_github_token
    prompt_root_user
    prompt_user_to_remove
    prompt_repo_prefix
    prompt_options
    
    # Show summary and confirm
    show_summary
    
    # Start processing
    log_header "🚀 Processing Repositories"
    
    # Fetch all repositories
    log_info "Discovering repositories for $ROOT_USER..."
    local repos_output
    repos_output=$(fetch_all_repos "$ROOT_USER")
    
    if [[ -z "$repos_output" ]]; then
        log_warning "No repositories found for '$ROOT_USER'"
        exit 0
    fi
    
    log_success "Found $TOTAL_REPOS_FOUND repositories"
    
    # Filter repositories by prefix
    log_info "Filtering repositories by pattern '$REPO_PREFIX'..."
    local matching_repos=()
    
    while IFS= read -r repo; do
        if [[ -n "$repo" ]] && matches_prefix "$repo" "$REPO_PREFIX"; then
            matching_repos+=("$repo")
            log_verbose "Matched: $repo"
        fi
    done <<< "$repos_output"
    
    MATCHING_REPOS=${#matching_repos[@]}
    
    if [[ $MATCHING_REPOS -eq 0 ]]; then
        log_warning "No repositories match the pattern '$REPO_PREFIX'"
        echo ""
        log_info "Available repositories:"
        while IFS= read -r repo; do
            log_info "  • $(basename "$repo")"
        done <<< "$repos_output"
        exit 0
    fi
    
    log_success "Found $MATCHING_REPOS repositories matching pattern '$REPO_PREFIX'"
    
    # Check collaborator status and remove
    log_info "Processing repositories..."
    echo ""
    
    local current=0
    for repo in "${matching_repos[@]}"; do
        ((current++))
        printf "\r${CYAN}Progress: [%3d%%] %d/%d repositories processed${NC}" \
            $((current * 100 / MATCHING_REPOS)) "$current" "$MATCHING_REPOS"
        
        if is_collaborator "$repo" "$USER_TO_REMOVE"; then
            ((COLLABORATOR_REPOS++))
            echo # New line after progress
            remove_user_from_repo "$repo" "$USER_TO_REMOVE"
        fi
    done
    
    echo # New line after progress
    
    # Show final summary
    show_final_summary
    
    if [[ $FAILED_REMOVALS -gt 0 ]]; then
        exit 1
    else
        exit 0
    fi
}

# Script execution
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi