#!/usr/bin/env bash
VERSION="1.0.0"

retry() {
	err "$*"
	prompt
}

# display error message and exit
die() {
	((!SILENT)) && printf "\033[1;31m%s\033[0m\n" "$*" >&2
	exit 1
}

# display an error message to stderr (in red)
err() {
	((!SILENT)) && printf "\33[2K\r\033[1;31m%s\033[0m\n" "$*" >&2
}

# display a log message if verbose mode is enabled
lg() {
	((VERBOSE)) && printf "\033[1;35m%s\033[0m\n" "$*" >&2
}

# display an informational message (first argument in green, second in magenta)
inf() {
	printf "\33[2K\r\033[1;35m%s \033[1;35m%s\033[0m\n" "$1" "$2"
}

progress() {
	((!SILENT)) && printf "\33[2K\r\033[1;34m%s\033[0m\n" "$1" >&2
}

# prompts the user with message in $1-2 ($1 in blue, $2 in magenta) and saves the input to the variables in $REPLY and $REPLY2
prompt() {
	printf "\033[1;35m%s\033[1;35m%s\033[1;34m\033[0m: " "$1" "$2"
}

# displays an even (cyan) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_even() {
	printf "\033[1;36m(\033[1;36m%s\033[1;36m) \033[1;36m%s\033[0m\n" "$2" "$1"
}

# displays an odd (yellow) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_odd() {
	printf "\033[1;33m(\033[1;33m%s\033[1;33m) \033[1;33m%s\033[0m\n" "$2" "$1"
}

# display alternating menu lines (even and odd)
menu_line_alternate() {
	menu_line_parity=${menu_line_parity:-0}
	if [ "$menu_line_parity" -eq 0 ]; then
		menu_line_odd "$1" "$2"
		menu_line_parity=1
	else
		menu_line_even "$1" "$2"
		menu_line_parity=0
	fi
}

# displays a warning (red) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_strong() {
	printf "\033[1;34m[\033[1;33m%s\033[1;34m] \033[1;33m%s\033[0m\n" "$2" "$1"
}

# Select anime from query results
anime_selection() {
	search_results=$*
	menu=""
	searched=""
	cnt=0
	while read -r anime_id; do
		anime_id=$(printf "%s" "$anime_id" | sed -E 's/\-episode\-.*//')
		[[ -z "$menu" ]] && menu="$((cnt + 1)). $anime_id" ||
			menu="$menu|$((cnt + 1)). $anime_id"
		if ! check_db "search" "$anime_id"; then
			[[ -z "$searched" ]] && searched="$cnt" || searched="$searched, $cnt"
		fi
		((++cnt))
	done <<< "$search_results"
	menu="$menu|$((++cnt)). Search another anime|$((++cnt)). Quit"

	# get the anime from indexed list
	msg="$(generate_span "Query: $query")"
	selection="$(rofi -dpi "$DPI" -dmenu -no-custom \
		-async-pre-read 33 -config "$ROFI_CFG" -l 15 -i -sep '|' \
		-mesg "$msg" -a "$searched" -p "Enter selection" -window-title 'aniwrapper' <<< "$menu")"
	choice="${selection%%.*}" # remmove everything from . to end
	lg "CHOICE: $choice"
	if ((choice == cnt)); then
		die "Quitting"
	elif ((choice == --cnt)); then
		stream
		return $?
	fi

	# Check if input is a number
	[[ "$choice" -eq "$choice" ]] 2> /dev/null || die "Invalid number entered"

	count=1
	while read -r anime_id; do
		if [[ "$count" -eq "$choice" ]]; then
			anime_id=$(printf "%s" "$anime_id" | sed -E 's/\-episode\-.*//')
			selection_id=$anime_id
			break
		fi
		count=$((count + 1))
	done <<< "$search_results"

	[[ -z "$selection_id" ]] && die "Invalid number entered"
	insert_history "search" "$selection_id" &
	lg "Selection: $selection_id"
	progress "(Gogoanime) Searching Episodes.."
	episode_list "$selection_id"
	return 0
}

# select episode from query results
episode_selection() {
	ep_choice_start=1
	lg "Anime ID: $anime_id"
	stmt="SELECT episode_number FROM watch_history WHERE anime_name = '$anime_id';"

	# Get Watch History for $anime_id as comma separated list
	watch_history=""
	while read -r i; do
		if ((FIRST_EP_NUMBER == 0)); then
			[[ -z "$watch_history" ]] && watch_history="$((i))" || watch_history="$watch_history, $((i))"
		else
			[[ -z "$watch_history" ]] && watch_history="$((--i))" || watch_history="$watch_history, $((--i))"
		fi
	done < <(run_stmt "$stmt")
	lg "Episode watch history -> $watch_history"

	# get user choice and set the start and end
	msg1="Anime Name: $anime_id"
	msg2="Range of episodes can be provided as: START_EPISODE - END_EPISODE"
	[[ "$is_download" -eq 1 ]] && msg=$(printf "%s\n%s" "$(generate_span "$msg1")" "$(generate_span "$msg2")") || msg=$(printf "%s\n" "$(generate_span "$msg1")")
	choice=$(
		seq "$FIRST_EP_NUMBER" "$LAST_EP_NUMBER" |
			rofi -dpi "$DPI" -dmenu -l 12 \
				-theme-str 'window {width: 45%;}' \
				-a "$watch_history" \
				-p "Select Episode [$FIRST_EP_NUMBER, $LAST_EP_NUMBER]:" \
				-mesg "$msg" -window-title 'aniwrapper' \
				-config "$ROFI_CFG"
	)
	ep_choice_start=$(printf '%s\n' "${choice}" | awk '{print $1}')
	ep_choice_end=$(printf '%s\n' "${choice}" | awk '{print $NF}')
	lg "START: $ep_choice_start | END: $ep_choice_end"
	if (((ep_choice_start < 0 || ep_choice_start > LAST_EP_NUMBER) || ep_choice_end < ep_choice_start || ep_choice_end > LAST_EP_NUMBER)); then
		die "Invalid episode/range entered: ep_start -> $ep_choice_start | ep_end -> $ep_choice_end"
	fi
}

continue_watching() {
	msg="$(printf '%s\n%s' "$(generate_span "Anime: $anime_id")" "$(generate_span "Next episode: $((episode + 1))")")"
	choice=$(rofi -dmenu -dpi "$DPI" -config "$ROFI_CFG" \
		-theme-str 'listview {columns: 1;} window {width: 25%;}' \
		-i -l 2 -no-custom -sep '|' -a 0 -mesg "$msg" \
		-p "Continue watching?" -window-title 'aniwrapper' <<< "Yes|No")
	[[ "$choice" =~ ^(y|Y|Yes)$ ]] && return 0 || return 1
}

# get the search query from user or from args
get_search_query() {
	if [ $# -gt 0 ]; then
		query="${*// /-}"
	else
		stmt="SELECT id || '. ' || anime_name FROM search_history ORDER BY search_date DESC;"
		msg="Choose from list of searched anime below, or enter a unique name of an anime to search for"
		query=$(rofi -dpi "$DPI" -dmenu -l 15 -p "Search Anime:" \
			-mesg "$(generate_span "$msg")" \
			-config "$ROFI_CFG" -window-title 'aniwrapper' < <(run_stmt "$stmt"))
		query="${query#*\. }" # remove [1-9]. from beginning of query
		query="${query// /-}" # replace spaces with -
	fi
}

get_dl_dir() {
	download_dir=$(
		rofi -dpi "$DPI" -dmenu -config "$ROFI_CFG" \
			-theme-str 'listview {columns: 1;} window {width: 45%;}' \
			-mesg "$(generate_span "Enter the path to the download directory, or leave blank to go with the default: $HOME/Videos/sauce/")" \
			-l 1 -p "Enter download dir:" -window-title 'aniwrapper'
	)
	[ -z "$download_dir" ] && download_dir="$HOME/Videos/sauce/"
	if [ ! -d "$download_dir" ]; then
		mkdir -p "$download_dir" || die "Error creating directory: $download_dir"
	fi
}

# sets the video quality
set_video_quality() {
	qualities="1. best|2. worst"
	while IFS='|' read -ra quals; do
		for q in "${quals[@]}"; do
			if [[ "$(awk '{ print $NF }' <<< "$q")" == "$quality" ]]; then
				cur_quality="$((${q:0:1} - 1))"
				break
			fi
		done
	done <<< "$qualities"
	choice=$(rofi -dmenu -dpi "$DPI" -config "$ROFI_CFG" \
		-theme-str 'listview {columns: 1;} window {width: 25%;}' \
		-i -l 6 -no-custom -sep '|' -a "$cur_quality" -mesg "$(generate_span "Current quality: $quality")" \
		-p "Choose quality:" -window-title 'aniwrapper' -selected-row "$cur_quality" <<< "$qualities")
	quality=$(awk '{ print $2 }' <<< "$choice")
	NEW_QUALITY=1
}

# vim :ft=sh
