#!/usr/bin/env bash

# COLOURS
red='\033[1;31m'
green='\033[1;32m'
blue='\033[1;34m'
cyan='\033[1;36m'
yellow='\033[1;33m'
nc='\033[0m'

# CONFIGURATION
session_file="$HOME/.aria2_session"
xdg_videos="${XDG_VIDEOS_DIR:-$HOME/Videos}"
xdg_music="${XDG_MUSIC_DIR:-$HOME/Music}"
hist_video="$HOME/.config/archive_history_video.txt"
hist_music="$HOME/.config/archive_history_music.txt"

# establish configuration directory
mkdir -p "$HOME/.config"
touch "$session_file"

# UTILITIES
log() {
    local col="$1"
    local msg="$2"
    printf "${col}%s${nc}\n" "$msg"
}

# verify core binaries and clipboard providers
check_dependencies() {
    local deps=("aria2c" "yt-dlp" "spotdl")
    for dep in "${deps[@]}"; do
        if ! command -v "$dep" >/dev/null 2>&1; then
            log "$red" "missing core dependency: $dep"
            exit 1
        fi
    done

    if ! command -v wl-paste >/dev/null 2>&1 && ! command -v xclip >/dev/null 2>&1; then
        log "$yellow" "warning: missing wl-clipboard or xclip. clipboard polling disabled."
    fi
}

# extract link from clipboard
get_clipboard_url() {
    local content=""

    if command -v wl-paste >/dev/null 2>&1; then
        content=$(wl-paste)
    elif command -v xclip >/dev/null 2>&1; then
        content=$(xclip -o -selection clipboard)
    fi

    content="$(echo "$content" | xargs)"

    [[ "$content" == http* ]] && echo "$content"
}

# ARIA2C CORE
run_aria2c() {
    aria2c \
        --continue=true \
        --max-connection-per-server=16 \
        --split=16 \
        --min-split-size=1M \
        --user-agent="Mozilla/5.0" \
        --save-session="$session_file" \
        --save-session-interval=60 \
        --seed-time=0 \
        "$@" || log "$red" "aria2c failed"
}

# SPOTIFY CORE
run_spotdl() {
    local url="$1"
    local target_dir="$2"

    log "$cyan" "spotify routing to $target_dir"

    mkdir -p "$target_dir"
    cd "$target_dir" || return 1

    local cmd=(
        spotdl download "$url"
        --format opus
        --output "{artists} - {title}.{ext}"
    )

    local attempt
    for attempt in 1 2 3; do
        log "$cyan" "spotdl execution attempt $attempt"

        if timeout 300 "${cmd[@]}"; then
            return 0
        fi

        log "$yellow" "spotdl network or api failure on attempt $attempt"
        sleep 2
    done

    log "$red" "spotdl failed permanently due to api restrictions"
    return 1
}

# YT-DLP CORE
run_ytdlp() {
    local url="$1"
    local target_dir="$2"
    local hist_file="$3"
    local out_tmpl="$4"
    shift 4
    local extra_args=("$@")

    log "$cyan" "media routing to $target_dir"

    mkdir -p "$target_dir"

    yt-dlp \
        --progress \
        --ignore-errors \
        --add-metadata \
        --embed-thumbnail \
        --embed-subs \
        --embed-chapters \
        --downloader aria2c \
        --downloader-args "aria2c:-x 4 -k 1M" \
        --download-archive "$hist_file" \
        -o "${target_dir}/${out_tmpl}" \
        "${extra_args[@]}" \
        "$url" \
        || log "$yellow" "yt-dlp finished with errors"
}

# MODES
mode_media() {
    local url="$1"
    local media_type="$2"
    local format_arg="$3"
    local playlist_flag="$4"

    local audio_tmpl="%(playlist_index|)s%(playlist_index& - |)s%(artist,uploader|Unknown)s - %(title)s [%(id)s].%(ext)s"
    local video_tmpl="%(playlist_index|)s%(playlist_index& - |)s%(uploader,channel|Unknown)s - %(title)s [%(id)s].%(ext)s"

    local extra_args=()
    [[ -n "$playlist_flag" ]] && extra_args+=("$playlist_flag")

    if [[ "$media_type" == "audio" ]]; then
        run_ytdlp "$url" "$xdg_music" "$hist_music" "$audio_tmpl" \
            "${extra_args[@]}" \
            --extract-audio --audio-format opus --audio-quality 0
    else
        if [[ "$format_arg" == "best" ]]; then
            run_ytdlp "$url" "$xdg_videos" "$hist_video" "$video_tmpl" \
                "${extra_args[@]}" -f "bv*+ba/b" --merge-output-format mkv

        elif [[ "$format_arg" == "ask" ]]; then
            log "$cyan" "querying upstream for format manifests"
            yt-dlp -F "$url"
            printf "\n${cyan}enter desired format code:${nc} "
            read -r selected_format
            
            if [[ -n "$selected_format" ]]; then
                run_ytdlp "$url" "$xdg_videos" "$hist_video" "$video_tmpl" \
                    "${extra_args[@]}" -f "$selected_format" --merge-output-format mkv
            else
                log "$red" "aborted: no format code provided"
                exit 1
            fi
        else
            run_ytdlp "$url" "$xdg_videos" "$hist_video" "$video_tmpl" \
                "${extra_args[@]}" -f "$format_arg" --merge-output-format mkv
        fi
    fi
}

# BATCH MODE
mode_batch() {
    local filepath="$1"

    [[ ! -f "$filepath" ]] && {
        log "$red" "batch file missing: $filepath"
        exit 1
    }

    log "$blue" "batch mode execution for $filepath"

    local tmp
    tmp=$(mktemp)

    # strip comments and empty lines
    grep -vE '^\s*#|^\s*$' "$filepath" > "$tmp"

    run_aria2c --input-file="$tmp" --max-concurrent-downloads=4

    rm -f "$tmp"
}

# ARG PARSING
target=""
media_type="video"
format_arg="best"
playlist_flag=""
resume=0

while [[ $# -gt 0 ]]; do
    case "$1" in
        -t|--type)
            media_type="$2"; shift 2 ;;
        -f|--format)
            format_arg="$2"; shift 2 ;;
        -p|--playlist)
            playlist_flag="--yes-playlist"; shift ;;
        -r|--resume)
            resume=1; shift ;;
        *)
            [[ -z "$target" ]] && target="$1"
            shift ;;
    esac
done

# ROUTER
check_dependencies

[[ -z "$target" ]] && target=$(get_clipboard_url)

if [[ -z "$target" && $resume -eq 0 ]]; then
    log "$yellow" "usage: fetch [url|file] [-t audio|video] [-f best|ask|code] [-p]"
    exit 1
fi

if [[ $resume -eq 1 ]]; then
    log "$yellow" "resuming global aria2 session"
    run_aria2c --input-file="$session_file"

elif [[ -f "$target" ]]; then
    mode_batch "$target"

elif [[ "$target" =~ \.(iso|zip|rar|tar|gz|bz2|7z|torrent|pdf|png|jpg|mp4|mkv)$ ]]; then
    log "$blue" "direct file payload detected"
    run_aria2c "$target"

elif [[ "$target" =~ spotify\.com ]]; then
    run_spotdl "$target" "$xdg_music" || {
        log "$red" "spotdl failed. yt-dlp cannot natively parse walled-garden spotify urls. manual extraction required."
        exit 1
    }

else
    mode_media "$target" "$media_type" "$format_arg" "$playlist_flag"
fi
