#!/usr/bin/env bash
# Interactive HP Envy menu wrapper for rip-dvd-to-video.

set -Eeuo pipefail

RIPPER="${RIPPER:-$HOME/.local/bin/rip-dvd-to-video}"
DEFAULT_OUTDIR="$HOME/Videos/DVD-Rips"
NAS_MOVIES_DIR="/mnt/main-nas/movies"
NAS_PORN_DIR="/mnt/main-nas/porn"
NAS_TV_DIR="/mnt/main-nas/tv-shows"

pause() {
  printf '\nPress Enter to return to the menu...'
  read -r _ || true
}

need_ripper() {
  if [[ ! -x "$RIPPER" ]]; then
    printf 'DVD ripper helper is missing or not executable: %s\n' "$RIPPER" >&2
    pause
    exit 1
  fi
}

detect_dvd_source() {
  local candidate
  for candidate in /dev/dvd /dev/cdrom /dev/sr0 /dev/sr1 /dev/sr2; do
    [[ -e "$candidate" ]] && { printf '%s' "$candidate"; return 0; }
  done
  printf '/dev/sr0'
}

safe_folder_name() {
  local raw="$1"
  printf '%s' "$raw" \
    | tr '/:' '--' \
    | tr -cd '[:alnum:]. _()-' \
    | sed -E 's/[[:space:]]+/_/g; s/^_+|_+$//g; s/_+/_/g'
}

dvd_label_for_source() {
  local source="$1" label=""
  if [[ -b "$source" ]]; then
    label="$(lsblk -no LABEL "$source" 2>/dev/null | sed -n '1p' || true)"
    if [[ -z "${label// }" ]]; then
      label="$(blkid -o value -s LABEL "$source" 2>/dev/null || true)"
    fi
  fi
  if [[ -z "${label// }" ]]; then
    label="$(findmnt -rno SOURCE,TARGET,FSTYPE | awk -v src="$source" '$1==src && ($3=="udf" || $3=="iso9660") {print $2; exit}' | xargs -r basename 2>/dev/null || true)"
  fi
  printf '%s' "$label"
}

show_drive_status() {
  printf '\nDVD/optical drive status\n'
  printf '========================\n\n'
  printf 'Device links:\n'
  local found_device=0
  for dev in /dev/dvd /dev/cdrom /dev/sr*; do
    if [[ -e "$dev" ]]; then
      ls -l "$dev"
      found_device=1
    fi
  done
  if [[ "$found_device" -eq 0 ]]; then
    printf '  No /dev/dvd, /dev/cdrom, or /dev/sr* device currently visible.\n'
  fi
  printf '\nBlock devices:\n'
  lsblk -o NAME,PATH,TYPE,SIZE,MODEL,FSTYPE,LABEL,MOUNTPOINTS | awk 'NR==1 || $3=="rom" || $2 ~ /\/dev\/sr[0-9]+/' || true
  printf '\nMounted optical media:\n'
  findmnt -rno SOURCE,TARGET,FSTYPE,OPTIONS | grep -Ei 'sr[0-9]|cdrom|dvd|udf|iso9660' || printf '  No optical disc currently mounted.\n'
  local source label
  source="$(detect_dvd_source)"
  label="$(dvd_label_for_source "$source")"
  printf '\nAuto-selected source would be: %s\n' "$source"
  if [[ -n "${label// }" ]]; then
    printf 'Detected DVD label/title: %s\n' "$label"
  fi
  pause
}

prompt_default() {
  local prompt="$1" default="$2" value
  printf '%s [%s]: ' "$prompt" "$default" >&2
  read -r value || value=""
  printf '%s' "${value:-$default}"
}

install_requirements() {
  printf '\nThis installs HandBrakeCLI plus support tools using apt.\n'
  printf 'You may be asked for your sudo password.\n\n'
  sudo apt update && sudo apt install -y handbrake-cli ffmpeg rsync eject
  pause
}

choose_nas_destination() {
  local category base default_folder folder dest
  while true; do
    cat >&2 <<MENU

Save finished rip under which NAS library?
1. Movies    ($NAS_MOVIES_DIR)
2. Porn      ($NAS_PORN_DIR)
3. TV Shows  ($NAS_TV_DIR)
MENU
    printf 'Choose 1/2/3 [1]: ' >&2
    read -r category || category=""
    case "${category:-1}" in
      1|movies|Movies|movie|Movie) base="$NAS_MOVIES_DIR"; break ;;
      2|porn|Porn) base="$NAS_PORN_DIR"; break ;;
      3|tv|TV|tvshows|TVShows|"tv shows"|"TV Shows") base="$NAS_TV_DIR"; break ;;
      *) printf 'Invalid choice. Pick 1, 2, or 3.\n' >&2 ;;
    esac
  done

  default_folder="$(safe_folder_name "$1")"
  [[ -n "${default_folder// }" ]] || default_folder="DVD_Rip"
  folder="$(prompt_default 'Folder name under that NAS library' "$default_folder")"
  folder="$(safe_folder_name "$folder")"
  [[ -n "${folder// }" ]] || folder="$default_folder"
  dest="$base/$folder"

  if [[ ! -d "$base" ]]; then
    printf 'NAS library folder does not exist or is not mounted: %s\n' "$base" >&2
    return 1
  fi
  mkdir -p "$dest"
  printf '%s' "$dest"
}

scan_disc() {
  need_ripper
  local source default_source
  default_source="$(detect_dvd_source)"
  source="$(prompt_default 'DVD device or VIDEO_TS folder' "$default_source")"
  "$RIPPER" --scan --source "$source"
  pause
}

rip_disc() {
  need_ripper
  local source default_source detected_title title_name title_num out_dir fmt copy_nas nas_dir
  default_source="$(detect_dvd_source)"
  source="$(prompt_default 'DVD device or VIDEO_TS folder' "$default_source")"
  detected_title="$(dvd_label_for_source "$source")"
  [[ -n "${detected_title// }" ]] || detected_title="DVD_Rip_$(date '+%Y%m%d')"
  title_name="$(prompt_default 'Output file title/name from DVD label' "$detected_title")"
  if [[ -z "${title_name// }" ]]; then
    printf 'Cancelled: title/name is required.\n' >&2
    pause
    return 1
  fi
  title_num="$(prompt_default 'DVD title number, 0 = automatic/main feature' '0')"
  out_dir="$(prompt_default 'Local output/staging folder' "$DEFAULT_OUTDIR")"
  fmt="$(prompt_default 'Format: mp4 or mkv' 'mp4')"

  nas_dir="$(choose_nas_destination "$title_name")" || { pause; return 1; }
  printf '\nFinal NAS destination folder: %s\n' "$nas_dir"
  printf 'Proceed with rip? [Y/n]: ' >&2
  read -r copy_nas || copy_nas=""
  if [[ "$copy_nas" =~ ^[Nn]$ ]]; then
    printf 'Cancelled before ripping.\n' >&2
    pause
    return 1
  fi

  "$RIPPER" \
    --title-name "$title_name" \
    --source "$source" \
    --title "$title_num" \
    --out-dir "$out_dir" \
    --format "$fmt" \
    --nas-dir "$nas_dir"
  pause
}

case "${1:-menu}" in
  status) show_drive_status ;;
  scan) scan_disc ;;
  rip) rip_disc ;;
  install) install_requirements ;;
  menu|*)
    while true; do
      clear || true
      cat <<MENU
DVD to Video Helper
===================

1. Check DVD drive/disc status
2. Scan DVD titles
3. Rip DVD / VIDEO_TS to video file
4. Install DVD ripping requirements
q. Quit
MENU
      printf '\nChoose: '
      read -r choice || exit 0
      case "$choice" in
        1) show_drive_status ;;
        2) scan_disc ;;
        3) rip_disc ;;
        4) install_requirements ;;
        q|Q|quit|exit) exit 0 ;;
        *) printf 'Invalid choice.\n'; sleep 1 ;;
      esac
    done
    ;;
esac
