#!/bin/bash

# This script is used to clone a project from a remote server
# and perform full project setup including Docker, environment,
# SSH keys, and database synchronization.
# Called by sync-project.sh with --git flag.

# Get current script real directory (follow symlinks)
SCRIPT_PATH="$(realpath "$0")"
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"

# Source shared variables
source "$SCRIPT_DIR/shared.sh"

# Arguments: SERVER_HOST SSH_PASSWORD SERVER_PROJECT_PATH LOCAL_FOLDER
SERVER_HOST="$1"
SSH_PASSWORD="$2"
SERVER_PROJECT_PATH="$3"
LOCAL_FOLDER="$4"

# Validate arguments
if [ -z "$SERVER_HOST" ] || [ -z "$SSH_PASSWORD" ] || [ -z "$SERVER_PROJECT_PATH" ] || [ -z "$LOCAL_FOLDER" ]; then
	echo -e "${RED}Usage: sync-git-project.sh SERVER_HOST SSH_PASSWORD SERVER_PROJECT_PATH LOCAL_FOLDER${NC}"
	exit 1
fi

# Extract username and host from SERVER_HOST
USERNAME="${SERVER_HOST%@*}"
HOST="${SERVER_HOST#*@}"

# ============================================================
# STEP 1: Clone Fork
# ============================================================
echo -e "${BLUE}=== Step 1: Cloning Repository ===${NC}"

GIT_SSH_COMMAND="sshpass -p '${SSH_PASSWORD}' ssh $SSH_OPTS" \
	git clone ${SERVER_HOST}:${SERVER_PROJECT_PATH} "${LOCAL_FOLDER}"

if [ $? -ne 0 ]; then
	echo -e "${RED}Failed to clone repository${NC}"
	echo -e "${YELLOW}Check that:${NC}"
	echo "  - SSH credentials are correct"
	echo "  - Repository exists at ${SERVER_PROJECT_PATH}"
	echo "  - You have access to the server"
	exit 1
fi

echo -e "${GREEN}Repository cloned successfully${NC}"

# Change into project directory
cd "${LOCAL_FOLDER}"

# Check for .npmrc
if [ ! -f ".npmrc" ]; then
	pause_for_user ".npmrc file not found! Please add .npmrc file to the project root before continuing."
fi

echo -e "${GREEN}Step 1 complete${NC}"

# ============================================================
# STEP 2: Copy Docker Env File
# ============================================================
echo -e "${BLUE}=== Step 2: Copying Docker Env File ===${NC}"

if [ -f ".docker/config/.env.local" ]; then
	cp ".docker/config/.env.local" ".env"
	echo -e "${GREEN}.env copied from .docker/config/.env.local${NC}"
else
	echo -e "${RED}.docker/config/.env.local not found!${NC}"
	pause_for_user "Please ensure .docker/config/.env.local exists before continuing."

	# Re-check after user resolves
	if [ -f ".docker/config/.env.local" ]; then
		cp ".docker/config/.env.local" ".env"
		echo -e "${GREEN}.env copied from .docker/config/.env.local${NC}"
	else
		echo -e "${RED}Still no .docker/config/.env.local - continuing without it${NC}"
	fi
fi

echo -e "${GREEN}Step 2 complete${NC}"

# ============================================================
# STEP 3: Clean Docker Volumes
# ============================================================
echo -e "${BLUE}=== Step 3: Cleaning Docker Volumes ===${NC}"

echo "Stopping all containers..."
docker stop $(docker ps -aq) 2>/dev/null || true

echo "Removing all containers..."
docker rm $(docker ps -aq) 2>/dev/null || true

echo "Removing all volumes..."
docker volume rm $(docker volume ls -q) 2>/dev/null || true

echo -e "${GREEN}Docker volumes cleaned${NC}"
echo -e "${GREEN}Step 3 complete${NC}"

# ============================================================
# STEP 4: Run docker-setup.sh
# ============================================================
echo -e "${BLUE}=== Step 4: Running docker-setup.sh ===${NC}"

if [ -f "docker-setup.sh" ]; then
	echo "Running docker-setup.sh..."
	sh docker-setup.sh
	if [ $? -ne 0 ]; then
		echo -e "${YELLOW}docker-setup.sh exited with non-zero status${NC}"
		pause_for_user "Please check docker-setup.sh output and resolve any issues."
	else
		echo -e "${GREEN}docker-setup.sh completed successfully${NC}"
	fi
else
	echo -e "${YELLOW}docker-setup.sh not found in project!${NC}"
	pause_for_user "No docker-setup.sh found. Please set up Docker manually if needed."
fi

echo -e "${GREEN}Step 4 complete${NC}"

# ============================================================
# STEP 5: Copy Server .env
# ============================================================
echo -e "${BLUE}=== Step 5: Copying Server .env ===${NC}"

sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS ${SERVER_HOST}:${SERVER_PROJECT_PATH}/.env .server.env

if [ $? -ne 0 ]; then
	echo -e "${RED}Failed to copy server .env file${NC}"
	pause_for_user "Please ensure .env exists on server at ${SERVER_PROJECT_PATH}/.env"

	# Retry after user resolves
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS ${SERVER_HOST}:${SERVER_PROJECT_PATH}/.env .server.env
	if [ $? -ne 0 ]; then
		echo -e "${RED}Still cannot copy server .env - continuing without it${NC}"
	fi
fi

if [ -f ".server.env" ]; then
	git update-index --assume-unchanged .server.env 2>/dev/null || true
	echo -e "${GREEN}Server .env copied to .server.env and marked as assume-unchanged${NC}"
fi

echo -e "${GREEN}Step 5 complete${NC}"

# ============================================================
# STEP 6: Modify Local .env
# ============================================================
echo -e "${BLUE}=== Step 6: Modifying Local .env ===${NC}"

if [ -f ".server.env" ] && [ -f ".env" ]; then
	# Extract values from server env
	APP_NAME=$(get_env_value ".server.env" "APP_NAME")
	APP_KEY=$(get_env_value ".server.env" "APP_KEY")

	if [ -n "$APP_NAME" ]; then
		set_env_value ".env" "APP_NAME" "$APP_NAME"
		echo -e "${GREEN}Set APP_NAME=${APP_NAME}${NC}"
	else
		echo -e "${YELLOW}APP_NAME not found in .server.env${NC}"
	fi

	if [ -n "$APP_KEY" ]; then
		set_env_value ".env" "APP_KEY" "$APP_KEY"
		echo -e "${GREEN}Set APP_KEY${NC}"
	else
		echo -e "${YELLOW}APP_KEY not found in .server.env${NC}"
	fi
else
	echo -e "${YELLOW}Skipping .env modification - missing .server.env or .env${NC}"
fi

echo -e "${GREEN}Step 6 complete${NC}"

# ============================================================
# STEP 7: Create .env.prod.local
# ============================================================
echo -e "${BLUE}=== Step 7: Creating .env.prod.local ===${NC}"

if [ -f ".server.env" ]; then
	# Extract database credentials from server env
	DB_DATABASE=$(get_env_value ".server.env" "DB_DATABASE")
	DB_USERNAME=$(get_env_value ".server.env" "DB_USERNAME")
	DB_PASSWORD=$(get_env_value ".server.env" "DB_PASSWORD")

	cat > .env.prod.local << EOF
PROD_HOST="${HOST}"
PROD_USER="${USERNAME}"
PROD_DB_NAME="${DB_DATABASE}"
PROD_DB_USER="${DB_USERNAME}"
PROD_DB_PASS="${DB_PASSWORD}"
EOF

	echo -e "${GREEN}.env.prod.local created with production credentials${NC}"
else
	echo -e "${YELLOW}Skipping .env.prod.local creation - .server.env not found${NC}"
fi

echo -e "${GREEN}Step 7 complete${NC}"

# ============================================================
# STEP 8: Add Helper Scripts
# ============================================================
echo -e "${BLUE}=== Step 8: Adding Helper Scripts ===${NC}"

# Define scripts to generate
scripts=("ssh.sh")

for script in "${scripts[@]}"; do
	# Create script with variables header
	cat > "${script}" << EOF
#!/bin/bash
set -e

# Configuration
SERVER_USER="${USERNAME}"
SERVER_HOST="${HOST}"
SERVER_PASSWORD="${SSH_PASSWORD}"
SERVER_PATH="${SERVER_PROJECT_PATH}/"
REMOTE_PROGRESS=".remote-in-progress"
EOF

	# Append the template content
	cat "${SCRIPT_DIR}/scripts/${script}" >> "${script}"

	# Make executable
	chmod +x "${script}"

	echo -e "${GREEN}${script} created successfully${NC}"

	# Add to .gitignore
	add_to_gitignore "${script}"
done

echo -e "${GREEN}Step 8 complete${NC}"

# ============================================================
# STEP 9: Upload lazygit
# ============================================================
echo -e "${BLUE}=== Step 9: Uploading lazygit ===${NC}"

sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS "${SCRIPT_DIR}/lazygit" ${SERVER_HOST}:${SERVER_PROJECT_PATH}

if [ $? -ne 0 ]; then
	echo -e "${RED}Failed to upload lazygit${NC}"
	pause_for_user "Please check server connectivity and permissions."
else
	echo -e "${GREEN}lazygit uploaded successfully${NC}"

	# Mark lazygit as assume-unchanged on server
	echo "Marking lazygit as assume-unchanged on server..."
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} \
		"cd ${SERVER_PROJECT_PATH} && git update-index --assume-unchanged lazygit"

	# Pull to get lazygit locally, then mark as assume-unchanged
	echo "Syncing and marking lazygit as assume-unchanged locally..."
	GIT_SSH_COMMAND="sshpass -p '${SSH_PASSWORD}' ssh $SSH_OPTS" git pull
	git update-index --assume-unchanged lazygit

	echo -e "${GREEN}lazygit configured successfully${NC}"
fi

echo -e "${GREEN}Step 9 complete${NC}"

# ============================================================
# STEP 10: SSH Key Management
# ============================================================
echo -e "${BLUE}=== Step 10: SSH Key Management ===${NC}"

# Check server state for SSH keys
HAS_PRIVATE=$(sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} "test -f ~/.ssh/id_rsa && echo 'yes' || echo 'no'")
HAS_PUBLIC=$(sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} "test -f ~/.ssh/id_rsa.pub && echo 'yes' || echo 'no'")

echo "Server SSH key state: private=$HAS_PRIVATE, public=$HAS_PUBLIC"

if [ "$HAS_PRIVATE" = "no" ] && [ "$HAS_PUBLIC" = "yes" ]; then
	# Case A: Server has ONLY public key (no private)
	echo -e "${YELLOW}Case A: Server has only public key - generating new keypair${NC}"

	# Generate new keypair locally
	ssh-keygen -t rsa -b 4096 -f staging.key -N "" -q

	# Upload both keys to server
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS staging.key ${SERVER_HOST}:~/.ssh/id_rsa
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS staging.key.pub ${SERVER_HOST}:~/.ssh/id_rsa.pub

	# Set correct permissions on server
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} "chmod 600 ~/.ssh/id_rsa && chmod 644 ~/.ssh/id_rsa.pub"

	# Add public key to authorized_keys
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} \
		"cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

	# Clean up local public key
	rm -f staging.key.pub

	echo -e "${GREEN}New keypair generated and uploaded to server${NC}"

elif [ "$HAS_PRIVATE" = "yes" ] && [ "$HAS_PUBLIC" = "yes" ]; then
	# Case B: Server has BOTH keys
	echo -e "${YELLOW}Case B: Server has both keys - downloading private key${NC}"

	# Check if public key is in authorized_keys
	IN_AUTH=$(sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} \
		"grep -qf ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys 2>/dev/null && echo 'yes' || echo 'no'")

	if [ "$IN_AUTH" = "no" ]; then
		echo "Adding public key to authorized_keys..."
		sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} \
			"cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
	fi

	# Download private key
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS ${SERVER_HOST}:~/.ssh/id_rsa staging.key
	chmod 600 staging.key

	echo -e "${GREEN}Private key downloaded as staging.key${NC}"

else
	# Case C: Server has NEITHER key (or only private, which is unusual)
	echo -e "${YELLOW}Case C: Server missing keys - generating new keypair${NC}"

	# Generate new keypair locally
	ssh-keygen -t rsa -b 4096 -f staging.key -N "" -q

	# Create .ssh directory on server if needed
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} "mkdir -p ~/.ssh && chmod 700 ~/.ssh"

	# Upload both keys to server
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS staging.key ${SERVER_HOST}:~/.ssh/id_rsa
	sshpass -p "${SSH_PASSWORD}" scp $SSH_OPTS staging.key.pub ${SERVER_HOST}:~/.ssh/id_rsa.pub

	# Set correct permissions on server
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} "chmod 600 ~/.ssh/id_rsa && chmod 644 ~/.ssh/id_rsa.pub"

	# Add public key to authorized_keys (create if doesn't exist)
	sshpass -p "${SSH_PASSWORD}" ssh $SSH_OPTS ${SERVER_HOST} \
		"cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

	# Clean up local public key
	rm -f staging.key.pub

	echo -e "${GREEN}New keypair generated and uploaded to server${NC}"
fi

# Add staging.key to .gitignore and mark as assume-unchanged
if [ -f "staging.key" ]; then
	add_to_gitignore "staging.key"
	git update-index --assume-unchanged staging.key 2>/dev/null || true
	echo -e "${GREEN}staging.key marked as assume-unchanged${NC}"
fi

echo -e "${GREEN}Step 10 complete${NC}"

# ============================================================
# STEP 11: SSH-Add
# ============================================================
echo -e "${BLUE}=== Step 11: Adding SSH Key to Agent ===${NC}"

if [ -f "staging.key" ]; then
	ssh-add ./staging.key 2>/dev/null
	if [ $? -ne 0 ]; then
		echo -e "${YELLOW}Failed to add staging.key to SSH agent${NC}"
		echo "This may happen if ssh-agent is not running."
		echo "You can start it with: eval \$(ssh-agent -s)"
		echo "Then run: ssh-add ./staging.key"
		pause_for_user "Please ensure SSH agent is running and add the key manually if needed."
	else
		echo -e "${GREEN}staging.key added to SSH agent${NC}"
	fi
else
	echo -e "${YELLOW}staging.key not found - skipping ssh-add${NC}"
fi

echo -e "${GREEN}Step 11 complete${NC}"

# ============================================================
# STEP 12: Database Setup
# ============================================================
echo -e "${BLUE}=== Step 12: Database Setup ===${NC}"

# Wipe local database
echo "Wiping local database..."
docker exec mtc-pharmacy-web php artisan db:wipe

if [ $? -ne 0 ]; then
	echo -e "${YELLOW}Failed to wipe database${NC}"
	echo "This may happen if Docker container is not running."
	pause_for_user "Please ensure mtc-pharmacy-web container is running."

	# Retry
	docker exec mtc-pharmacy-web php artisan db:wipe
fi

# Sync database from staging
echo "Syncing database from staging..."
make db-sync

if [ $? -ne 0 ]; then
	echo -e "${YELLOW}make db-sync failed${NC}"
	pause_for_user "Please check Makefile and database connection settings."
else
	echo -e "${GREEN}Database synced successfully${NC}"
fi

echo -e "${GREEN}Step 12 complete${NC}"

# ============================================================
# COMPLETE
# ============================================================
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}   Project Setup Complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "Project cloned to: ${LOCAL_FOLDER}"
echo "SSH key: ./staging.key"
echo ""
echo "Available commands:"
echo "  ./ssh.sh       - SSH into server"
echo "  ./ssh.sh --git - Run lazygit on server"
echo "  ./ssh.sh --db  - Forward database port"
echo ""

exit 0
