#!/usr/bin/env bash
#  ██████╗ ██╗ ██████╗███████╗    ██╗███╗   ██╗███████╗████████╗ █████╗ ██╗     ██╗     ███████╗██████╗
#  ██╔══██╗██║██╔════╝██╔════╝    ██║████╗  ██║██╔════╝╚══██╔══╝██╔══██╗██║     ██║     ██╔════╝██╔══██╗
#  ██████╔╝██║██║     █████╗      ██║██╔██╗ ██║███████╗   ██║   ███████║██║     ██║     █████╗  ██████╔╝
#  ██╔══██╗██║██║     ██╔══╝      ██║██║╚██╗██║╚════██║   ██║   ██╔══██║██║     ██║     ██╔══╝  ██╔══██╗
#  ██║  ██║██║╚██████╗███████╗    ██║██║ ╚████║███████║   ██║   ██║  ██║███████╗███████╗███████╗██║  ██║
#  ╚═╝  ╚═╝╚═╝ ╚═════╝╚══════╝    ╚═╝╚═╝  ╚═══╝╚══════╝   ╚═╝   ╚═╝  ╚═╝╚══════╝╚══════╝╚══════╝╚═╝  ╚═╝
#
#	Author	-	gh0stzk
#	Repo	-	https://github.com/gh0stzk/dotfiles
#	Last updated	-	24.03.2025 08:58:16
#
#	RiceInstaller - Script to install my dotfiles
#
# Copyright (C) 2021-2025 gh0stzk <z0mbi3.zk@protonmail.com>
# Licensed under GPL-3.0 license

# Colors
CRE=$(tput setaf 1)    # Red
CYE=$(tput setaf 3)    # Yellow
CGR=$(tput setaf 2)    # Green
CBL=$(tput setaf 4)    # Blue
BLD=$(tput bold)       # Bold
CNC=$(tput sgr0)       # Reset colors

# Global vars
backup_folder=~/.RiceBackup
ERROR_LOG="$HOME/RiceError.log"

# Logo
logo() {
    local text="${1:?}"
    echo -en "
               %%%
        %%%%%//%%%%%
      %%************%%%
  (%%//############*****%%
 %%%%**###&&&&&&&&&###**//
 %%(**##&&&#########&&&##**
 %%(**##*****#####*****##**%%%
 %%(**##     *****     ##**
   //##   @@**   @@   ##//
     ##     **###     ##
     #######     #####//
       ###**&&&&&**###
       &&&         &&&
       &&&////   &&
          &&//@@@**
            ..***

   ${BLD}${CRE}[ ${CYE}${text} ${CRE}]${CNC}\n\n"
}

# Handle errors
log_error() {
    local error_msg="$1"
    local timestamp=$(date +"%Y-%m-%d %H:%M:%S")

    # Escribir en el log con timestamp
    echo "[${timestamp}] ERROR: ${error_msg}" >> "$ERROR_LOG"

    # Mostrar error en colores
    printf "%s%sERROR:%s %s\n" "${CRE}" "${BLD}" "${CNC}" "${error_msg}" >&2
}

# Verificaciones iniciales
initial_checks() {
    # Verificar usuario root
    if [ "$(id -u)" = 0 ]; then
        log_error "This script MUST NOT be run as root user."
        exit 1
    fi

    # Verificar directorio HOME
    if [ "$PWD" != "$HOME" ]; then
        log_error "The script must be executed from HOME directory."
        exit 1
    fi

    # Verificar conexión a internet
    if ! ping -q -c 1 -W 1 8.8.8.8 &>/dev/null; then
        log_error "No internet connection detected."
        exit 1
    fi
}

# Internal verification function
is_installed() {
    pacman -Qq "$1" >/dev/null 2>&1
}

is_reflector() {
	if ! command -v reflector  >/dev/null; then
		echo -e "\t${BLD}${CBL}Installing reflector to get the best mirrors...${CNC}"
		sudo pacman -Syy >> "$ERROR_LOG" 2>&1
		sudo pacman -S reflector --noconfirm >> "$ERROR_LOG" 2>&1
	fi
}

welcome() {
    clear
	logo "Welcome $USER"
	echo -en "${BLD}${CGR}This script will install my dotfiles and this is what it will do:${CNC}

  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} 2 repositories will be installed. ${CBL}gh0stzk-dotfiles${CNC} and ${CBL}Chaotic-Aur${CNC}
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Check necessary dependencies and install them
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Download my dotfiles in ${HOME}/dotfiles
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Backup of possible existing configurations (bspwm, polybar, etc...)
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Install my configuration
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Enabling MPD service (Music player daemon)
  ${BLD}${CGR}[${CYE}i${CGR}]${CNC} Change your shell to zsh shell

${BLD}${CGR}[${CRE}!${CGR}]${CNC} ${BLD}${CRE}My dotfiles DO NOT modify any of your system configurations${CNC}
${BLD}${CGR}[${CRE}!${CGR}]${CNC} ${BLD}${CRE}This script does NOT have the potential power to break your system${CNC}

"
    local yn
    while true; do
        read -rp " ${BLD}${CGR}Do you wish to continue?${CNC} [y/N]: " yn
        case "${yn,,}" in
            y|yes)
                return 0
                ;;
            n|no|"")
                echo -e "\n${BLD}${CYE}Operation cancelled${CNC}"
                exit 0
                ;;
            *)
                echo -e "\n${BLD}${CRE}Error:${CNC} Just write '${BLD}${CYE}y${CNC}' or '${BLD}${CYE}n${CNC}'\n"
                ;;
        esac
    done
}


add_gh0stzk_repo() {
    clear
    logo "Add gh0stzk custom repo"
    local repo_name="gh0stzk-dotfiles"
	sleep 2

    # Check if the repository already exists
    echo -e "${BLD}${CYE}Installing ${CBL}${repo_name} ${CYE}repository...${CNC}"
    if ! grep -q "\[${repo_name}\]" /etc/pacman.conf; then
		if echo -e "\n[${repo_name}]\nSigLevel = Optional TrustAll\nServer = http://gh0stzk.github.io/pkgs/x86_64" | \
       sudo tee -a /etc/pacman.conf >/dev/null 2>> "$ERROR_LOG"
		then
			echo -e "\n${BLD}${CYE}${repo_name} ${CGR}repository added succesfully!${CNC}"

        # Update databases
			if ! sudo pacman -Syy >> "$ERROR_LOG" 2>&1; then
				log_error "Database update failed"
				return 1
			fi
		else
			log_error "Error adding repository - check permissions"
			return 1
		fi
	else
        echo -e "\n${BLD}${CYE}The repository already exists and is configured${CNC}"
        sleep 3
        return 0
    fi
}

add_chaotic_repo() {
    clear
    logo "Add chaotic-aur repository"
    local repo_name="chaotic-aur"
    local key_id="3056513887B78AEB"
    sleep 2

    # Check if repository already exists
    echo -e "${BLD}${CYE}Configuring ${CBL}${repo_name} ${CYE}repository...${CNC}"
    if grep -q "\[${repo_name}\]" /etc/pacman.conf; then
        echo -e "\n${BLD}${CYE}Repository already exists in pacman.conf${CNC}"
        sleep 3
        return 0
    fi

    # Key management
    if ! pacman-key -l | grep -q "$key_id"; then
        echo -e "${BLD}${CYE}Adding GPG key...${CNC}"
        if ! sudo pacman-key --recv-key "$key_id" --keyserver keyserver.ubuntu.com >> "$ERROR_LOG" 2>&1; then
            log_error "Failed to receive GPG key"
            return 1
        fi

        echo -e "${BLD}${CYE}Signing key locally...${CNC}"
        if ! sudo pacman-key --lsign-key "$key_id" >> "$ERROR_LOG" 2>&1; then
            log_error "Failed to sign GPG key"
            return 1
        fi
    else
        echo -e "${BLD}${CYE}GPG key already exists in keyring${CNC}"
    fi

    # Install required packages if missing
    local chaotic_pkgs=("chaotic-keyring" "chaotic-mirrorlist")
    for pkg in "${chaotic_pkgs[@]}"; do
        if ! pacman -Qq "$pkg" >/dev/null 2>&1; then
            echo -e "${BLD}${CYE}Installing ${CBL}${pkg}${CNC}"
            if ! sudo pacman -U --noconfirm "https://cdn-mirror.chaotic.cx/chaotic-aur/${pkg}.pkg.tar.zst" >> "$ERROR_LOG" 2>&1; then
                log_error "Failed to install ${pkg}"
                return 1
            fi
        else
            echo -e "${BLD}${CYE}${pkg} is already installed${CNC}"
        fi
    done

    # Add repository configuration
    echo -e "${BLD}${CYE}Adding repository to pacman.conf...${CNC}"
    if ! echo -e "\n[${repo_name}]\nInclude = /etc/pacman.d/chaotic-mirrorlist" | \
       sudo tee -a /etc/pacman.conf >/dev/null 2>> "$ERROR_LOG"; then
        log_error "Failed to add repository configuration"
        return 1
    fi

    echo -e "\n${BLD}${CGR}${repo_name} repository configured successfully!${CNC}"
    sleep 3
}

install_dependencies() {
	clear
    logo "Installing needed packages from official repositories..."
	sleep 2

	is_reflector
	echo -e "\n${BLD}${CGR}Getting the 10 best and fastest mirrors${CNC}\n"
	sudo reflector --verbose --age 12 --fastest 10 --score 10 --protocol https --latest 5 --sort rate --save /etc/pacman.d/mirrorlist
	sudo pacman -Syy

    # List of dependencies
    local dependencies=(
        alacritty base-devel bat brightnessctl bspwm clipcat dunst eza feh fzf thunar
        tumbler gvfs-mtp firefox geany git imagemagick jq jgmenu kitty libwebp maim
        mpc mpd mpv neovim ncmpcpp npm pamixer pacman-contrib papirus-icon-theme
        picom playerctl polybar polkit-gnome python-gobject redshift rofi rustup
        sxhkd tmux xclip xdg-user-dirs xdo xdotool xsettingsd xorg-xdpyinfo
        xorg-xkill xorg-xprop xorg-xrandr xorg-xsetroot xorg-xwininfo yazi zsh
        zsh-autosuggestions zsh-history-substring-search zsh-syntax-highlighting
        ttf-inconsolata ttf-jetbrains-mono ttf-jetbrains-mono-nerd ttf-terminus-nerd
        ttf-ubuntu-mono-nerd webp-pixbuf-loader
    )

    echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"
	sleep 2

    # Detect missing packages
    local missing_pkgs=()
    for pkg in "${dependencies[@]}"; do
        if ! is_installed "$pkg"; then
            missing_pkgs+=("$pkg")
            echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
        else
            echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
        fi
    done

    # Batch installation
    if ((${#missing_pkgs[@]} > 0)); then
		echo -e "\n${BLD}${CYE}Installing ${#missing_pkgs[@]} packages, please wait...${CNC}\n"

        if sudo pacman -S --noconfirm --needed "${missing_pkgs[@]}" >> "$ERROR_LOG" 2>&1; then
            # Verify complete installation
            local failed_pkgs=()
            for pkg in "${missing_pkgs[@]}"; do
                if ! is_installed "$pkg"; then
                    failed_pkgs+=("$pkg")
                    log_error "Failed to install: $pkg"
                fi
            done

            # Show final results
            if ((${#failed_pkgs[@]} == 0)); then
                echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\n"
            else
                echo -e "${BLD}${CRE}Failed to install ${#failed_pkgs[@]} packages:${CNC}\n"
                echo -e "  ${BLD}${CYE}${failed_pkgs[*]}${CNC}\n\n"
            fi
        else
            log_error "Critical error during batch installation"
            echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\n"
            return 1
        fi
    else
        echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
    fi

    sleep 3
}

install_gh0stzk_dependencies() {
	clear
    logo "Installing needed packages from gh0stzk repository..."
	sleep 2

    # List of dependencies
    local gh0stzk_dependencies=(
        gh0stzk-gtk-themes gh0stzk-cursor-qogirr gh0stzk-icons-beautyline
        gh0stzk-icons-candy gh0stzk-icons-catppuccin-mocha gh0stzk-icons-dracula
        gh0stzk-icons-glassy gh0stzk-icons-gruvbox-plus-dark gh0stzk-icons-hack
        gh0stzk-icons-luv gh0stzk-icons-sweet-rainbow gh0stzk-icons-tokyo-night
        gh0stzk-icons-vimix-white gh0stzk-icons-zafiro gh0stzk-icons-zafiro-purple
    )

    echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"
	sleep 2

    # Detect missing packages
    local missing_gh0stzk_pkgs=()
    for pkg in "${gh0stzk_dependencies[@]}"; do
        if ! is_installed "$pkg"; then
            missing_gh0stzk_pkgs+=("$pkg")
            echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
        else
            echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
        fi
    done

    # Batch installation
    if ((${#missing_gh0stzk_pkgs[@]} > 0)); then
        echo -e "\n${BLD}${CYE}Installing ${#missing_gh0stzk_pkgs[@]} packages, please wait...${CNC}\n"

        if sudo pacman -S --noconfirm --needed "${missing_gh0stzk_pkgs[@]}" >> "$ERROR_LOG" 2>&1; then
            # Verify complete installation
            local failed_gh0stzk_pkgs=()
            for pkg in "${missing_gh0stzk_pkgs[@]}"; do
                if ! is_installed "$pkg"; then
                    failed_gh0stzk_pkgs+=("$pkg")
                    log_error "Failed to install: $pkg"
                fi
            done

            # Show final results
            if ((${#failed_gh0stzk_pkgs[@]} == 0)); then
                echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\n"
            else
                echo -e "${BLD}${CRE}Failed to install ${#failed_gh0stzk_pkgs[@]} packages:${CNC}\n"
                echo -e "  ${BLD}${CYE}${failed_gh0stzk_pkgs[*]}${CNC}\n\n"
            fi
        else
            log_error "Critical error during batch installation"
            echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\n"
            return 1
        fi
    else
        echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
    fi

    sleep 3
}

install_chaotic_dependencies() {
	clear
    logo "Installing needed packages from chaotic repository..."
	sleep 2

    # List of dependencies
    local chaotic_dependencies=(
        paru eww-git i3lock-color simple-mtpfs fzf-tab-git
    )

    echo -e "\n${BLD}${CBL}Checking for required packages...${CNC}\n"
	sleep 2

    # Detect missing packages
    local missing_chaotic_pkgs=()
    for pkg in "${chaotic_dependencies[@]}"; do
        if ! is_installed "$pkg"; then
            missing_chaotic_pkgs+=("$pkg")
            echo -e " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}"
        else
            echo -e "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}"
        fi
    done

    # Batch installation
    if ((${#missing_chaotic_pkgs[@]} > 0)); then
        echo -e "\n${BLD}${CYE}Installing ${#missing_chaotic_pkgs[@]} packages, please wait...${CNC}\n"

        if sudo pacman -S --noconfirm --needed "${missing_chaotic_pkgs[@]}" >> "$ERROR_LOG" 2>&1; then
            # Verify complete installation
            local failed_chaotic_pkgs=()
            for pkg in "${missing_chaotic_pkgs[@]}"; do
                if ! is_installed "$pkg"; then
                    failed_chaotic_pkgs+=("$pkg")
                    log_error "Failed to install: $pkg"
                fi
            done

            # Show final results
            if ((${#failed_chaotic_pkgs[@]} == 0)); then
                echo -e "${BLD}${CGR}All packages installed successfully!${CNC}\n\n"
            else
                echo -e "${BLD}${CRE}Failed to install ${#failed_chaotic_pkgs[@]} packages:${CNC}\n"
                echo -e "  ${BLD}${CYE}${failed_chaotic_pkgs[*]}${CNC}\n\n"
            fi
        else
            log_error "Critical error during batch installation"
            echo -e "${BLD}${CRE}Installation failed! Check log for details${CNC}\n"
            return 1
        fi
    else
        echo -e "\n${BLD}${CGR}All dependencies are already installed!${CNC}"
    fi

    sleep 3
}

install_aur_dependencies() {
	clear
    logo "Installing AUR dependencies..."
	sleep 2

    # AUR Package List
    local aur_apps=(xqp xwinwrap-0.9-bin)

    echo -e "${BLD}${CBL}Checking for required AUR packages...${CNC}\n"
    sleep 2

    # Detect missing AUR packages
    local missing_aur=()
    for pkg in "${aur_apps[@]}"; do
        if ! is_installed "$pkg"; then
            missing_aur+=("$pkg")
            echo -en " ${BLD}${CYE}${pkg} ${CRE}not installed${CNC}\n"
        else
            echo -en "${BLD}${CGR}${pkg} ${CBL}already installed${CNC}\n"
        fi
    done

    # Batch AUR installation
    if ((${#missing_aur[@]} > 0)); then
        echo -en "\n\n${BLD}${CYE}Installing ${#missing_aur[@]} AUR packages, please wait...${CNC}\n"

        local aur_failed=()
        for pkg in "${missing_aur[@]}"; do
            echo -en "${BLD}${CBL}Processing: ${pkg}${CNC}\n"

            if paru -S --skipreview --noconfirm "$pkg" >> "$ERROR_LOG" 2>&1; then
                echo -en "  ${BLD}${CGR}Successfully installed!${CNC}\n"
            else
                log_error "AUR package installation failed: $pkg"
                aur_failed+=("$pkg")
                echo -en "  ${BLD}${CRE}Installation failed!${CNC}\n"
            fi
            sleep 0.5
        done

        # Show final summary
        if ((${#aur_failed[@]} > 0)); then
            echo -en "\n${BLD}${CRE}Failed ${#aur_failed[@]}/${#missing_aur[@]} AUR packages:${CNC}\n"
            echo -en "${BLD}${CYE}${aur_failed[*]}${CNC}\n\n"
        else
            echo -en "\n${BLD}${CGR}All AUR packages installed successfully!${CNC}\n\n"
        fi
    else
        echo -en "\n${BLD}${CGR}All AUR dependencies are already installed!${CNC}\n\n"
    fi

    sleep 3
}

clone_dotfiles() {
    clear
    logo "Downloading dotfiles"
    local repo_url="https://github.com/gh0stzk/dotfiles"
    local repo_dir="$HOME/dotfiles"
    local timestamp=$(date +%Y%m%d-%H%M%S)
    sleep 3

    # Handle existing repository
    if [[ -d "$repo_dir" ]]; then
        local backup_dir="${repo_dir}_${timestamp}"
        echo -en "${BLD}${CYE}Existing repository found - renaming to: ${CBL}${backup_dir}${CNC}\n"

        if ! mv -v "$repo_dir" "$backup_dir" >> "$ERROR_LOG" 2>&1; then
            log_error "Failed to rename existing repository"
            echo -en "${BLD}${CRE}Renaming failed! Check${CYE}RiceError.log${CNC}\n"
            return 1
        fi
        echo -en "${BLD}${CGR}Repository successfully renamed for backup${CNC}\n\n"
    fi

    # Clone new repository
    echo -en "${BLD}${CYE}Cloning dotfiles from: ${CBL}${repo_url}${CNC}\n"
    if git clone --depth=1 "$repo_url" "$repo_dir" >> "$ERROR_LOG" 2>&1; then
        echo -en "${BLD}${CGR}Dotfiles cloned successfully!${CNC}\n\n"
    else
        log_error "Repository clone failed"
        echo -en "${BLD}${CRE}Clone failed! Check ${CYE}RiceError.log${CNC}\n"
        return 1
    fi

    sleep 3
}

backup_existing_config() {
	clear
    logo "Backup files"
    local date=$(date +%Y%m%d-%H%M%S)
    sleep 2

    # User questions
    declare -g try_nvim try_firefox
	echo -en "My dotfiles come with a lightweight, simple, and functional Neovim configuration.\nBut if you already have a custom, super pro Neovim configuration and don't want to try mine, just type 'n'\n"
    while true; do
        read -rp "${BLD}${CYE}Do you want to use my Neovim setup?${CNC} [y/N]: " try_nvim
        case "${try_nvim,,}" in
            y|n) break ;;
            *) echo " ${BLD}${CRE}Error:${CNC} write 'y' or 'n'" ;;
        esac
    done

	echo -en "\nMy dotfiles come with a beautiful, minimalist Firefox theme, but if you don't want to try it, just type 'n'.\n"
    while true; do
        read -rp "${BLD}${CYE}Do you want to use my Firefox theme?${CNC} [y/N]: " try_firefox
        case "${try_firefox,,}" in
            y|n) break ;;
            *) echo " ${BLD}${CRE}Error:${CNC} write 'y' or 'n'" ;;
        esac
    done

    # Create backup directory
    mkdir -p "$backup_folder" 2>> "$ERROR_LOG"
    echo -en "\n${BLD}${CYE}Backup directory: ${CBL}${backup_folder}${CNC}\n\n"
    sleep 2

    # Generic backup function
    backup_item() {
        local type=$1 path=$2 target=$3
        local base_name=$(basename "$path")

        if [ -$type "$path" ]; then
            if mv "$path" "$backup_folder/${target}_${date}" 2>> "$ERROR_LOG"; then
                echo -en "${BLD}${CGR}${base_name} ${CBL}backup successful${CNC}\n"
            else
                log_error "Error backup: $base_name"
                echo -en "${BLD}${CRE}${base_name} ${CYE}backup failed${CNC}\n"
            fi
            sleep 0.5
        else
            echo -en "${BLD}${CYE}${base_name} ${CBL}not found${CNC}\n"
            sleep 0.3
        fi
    }

    # Backup of main configurations
    local config_folders=(bspwm alacritty clipcat picom rofi eww sxhkd dunst kitty polybar geany gtk-3.0 ncmpcpp yazi tmux zsh mpd paru)
    for folder in "${config_folders[@]}"; do
        backup_item d "$HOME/.config/$folder" "$folder"
    done

    # Neovim Conditional Backup
    if [[ "${try_nvim,,}" == "y" ]]; then
        backup_item d "$HOME/.config/nvim" "nvim"
    fi

    # Firefox management
    if [[ "${try_firefox,,}" == "y" ]]; then
        if [ ! -d "$HOME/.mozilla" ]; then
            echo -en "${BLD}${CYE}Creating Firefox profile...${CNC}\n"
            timeout 1s firefox --headless --display=0 >/dev/null 2>&1
            sleep 1
        fi

        # Backup of Firefox components
        local firefox_profile=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -type d -name '*.default-release' 2>/dev/null | head -1)

        if [ -n "$firefox_profile" ]; then
            backup_item d "${firefox_profile}/chrome" "chrome"
            backup_item f "${firefox_profile}/user.js" "user.js"
        fi
    fi

    # Backup of individual files
    local single_files=("$HOME/.zshrc" "$HOME/.gtkrc-2.0" "$HOME/.icons")
    for item in "${single_files[@]}"; do
        if [[ "$item" == *".icons" ]]; then
            backup_item d "$item" ".icons"
        else
            backup_item f "$item" "$(basename "$item")"
        fi
    done

    echo -en "\n${BLD}${CGR}Backup completed!${CNC}\n\n"
    sleep 3
}

install_dotfiles() {
	clear
    logo "Installing dotfiles.."
    echo -en "${BLD}${CBL} Copying files to respective directories...${CNC}\n\n"
	sleep 2

    # Create required directories
    local required_dirs=("$HOME/.config" "$HOME/.local/bin" "$HOME/.local/share")
    for dir in "${required_dirs[@]}"; do
        if [ ! -d "$dir" ]; then
            mkdir -p "$dir" 2>> "$ERROR_LOG" && \
            echo -en "${BLD}${CGR}Created directory: ${CBL}${dir}${CNC}\n"
        fi
    done

    # Generic function to copy files
    copy_files() {
        local source="$1"
        local target="$2"
        local item_name=$(basename "$source")

        if cp -R "$source" "$target" 2>> "$ERROR_LOG"; then
            echo -en "${BLD}${CYE}${item_name} ${CGR}copied successfully!${CNC}\n"
            return 0
        else
            log_error "Failed to copy: $item_name"
            echo -en "${BLD}${CYE}${item_name} ${CRE}copy failed!${CNC}\n"
            return 1
        fi
    }

    # Copy main settings
    local config_source="$HOME/dotfiles/config"
    for config_dir in "$config_source"/*; do
        local dir_name=$(basename "$config_dir")

        # Skip neovim if the user doesn't want it
        [[ "$dir_name" == "nvim" && "$try_nvim" != "y" ]] && continue

        copy_files "$config_dir" "$HOME/.config/"
        sleep 0.3
    done

    # Copy miscellaneous components
    local misc_items=("applications" "asciiart" "fonts" "startup-page" "bin")
    for item in "${misc_items[@]}"; do
        local source_path="$HOME/dotfiles/misc/$item"
        local target_path="$HOME/.local/share/"

        [[ "$item" == "bin" ]] && target_path="$HOME/.local/"

        copy_files "$source_path" "$target_path"
        sleep 0.3
    done

    # Handle Firefox theme
    if [[ "$try_firefox" == "y" ]]; then
    local firefox_profile=$(find "$HOME/.mozilla/firefox" -maxdepth 1 -type d -name '*.default-release' 2>/dev/null | head -n1)

    if [ -n "$firefox_profile" ]; then
        # Create necessary directories
        mkdir -p "$firefox_profile/chrome" 2>> "$ERROR_LOG"

        # Copy content from firefox/
        for item in "$HOME/dotfiles/misc/firefox/"*; do
            if [ -e "$item" ]; then
                local item_name=$(basename "$item")
                local target="$firefox_profile"

                if [[ "$item_name" == "chrome" ]]; then
                    for chrome_item in "$item"/*; do
                        copy_files "$chrome_item" "$firefox_profile/chrome/"
                    done
                else
                    copy_files "$item" "$target/"
                fi
            fi
        done

			# Update settings
			local user_js="$firefox_profile/user.js"
			local startup_cfg="$HOME/.local/share/startup-page/config.js"

			if [ -f "$user_js" ]; then
				sed -i "s|/home/z0mbi3|/home/$USER|g" "$user_js" 2>> "$ERROR_LOG" && \
				echo -en "${BLD}${CGR}Firefox config updated!${CNC}\n"
			fi

			if [ -f "$startup_cfg" ]; then
				sed -i "s/name: 'gh0stzk'/name: '$USER'/" "$startup_cfg" 2>> "$ERROR_LOG" && \
				echo -en "${BLD}${CGR}Startup page updated!${CNC}\n"
			fi
		else
			log_error "Firefox profile not found"
			echo -en "${BLD}${CRE}Firefox profile not found!${CNC}\n"
		fi
	fi

    # Copy remaining files
    local home_files=("$HOME/dotfiles/home/.zshrc" "$HOME/dotfiles/home/.gtkrc-2.0" "$HOME/dotfiles/home/.icons")
    for file in "${home_files[@]}"; do
        copy_files "$file" "$HOME/"
    done

    # Update font cache
    if fc-cache -rv >/dev/null 2>&1; then
        echo -en "\n${BLD}${CGR}Font cache updated successfully!${CNC}\n"
    else
        log_error "Failed to update font cache"
    fi

	# Generate xdg dirs
	if [[ ! -e "$HOME/.config/user-dirs.dirs" ]]; then
		if xdg-user-dirs-update >/dev/null 2>&1; then
			echo -en "${BLD}${CGR}Xdg dirs generated successfully!${CNC}\n"
		else
			log_error "Failed to generate xdg dirs"
		fi
	fi

    # Copying polybar-update.hook
    if [[ ! -d /etc/pacman.d/hooks ]]; then
        sudo mkdir -p /etc/pacman.d/hooks
    fi

    if sudo cp "$HOME/dotfiles/misc/polybar-update.hook" /etc/pacman.d/hooks; then
        echo -en "${BLD}${CGR}Pacman hook copied successfully!${CNC}\n"
    else
        log_error "Failed to copy pacman hook :("
    fi

    echo -en "\n${BLD}${CGR}Dotfiles installed successfully!${CNC}\n"
    sleep 3
}

configure_services() {
	clear
    logo "Configuring Services"
    local picom_config="$HOME/.config/bspwm/src/config/picom.conf"
    sleep 2

    # MPD Service Management
    if systemctl is-enabled --quiet mpd.service; then
        printf "%s%sDisabling global MPD service...%s\n" "${BLD}" "${CYE}" "${CNC}"
        if sudo systemctl disable --now mpd.service >> "$ERROR_LOG" 2>&1; then
            echo -en "${BLD}${CGR}Global MPD service disabled successfully${CNC}"
        else
            log_error "Failed to disable global MPD service"
            echo -en "${BLD}${CRE}Failed to disable global MPD service${CNC}\n\n"
        fi
    fi

    # User-level MPD Service
    echo -en "${BLD}${CYE}Enabling user MPD service...${CNC}\n"
    if systemctl --user enable --now mpd.service >> "$ERROR_LOG" 2>&1; then
        echo -en "${BLD}${CGR}User MPD service activated successfully${CNC}\n\n"
    else
        log_error "Failed to enable user MPD service"
        echo -en "${BLD}${CRE}Failed to activate user MPD service${CNC}\n\n"
    fi

    # User-level ArchUpdates
    echo -en "${BLD}${CYE}Enabling user ArchUpdates service...${CNC}\n"
    if systemctl --user enable --now ArchUpdates.timer >> "$ERROR_LOG" 2>&1; then
        echo -en "${BLD}${CGR}User ArchUpdates service activated successfully${CNC}\n\n"
    else
        log_error "Failed to enable user ArchUpdates service"
        echo -en "${BLD}${CRE}Failed to activate user ArchUpdates service${CNC}\n\n"
    fi

    # Virtual Machine Detection
    is_virtual_machine() {
        systemd-detect-virt --quiet && return 0 || return 1
    }

    # Picom Configuration for VMs
    if is_virtual_machine; then
        echo -en "${BLD}${CYE}Virtual machine detected${CNC}\n"
        echo -en "${BLD}${CYE}Adjusting Picom configuration...${CNC}\n"

        if [ -f "$picom_config" ]; then
            if sed -i 's/backend = "glx"/backend = "xrender"/' "$picom_config" >> "$ERROR_LOG" 2>&1; then
                echo -en "${BLD}${CGR}Picom backend changed to xrender${CNC}\n\n"
            else
                log_error "Failed to modify Picom configuration"
                echo -en "${BLD}${CRE}Failed to adjust Picom settings${CNC}\n\n"
            fi
        else
            log_error "Picom configuration file not found"
            echo -en "${BLD}${CRE}Picom config file missing: ${CYE}${picom_config}${CNC}\n\n"
        fi

        if [ -f "$picom_config" ]; then
            if sed -i 's/vsync = true/vsync = false/' "$picom_config" >> "$ERROR_LOG" 2>&1; then
                echo -en "${BLD}${CGR}Picom vSync disabled${CNC}\n\n"
            else
                log_error "Failed to modify Picom configuration"
                echo -en "${BLD}${CRE}Failed to adjust Picom settings${CNC}\n\n"
            fi
        else
            log_error "Picom configuration file not found"
            echo -en "${BLD}${CRE}Picom config file missing: ${CYE}${picom_config}${CNC}\n\n"
        fi
    fi

    sleep 3
}

change_default_shell() {
	clear
	logo "Changing default shell to zsh"
	local zsh_path=$(which zsh)
	sleep 3

	if [[ -z "$zsh_path" ]]; then
		log_error "Zsh binary not found"
		echo -en "${BLD}${CRE}Zsh is not installed! Cannot change shell${CNC}\n\n"
		return 1
	fi

	if [[ "$SHELL" != "$zsh_path" ]]; then
		echo -en "${BLD}${CYE}Changing your shell to Zsh...${CNC}\n"

		if chsh -s "$zsh_path" 2> >(tee -a "$ERROR_LOG"); then
			echo -en "\n${BLD}${CGR}Shell changed successfully!${CNC}\n"
		else
			log_error "Failed to change shell to Zsh"
			echo -en "\n${BLD}${CRE}Error changing shell! ${CYE}Check RiceError.log${CNC}\n\n"
		fi
	else
		echo -en "${BLD}${CGR}Zsh is already your default shell!${CNC}\n\n"
	fi

    sleep 3
}

final_prompt() {
	clear
    logo "Installation Complete"
    sleep 2

    echo -en "${BLD}${CGR}Installation completed successfully!${CNC}\n"
    echo -en "${BLD}${CRE}You ${CBL}MUST ${CRE}restart your system to apply changes${CNC}\n\n"

    while true; do
        read -rp " ${BLD}${CYE}Reboot now?${CNC} [y/N]: " yn
        case "${yn,,}" in
            y|yes)
                echo -en "\n${BLD}${CGR}Initiating reboot...${CNC}\n"
                sleep 2
                if ! sudo reboot >> "$ERROR_LOG" 2>&1; then
                    log_error "Failed to trigger reboot"
                    echo -en "${BLD}${CRE}Reboot failed! Execute manually${CNC}\n"
                fi
                exit 0
                ;;
            n|no|"")
                echo -en "\n${BLD}${CYE}You really need to reboot bro!!${CNC}\n\n"
                exit 0
                ;;
            *)
                echo -en "\n${BLD}${CRE}Invalid choice - use '${CYE}y${CRE}' or '${CYE}n${CRE}'${CNC}\n\n"
                sleep 1
                ;;
        esac
    done
}


# --- Main run --- #
initial_checks
welcome
add_gh0stzk_repo
add_chaotic_repo

install_dependencies
install_gh0stzk_dependencies
install_chaotic_dependencies
install_aur_dependencies
clone_dotfiles

backup_existing_config
install_dotfiles
configure_services
change_default_shell
final_prompt